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
MeshInstance(Mesh * mesh,Texture * texture,const Vector3 & position,const Quaternion & orientation,float animOffset)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
~MeshInstance()32 MeshInstance::~MeshInstance()
33 {
34 }
35
36
37 void
Update(float dt)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
Render()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