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