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