1bee3c7a9SAlexandre Deckner /* 2bee3c7a9SAlexandre Deckner * Copyright 2008, Haiku Inc. All rights reserved. 3bee3c7a9SAlexandre Deckner * Distributed under the terms of the MIT License. 4bee3c7a9SAlexandre Deckner * 5bee3c7a9SAlexandre Deckner * Authors: 6bee3c7a9SAlexandre Deckner * Alexandre Deckner <alex@zappotek.com> 7bee3c7a9SAlexandre Deckner */ 8bee3c7a9SAlexandre Deckner 9bee3c7a9SAlexandre Deckner #include "MeshInstance.h" 10bee3c7a9SAlexandre Deckner #include "MathUtils.h" 11*8e4cdaaeSAlexander von Gluck IV #include <GL/gl.h> 12bee3c7a9SAlexandre Deckner 13bee3c7a9SAlexandre Deckner //#include <stdio.h> // debug 14bee3c7a9SAlexandre Deckner 15bee3c7a9SAlexandre Deckner 16bee3c7a9SAlexandre Deckner MeshInstance::MeshInstance(Mesh* mesh, Texture* texture, 17bee3c7a9SAlexandre Deckner const Vector3& position, const Quaternion& orientation, float animOffset) 18bee3c7a9SAlexandre Deckner : 19bee3c7a9SAlexandre Deckner fMeshReference(mesh), 20bee3c7a9SAlexandre Deckner fTextureReference(texture), 21bee3c7a9SAlexandre Deckner fPosition(position), 22bee3c7a9SAlexandre Deckner fOrientation(orientation), 23bee3c7a9SAlexandre Deckner fScale(1.0f), 24bee3c7a9SAlexandre Deckner fTime(0.0f), 25bee3c7a9SAlexandre Deckner fAnimOffset(animOffset), 26bee3c7a9SAlexandre Deckner fDoubleSided(true), 27bee3c7a9SAlexandre Deckner fDrawNormals(false) 28bee3c7a9SAlexandre Deckner { 29bee3c7a9SAlexandre Deckner } 30bee3c7a9SAlexandre Deckner 31bee3c7a9SAlexandre Deckner 32bee3c7a9SAlexandre Deckner MeshInstance::~MeshInstance() 33bee3c7a9SAlexandre Deckner { 34bee3c7a9SAlexandre Deckner } 35bee3c7a9SAlexandre Deckner 36bee3c7a9SAlexandre Deckner 37bee3c7a9SAlexandre Deckner void 38bee3c7a9SAlexandre Deckner MeshInstance::Update(float dt) 39bee3c7a9SAlexandre Deckner { 40bee3c7a9SAlexandre Deckner fTextureReference->Update(dt); 41bee3c7a9SAlexandre Deckner 42bee3c7a9SAlexandre Deckner float animDuration = 4.0f; 43bee3c7a9SAlexandre Deckner 44bee3c7a9SAlexandre Deckner fTime += dt; 45bee3c7a9SAlexandre Deckner if (fTime >= fAnimOffset) { 46bee3c7a9SAlexandre Deckner float animTime = (fTime - fAnimOffset); 47bee3c7a9SAlexandre Deckner 48bee3c7a9SAlexandre Deckner float rotAngle = MathUtils::EaseInOutQuart(animTime, 0, 49bee3c7a9SAlexandre Deckner 3 * 2 * 3.14159, animDuration); 50bee3c7a9SAlexandre Deckner 51bee3c7a9SAlexandre Deckner fOrientation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), rotAngle); 52bee3c7a9SAlexandre Deckner } 53bee3c7a9SAlexandre Deckner 54bee3c7a9SAlexandre Deckner if (fTime >= fAnimOffset + animDuration) { 55bee3c7a9SAlexandre Deckner fOrientation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), 0.0); 56bee3c7a9SAlexandre Deckner } 57bee3c7a9SAlexandre Deckner 58bee3c7a9SAlexandre Deckner if (fTime >= animDuration * 6) { 59bee3c7a9SAlexandre Deckner fTime = 0.0; 60bee3c7a9SAlexandre Deckner } 61bee3c7a9SAlexandre Deckner } 62bee3c7a9SAlexandre Deckner 63bee3c7a9SAlexandre Deckner 64bee3c7a9SAlexandre Deckner void 65bee3c7a9SAlexandre Deckner MeshInstance::Render() 66bee3c7a9SAlexandre Deckner { 67bee3c7a9SAlexandre Deckner if (fMeshReference->FaceCount() == 0) 68bee3c7a9SAlexandre Deckner return; 69bee3c7a9SAlexandre Deckner 70bee3c7a9SAlexandre Deckner glPushMatrix(); 71bee3c7a9SAlexandre Deckner glTranslatef(fPosition.x(), fPosition.y(), fPosition.z()); 72bee3c7a9SAlexandre Deckner float mat[4][4]; 73bee3c7a9SAlexandre Deckner fOrientation.toOpenGLMatrix(mat); 74bee3c7a9SAlexandre Deckner glMultMatrixf((GLfloat*) mat); 75bee3c7a9SAlexandre Deckner glScalef(fScale, fScale, fScale); 76bee3c7a9SAlexandre Deckner glBindTexture(GL_TEXTURE_2D, fTextureReference->Id()); 77bee3c7a9SAlexandre Deckner 78bee3c7a9SAlexandre Deckner int lastVertexCount = 0; 79bee3c7a9SAlexandre Deckner 80bee3c7a9SAlexandre Deckner for (uint32 i = 0; i < fMeshReference->FaceCount(); i++) { 81bee3c7a9SAlexandre Deckner 82bee3c7a9SAlexandre Deckner const Face& face = fMeshReference->GetFace(i); 83bee3c7a9SAlexandre Deckner 84bee3c7a9SAlexandre Deckner // switch face mode 85bee3c7a9SAlexandre Deckner if (face.vertexCount != lastVertexCount) { 86bee3c7a9SAlexandre Deckner if (lastVertexCount != 0) 87bee3c7a9SAlexandre Deckner glEnd(); 88bee3c7a9SAlexandre Deckner 89bee3c7a9SAlexandre Deckner if (face.vertexCount == 3) 90bee3c7a9SAlexandre Deckner glBegin(GL_TRIANGLES); 91bee3c7a9SAlexandre Deckner else 92bee3c7a9SAlexandre Deckner glBegin(GL_QUADS); 93bee3c7a9SAlexandre Deckner } 94bee3c7a9SAlexandre Deckner 95bee3c7a9SAlexandre Deckner // calculate normal 96bee3c7a9SAlexandre Deckner Vector3 lu(face.v[0].p - face.v[1].p); 97bee3c7a9SAlexandre Deckner Vector3 lv(face.v[1].p - face.v[2].p); 98bee3c7a9SAlexandre Deckner Vector3 normal(lu.cross(lv)); 99bee3c7a9SAlexandre Deckner if (normal.length() <= 0.000001) 100bee3c7a9SAlexandre Deckner normal.setValue(0, 0, -1.0); 101bee3c7a9SAlexandre Deckner normal.normalize(); 102bee3c7a9SAlexandre Deckner 103bee3c7a9SAlexandre Deckner // draw face 104bee3c7a9SAlexandre Deckner glNormal3f(normal.x(), normal.y(), normal.z()); 105bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[0].u, face.v[0].v); 106bee3c7a9SAlexandre Deckner glVertex3f(face.v[0].p.x(), face.v[0].p.y(), face.v[0].p.z()); 107bee3c7a9SAlexandre Deckner 108bee3c7a9SAlexandre Deckner glNormal3f(normal.x(), normal.y(), normal.z()); 109bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[1].u, face.v[1].v); 110bee3c7a9SAlexandre Deckner glVertex3f(face.v[1].p.x(), face.v[1].p.y(), face.v[1].p.z()); 111bee3c7a9SAlexandre Deckner 112bee3c7a9SAlexandre Deckner glNormal3f(normal.x(), normal.y(), normal.z()); 113bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[2].u, face.v[2].v); 114bee3c7a9SAlexandre Deckner glVertex3f(face.v[2].p.x(), face.v[2].p.y(), face.v[2].p.z()); 115bee3c7a9SAlexandre Deckner 116bee3c7a9SAlexandre Deckner if (face.vertexCount == 4) { 117bee3c7a9SAlexandre Deckner glNormal3f(normal.x(), normal.y(), normal.z()); 118bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[3].u, face.v[3].v); 119bee3c7a9SAlexandre Deckner glVertex3f(face.v[3].p.x(), face.v[3].p.y(), face.v[3].p.z()); 120bee3c7a9SAlexandre Deckner } 121bee3c7a9SAlexandre Deckner 122bee3c7a9SAlexandre Deckner if (fDoubleSided) { 123bee3c7a9SAlexandre Deckner if (face.vertexCount == 4) { 124bee3c7a9SAlexandre Deckner glNormal3f(-normal.x(), -normal.y(), -normal.z()); 125bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[3].u, face.v[3].v); 126bee3c7a9SAlexandre Deckner glVertex3f(face.v[3].p.x(), face.v[3].p.y(), face.v[3].p.z()); 127bee3c7a9SAlexandre Deckner } 128bee3c7a9SAlexandre Deckner 129bee3c7a9SAlexandre Deckner glNormal3f(-normal.x(), -normal.y(), -normal.z()); 130bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[2].u, face.v[2].v); 131bee3c7a9SAlexandre Deckner glVertex3f(face.v[2].p.x(), face.v[2].p.y(), face.v[2].p.z()); 132bee3c7a9SAlexandre Deckner 133bee3c7a9SAlexandre Deckner glNormal3f(-normal.x(), -normal.y(), -normal.z()); 134bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[1].u, face.v[1].v); 135bee3c7a9SAlexandre Deckner glVertex3f(face.v[1].p.x(), face.v[1].p.y(), face.v[1].p.z()); 136bee3c7a9SAlexandre Deckner 137bee3c7a9SAlexandre Deckner glNormal3f(-normal.x(), -normal.y(), -normal.z()); 138bee3c7a9SAlexandre Deckner glTexCoord2f(face.v[0].u, face.v[0].v); 139bee3c7a9SAlexandre Deckner glVertex3f(face.v[0].p.x(), face.v[0].p.y(), face.v[0].p.z()); 140bee3c7a9SAlexandre Deckner } 141bee3c7a9SAlexandre Deckner lastVertexCount = face.vertexCount; 142bee3c7a9SAlexandre Deckner } 143bee3c7a9SAlexandre Deckner glEnd(); 144bee3c7a9SAlexandre Deckner 145bee3c7a9SAlexandre Deckner if (fDrawNormals) { 146bee3c7a9SAlexandre Deckner glBegin(GL_LINES); 147bee3c7a9SAlexandre Deckner for (uint32 i = 0; i < fMeshReference->FaceCount(); i++) { 148bee3c7a9SAlexandre Deckner 149bee3c7a9SAlexandre Deckner const Face& face = fMeshReference->GetFace(i); 150bee3c7a9SAlexandre Deckner 151bee3c7a9SAlexandre Deckner if (face.vertexCount == 4) { 152bee3c7a9SAlexandre Deckner 153bee3c7a9SAlexandre Deckner // calculate normal 154bee3c7a9SAlexandre Deckner Vector3 lu(face.v[0].p - face.v[1].p); 155bee3c7a9SAlexandre Deckner Vector3 lv(face.v[1].p - face.v[2].p); 156bee3c7a9SAlexandre Deckner Vector3 normal(lu.cross(lv)); 157bee3c7a9SAlexandre Deckner if (normal.length() <= 0.000001) 158bee3c7a9SAlexandre Deckner normal.setValue(0, 0, -1.0); 159bee3c7a9SAlexandre Deckner normal.normalize(); 160bee3c7a9SAlexandre Deckner 161bee3c7a9SAlexandre Deckner // center of the face 162bee3c7a9SAlexandre Deckner Vector3 g; 163bee3c7a9SAlexandre Deckner if (face.vertexCount == 4) 164bee3c7a9SAlexandre Deckner g = (face.v[0].p + face.v[1].p + face.v[2].p + face.v[3].p) 165bee3c7a9SAlexandre Deckner / 4.0; 166bee3c7a9SAlexandre Deckner else 167bee3c7a9SAlexandre Deckner g = (face.v[0].p + face.v[1].p + face.v[2].p) / 3.0; 168bee3c7a9SAlexandre Deckner 169bee3c7a9SAlexandre Deckner Vector3 h(g + normal); 170bee3c7a9SAlexandre Deckner 171bee3c7a9SAlexandre Deckner glVertex3f(g.x(), g.y(), g.z()); 172bee3c7a9SAlexandre Deckner glVertex3f(h.x(), h.y(), h.z()); 173bee3c7a9SAlexandre Deckner } 174bee3c7a9SAlexandre Deckner } 175bee3c7a9SAlexandre Deckner glEnd(); 176bee3c7a9SAlexandre Deckner } 177bee3c7a9SAlexandre Deckner 178bee3c7a9SAlexandre Deckner glPopMatrix(); 179bee3c7a9SAlexandre Deckner } 180