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 <opengl/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 //int batchCount = 0; 80 81 for(uint32 i = 0; i < fMeshReference->FaceCount(); i++) { 82 83 const Face& face = fMeshReference->GetFace(i); 84 85 // switch face mode 86 if (face.vertexCount != lastVertexCount) { 87 if (lastVertexCount != 0) 88 glEnd(); 89 90 if (face.vertexCount == 3) 91 glBegin(GL_TRIANGLES); 92 else 93 glBegin(GL_QUADS); 94 95 //batchCount++; 96 } 97 98 // calculate normal 99 Vector3 lu(face.v[0].p - face.v[1].p); 100 Vector3 lv(face.v[1].p - face.v[2].p); 101 Vector3 normal(lu.cross(lv)); 102 if (normal.length() <= 0.000001) 103 normal.setValue(0, 0, -1.0); 104 normal.normalize(); 105 106 // draw face 107 glNormal3f(normal.x(), normal.y(), normal.z()); 108 glTexCoord2f(face.v[0].u, face.v[0].v); 109 glVertex3f(face.v[0].p.x(), face.v[0].p.y(), face.v[0].p.z()); 110 111 glNormal3f(normal.x(), normal.y(), normal.z()); 112 glTexCoord2f(face.v[1].u, face.v[1].v); 113 glVertex3f(face.v[1].p.x(), face.v[1].p.y(), face.v[1].p.z()); 114 115 glNormal3f(normal.x(), normal.y(), normal.z()); 116 glTexCoord2f(face.v[2].u, face.v[2].v); 117 glVertex3f(face.v[2].p.x(), face.v[2].p.y(), face.v[2].p.z()); 118 119 if (face.vertexCount == 4) { 120 glNormal3f(normal.x(), normal.y(), normal.z()); 121 glTexCoord2f(face.v[3].u, face.v[3].v); 122 glVertex3f(face.v[3].p.x(), face.v[3].p.y(), face.v[3].p.z()); 123 } 124 125 if (fDoubleSided) { 126 if (face.vertexCount == 4) { 127 glNormal3f(-normal.x(), -normal.y(), -normal.z()); 128 glTexCoord2f(face.v[3].u, face.v[3].v); 129 glVertex3f(face.v[3].p.x(), face.v[3].p.y(), face.v[3].p.z()); 130 } 131 132 glNormal3f(-normal.x(), -normal.y(), -normal.z()); 133 glTexCoord2f(face.v[2].u, face.v[2].v); 134 glVertex3f(face.v[2].p.x(), face.v[2].p.y(), face.v[2].p.z()); 135 136 glNormal3f(-normal.x(), -normal.y(), -normal.z()); 137 glTexCoord2f(face.v[1].u, face.v[1].v); 138 glVertex3f(face.v[1].p.x(), face.v[1].p.y(), face.v[1].p.z()); 139 140 glNormal3f(-normal.x(), -normal.y(), -normal.z()); 141 glTexCoord2f(face.v[0].u, face.v[0].v); 142 glVertex3f(face.v[0].p.x(), face.v[0].p.y(), face.v[0].p.z()); 143 } 144 lastVertexCount = face.vertexCount; 145 } 146 glEnd(); 147 //printf("batchCount %d\n", batchCount); 148 149 if (fDrawNormals) { 150 glBegin(GL_LINES); 151 for(uint32 i = 0; i < fMeshReference->FaceCount(); i++) { 152 153 const Face& face = fMeshReference->GetFace(i); 154 155 if (face.vertexCount == 4) { 156 157 // calculate normal 158 Vector3 lu(face.v[0].p - face.v[1].p); 159 Vector3 lv(face.v[1].p - face.v[2].p); 160 Vector3 normal(lu.cross(lv)); 161 if (normal.length() <= 0.000001) 162 normal.setValue(0, 0, -1.0); 163 normal.normalize(); 164 165 // center of the face 166 Vector3 g; 167 if (face.vertexCount == 4) 168 g = (face.v[0].p + face.v[1].p + face.v[2].p + face.v[3].p) 169 / 4.0; 170 else 171 g = (face.v[0].p + face.v[1].p + face.v[2].p) / 3.0; 172 173 Vector3 h(g + normal); 174 175 glVertex3f(g.x(), g.y(), g.z()); 176 glVertex3f(h.x(), h.y(), h.z()); 177 } 178 } 179 glEnd(); 180 } 181 182 glPopMatrix(); 183 } 184