framework2
299 строк · 9.5 Кб
1//
2// ofxFBXMesh.h
3// ofxFBX-Example-Importer
4//
5// Created by Nick Hardeman on 10/31/13.
6//
7//
8
9#include "ofxFBXMesh.h"
10#include "ofxFBX.h"
11
12ofVbo ofxFBXMesh::dummyVbo;
13
14//----------------------------------------
15ofxFBXSource::Node::NodeType ofxFBXMesh::getType() {
16return ofxFBXSource::Node::OFX_FBX_MESH;
17}
18
19//--------------------------------------------------------------
20void ofxFBXMesh::setup( shared_ptr<ofxFBXSource::Node> anode ) {
21ofxFBXNode::setup( anode );
22_checkSrcMesh();
23bHasTexture = false;
24if(mSrcMesh) {
25mSrcMesh->configureMesh( mesh );
26setTransform( anode );
27// populate the materials //
28auto srcMats = mSrcMesh->getMaterials();
29for( auto sm : srcMats ) {
30auto mat = make_shared<ofxFBXMeshMaterial>();
31mat->setup( sm );
32mMaterials.push_back( mat );
33if( mat->hasTexture() ) {
34bHasTexture = true;
35}
36}
37}
38}
39
40//--------------------------------------------------------------
41void ofxFBXMesh::update( FbxTime& pTime, FbxPose* pPose ) {
42_checkSrcMesh();
43if(mSrcMesh) {
44mSrcMesh->update( pTime, pPose );
45bDrawMeshKeyframe=false;
46}
47}
48
49//--------------------------------------------------------------
50void ofxFBXMesh::update( int aAnimIndex, signed long aMillis ) {
51_checkSrcMesh();
52if(mSrcMesh) {
53mSrcMesh->update( aAnimIndex, aMillis );
54
55if( mSrcMesh->isUsingCachedMeshes() && mSrcMesh->hasMeshKeyCollection(aAnimIndex)) {
56// now configure the mesh for the animation index and time //
57// but only if there are no vertices, since the src mesh has all of the meshes already in a vector //
58// the mesh gets blended in transition, so setup here, so there isn't a stutter on transition start //
59if( bBlendMeshFrames ) {
60mSrcMesh->updateMeshFromKeyframesBlended( &mesh, aAnimIndex, aMillis );
61} else {
62if( mesh.getNumVertices() < 1 ) {
63mSrcMesh->updateMeshFromKeyframes( &mesh, aAnimIndex, aMillis );
64}
65}
66mLastAnimIndex = aAnimIndex;
67mLastFbxTimeMillis = aMillis;
68bDrawMeshKeyframe=true;
69}
70}
71}
72
73//--------------------------------------------------------------
74void ofxFBXMesh::update( int aAnimIndex1, signed long aAnim1Millis, int aAnimIndex2, signed long aAnim2Millis, float aMixPct ) {
75_checkSrcMesh();
76if(mSrcMesh) {
77mSrcMesh->update( aAnimIndex1, aAnim1Millis, aAnimIndex2, aAnim2Millis, aMixPct );
78bDrawMeshKeyframe=false;
79if( mSrcMesh->isUsingCachedMeshes() && mSrcMesh->hasMeshKeyCollection(aAnimIndex1) && mSrcMesh->hasMeshKeyCollection(aAnimIndex2)) {
80mSrcMesh->updateMeshFromKeyframes( &mesh, aAnimIndex1, aAnim1Millis, aAnimIndex2, aAnim2Millis, aMixPct );
81}
82}
83}
84
85//--------------------------------------------------------------
86void ofxFBXMesh::update() {
87_checkSrcMesh();
88if(mSrcMesh) {
89setPosition( mSrcMesh->getPosition() );
90setOrientation( mSrcMesh->getOrientationQuat() );
91setScale( mSrcMesh->getScale() );
92}
93}
94
95//--------------------------------------------------------------
96void ofxFBXMesh::lateUpdate(FbxTime& pTime, FbxAnimLayer * pAnimLayer, FbxPose* pPose) {
97_checkSrcMesh();
98if(mSrcMesh) {
99// signed long ctime = (signed long)pTime.GetMilliSeconds();
100// if(mLastFbxTimeMillis != ctime ) {
101if(!mSrcMesh->isUsingCachedMeshes() ) {
102mSrcMesh->updateMesh( &mesh, pTime, pAnimLayer, pPose );
103bMeshDirty = true;
104} else {
105bMeshDirty = true;
106}
107// mLastFbxTimeMillis = ctime;
108}
109}
110
111//--------------------------------------------------------------
112void ofxFBXMesh::draw() {
113_checkSrcMesh();
114if(!mSrcMesh) {
115ofLogError("ofxFBXMesh::draw : src mesh is invalid! ") << getName();
116return;
117}
118transformGL(); {
119if(bDrawMeshKeyframe) {
120mSrcMesh->drawMeshKeyframe( mLastAnimIndex, mLastFbxTimeMillis, mMaterials, bMeshDirty );
121} else {
122mSrcMesh->draw( &mesh, mMaterials, bMeshDirty );
123}
124} restoreTransformGL();
125
126bMeshDirty = false;
127}
128
129//--------------------------------------------------------------
130void ofxFBXMesh::drawWireframe() {
131_checkSrcMesh();
132transformGL(); {
133mesh.drawWireframe();
134} restoreTransformGL();
135}
136
137//--------------------------------------------------------------
138void ofxFBXMesh::drawNormals(float length, bool bFaceNormals ) {
139
140if( mesh.usingNormals()) {
141vector<glm::vec3>& normals = mesh.getNormals();
142vector<glm::vec3>& vertices = mesh.getVertices();
143glm::vec3 normal;
144glm::vec3 vert;
145
146// super inefficient, for debug only //
147// ofMesh normalsMesh;
148if( normalsMesh.getNumVertices() != normals.size() * 2 ) {
149normalsMesh.getVertices().resize( normals.size() * 2 );
150normalsMesh.setMode( OF_PRIMITIVE_LINES );
151}
152
153// normalsMesh.getVertices().resize( normals.size() * 2);
154
155if(bFaceNormals) {
156for(int i = 0; i < (int)normals.size(); i++ ) {
157if(i % 3 == 0) {
158vert = (vertices[i]+vertices[i+1]+vertices[i+2]) / 3;
159} else if(i % 3 == 1) {
160vert = (vertices[i-1]+vertices[i]+vertices[i+1]) / 3;
161} else if ( i % 3 == 2) {
162vert = (vertices[i-2]+vertices[i-1]+vertices[i]) / 3;
163}
164normalsMesh.setVertex(i*2, vert);
165normal = glm::normalize(normals[i]);
166normal *= length;
167normalsMesh.setVertex(i*2+1, normal+vert);
168}
169} else {
170for(int i = 0; i < (int)normals.size(); i++) {
171vert = vertices[i];
172normal = glm::normalize(normals[i]);
173normalsMesh.setVertex( i*2, vert);
174normal *= length;
175normalsMesh.setVertex(i*2+1, normal+vert);
176}
177}
178transformGL(); {
179normalsMesh.draw();
180} restoreTransformGL();
181} else {
182ofLogWarning("ofxFBXMesh") << "drawNormals(): mesh normals are disabled for " << getName();
183}
184}
185
186//--------------------------------------------------------------
187ofVbo& ofxFBXMesh::getVbo() {
188_checkSrcMesh();
189if( mSrcMesh ) {
190return mSrcMesh->getVbo();
191}
192ofLogWarning( "ofxFBXMesh::getVbo src node is not set!!" );
193return dummyVbo;
194}
195
196//--------------------------------------------------------------
197ofMesh& ofxFBXMesh::getMesh() {
198return mesh;
199}
200
201//--------------------------------------------------------------
202int ofxFBXMesh::getNumMaterials() {
203return mMaterials.size();
204}
205
206//--------------------------------------------------------------
207vector< shared_ptr<ofxFBXMeshMaterial> > ofxFBXMesh::getMaterials() {
208return mMaterials;
209}
210
211//--------------------------------------------------------------
212void ofxFBXMesh::setMaterialsEnabled(bool ab) {
213for( auto mat : mMaterials ) {
214if( ab ) {
215mat->enable();
216} else {
217mat->disable();
218}
219}
220}
221
222//--------------------------------------------------------------
223vector< shared_ptr<ofxFBXSource::MeshTexture> > ofxFBXMesh::getTextures() {
224vector< shared_ptr<ofxFBXSource::MeshTexture> > ttexs;
225for( auto mat : mMaterials ) {
226if( mat->hasSourceTexture() ) {
227ttexs.push_back( mat->getSrcTexture() );
228}
229}
230return ttexs;
231}
232
233//--------------------------------------------------------------
234bool ofxFBXMesh::hasTexture() {
235return bHasTexture;
236// for( auto mat : mMaterials ) {
237// if( mat->hasTexture() ) {
238// return true;
239// }
240// }
241// return false;
242}
243
244//--------------------------------------------------------------
245ofMesh ofxFBXMesh::getGlobalMesh() {
246glm::mat4 gmat = getGlobalTransformMatrix();
247// transform points into global space //
248ofMesh tmesh = mesh;
249auto& tverts = tmesh.getVertices();
250
251for( int i = 0; i < tverts.size(); i++ ) {
252auto& mp = tverts[i];
253glm::vec4 v = gmat * glm::vec4(mp, 1.0);
254mp = glm::vec3(v.x, v.y, v.z);
255}
256
257glm::quat tq = getGlobalOrientation();
258// transform the normals from local to global space //
259auto& tnormals = tmesh.getNormals();
260for( auto& tn : tnormals ) {
261tn = tq * tn;
262}
263
264return tmesh;
265}
266
267//--------------------------------------------------------------
268ofMesh ofxFBXMesh::getGlobalMeshAroundPosition() {
269glm::vec3 gpos = getGlobalPosition();
270auto tmesh = getGlobalMesh();
271for( auto& tv : tmesh.getVertices() ) {
272tv -= gpos;
273}
274return tmesh;
275}
276
277//--------------------------------------------------------------
278ofMesh ofxFBXMesh::getMeshAroundPositionScaleApplied() {
279glm::vec3 gscale = getGlobalScale();
280glm::vec3 gpos = getGlobalPosition();
281// transform points into global space //
282ofMesh tmesh = mesh;
283auto& tverts = tmesh.getVertices();
284
285for( int i = 0; i < tverts.size(); i++ ) {
286auto& mp = tverts[i];// - gpos;
287mp -= gpos;
288mp = gscale * mp;//glm::vec4(mp, 1.0);
289}
290return tmesh;
291}
292
293#pragma mark private
294//--------------------------------------------------------------
295void ofxFBXMesh::_checkSrcMesh() {
296if( !mSrcMesh && mSrcNode && mSrcNode->getType() == ofxFBXSource::Node::OFX_FBX_MESH ) {
297mSrcMesh = dynamic_pointer_cast<ofxFBXSource::Mesh>(mSrcNode);
298}
299}
300