void display(void) { float component = -0.8213f; Quat q(-1,0,0,0); ushort s0,s1,s2; Quat::EncodeQuat( q, s0, s1, s2 ); Quat q2; Quat::DecodeQuat( s0, s1, s2, q2 ); WbLog( "Default", "(%.5f, %.5f,%.5f,%.5f)\n", q2.w, q2.x, q2.y, q2.z ); short val = Quat::EncodeComponent( component ); float comp2 = Quat::DecodeComponent( val ); WbLog( "Default", "Quantizing: %.5f -> %d -> %.5f\n", component, val, comp2); //clear white, draw with black glClearColor(0, 0, 0, 0); // glColor3f(1.0f, 1.0f, 1.0f); // Enable Texture Mapping ( NEW ) glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspectiv glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); /* GLfloat mat[] = { 1.0, 1.0, 1.0, 1.0 }; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); GLfloat zero[] = { 0,0,0,1.f}; GLfloat ambient[] = {1.0f, 1.0f, 1.0f, 1.0f}; glLightfv( GL_LIGHT0, GL_AMBIENT, zero); glLightfv( GL_LIGHT0, GL_DIFFUSE, ambient); glLightfv( GL_LIGHT0, GL_SPECULAR, zero);*/ glLoadIdentity(); //rot += 0.1f; //glBindTexture(GL_TEXTURE_2D, textureID); //glScalef(4,4,4); glTranslatef(0.0f,-1.0f, -9.6f); // //glTranslatef(0.0f,-10.0f, -40.6f); // glRotatef( rot, 0, 1,0 ); //if(pMesh1); //pMesh1->Render(); if (pMesh ) { // WhiteBox::gVars->pRenderer->BindTexture( pTex->GetTextureId(), 0 ); //pMesh->Render(); } //glRotatef( -rot, 0, 1, 0 ); // glTranslatef( 1.5f, 0.0f, 6.0f); //glTranslatef(1.5f,0.0f,-6.0f); // glRotatef( rot, 0, 1,0 ); //if(pMesh2) //pMesh2->Render(); // glRotatef( -rot, 0, 1, 0 ); /* glColorPointer(3, GL_FLOAT, decl.GetSize(), (void*)decl.GetSingleElementOffset( WhiteBox::CVertexDeclaration::eSE_Color ) ); //glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(SVertex), BUFFER_OFFSET(ColorOffset)); glVertexPointer(3, GL_FLOAT, decl.GetSize(), (void*)decl.GetSingleElementOffset( WhiteBox::CVertexDeclaration::eSE_Position ) ); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);*/ //pMesh2->Render(); /* glBegin(GL_TRIANGLES); // Drawing Using Triangles glVertex3f( 0.0f, 1.0f, 0.0f); // Top glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right glEnd(); */ //WhiteBox::gVars->pRenderer->BindTexture( pTex->GetTextureId(), 0 ); //WhiteBox::gVars->pRenderer->BindTexture( new int(12), 0 ); //WhiteBox::gVars->pRenderer->BindTexture( new int(1), 0 ); //glTranslatef(3.0f,0.0f, -1.0f) ;//0.0f); /* glBegin(GL_QUADS); // Draw A Quad glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left glEnd(); */ // glColor3f( 0.0f, 0.0f, 1.0f ); //glTranslatef(-8,0.0f,0.0f); // glMaterialfv(GL_FRONT, GL_AMBIENT, mat); phase += 0.5f; float angle = Cos( Degree(phase) ) * 40.0f; float angle3 = Cos( Degree(phase * 0.2f) ) * 90.0f; if (true) { size_t count = skel.GetBones().size(); skel.ComputeInvertedGlobalBindPose(); CPose pose; pose.m_boneTransforms.resize( count ); pose.m_boneTransforms[ 1 ].rotation = Quat::CreateRotX( Degree(angle3 ) ) * Quat::CreateRotZ( Degree(angle) ); //pose.m_boneTransforms[ 1 ].position.x = 0.5f; skel.ConvertFromBindToLocalSpace( pose ); skel.ComputeGlobalPose( pose, pose ); WbLog( "Default", "Skel\n" ); for( size_t i=0 ; i < count ; ++i ) { CBone& bone = skel.GetBones()[ i ]; if ( bone.GetParentIndex() >= 0 ) { Vec3 parentPos = pose.m_boneTransforms[ bone.GetParentIndex() ].position; gVars->pRenderer->DrawLine( parentPos, pose.m_boneTransforms[ i ].position, Color::White ); } WbLog( "Default", "Bone %s, father:%d, Pos(%.2f,%.2f,%.2f)\n", bone.GetName().c_str(), bone.GetParentIndex(), pose.m_boneTransforms[ i ].position.x, pose.m_boneTransforms[ i ].position.y, pose.m_boneTransforms[ i ].position.z ); } CPose skinPose; skel.ComputeSkinningPose( pose, skinPose ); for(int i=0 ; i<vert*hori ; ++i) { float w = points[ i ].y / 3.0f; points2[ i ] = (1.0f - w)*(skinPose.m_boneTransforms[ 0] * points[ i ]) + w*(skinPose.m_boneTransforms[ 2] * points[ i ]); } for( size_t i=0 ; i < vert ; ++i ) for( size_t j=0 ; j < hori-1 ; ++j ) { Vec3& pt1 = points2[ hori * i + j ]; Vec3& pt2 = points2[ hori * i + j + 1 ]; gVars->pRenderer->DrawLine( pt1, pt2, Color::Blue ); } WbLog( "Default", " %.2f\n", points[ 0].y ); WbLog( "Default", " %.2f\n", points2[ 0].x ); } glTranslatef(0.55f,0.0f,0.0f); //this draws a square using vertices /* glBegin(GL_QUADS); glVertex2i(0, 0); glVertex2i(0, 128); glVertex2i(128, 128); glVertex2i(128, 0); glEnd();*/ //a more useful helper // glRecti(200, 200, 250, 250); glutSwapBuffers(); }
void CFbxExporter::Export( const String& assetFolder, const String& resourceFolder, const String& filePath ) { log::Log log(new log::DefaultMessages(), -1); FbxConv conv(&log); Settings settings; settings.flipV = false; settings.packColors = false; settings.verbose = true; settings.maxNodePartBonesCount = 120; settings.maxVertexBonesCount = 4; settings.maxVertexCount = INT_MAX; // (1 << 15) - 1; settings.maxIndexCount = INT_MAX; // (1 << 15) - 1; settings.outType = FILETYPE_AUTO; settings.inType = FILETYPE_FBX; settings.inFile = std::string( (assetFolder + filePath).c_str() ); modeldata::Model *model = new modeldata::Model(); if (!conv.load(&settings, model)) { return; } conv.info(model); CSkeleton* pLastSkeleton = nullptr; for (Node* node : model->nodes) { CSkeleton* pSkeleton = new CSkeleton(); ParseModelNode( node, *pSkeleton, "" ); pSkeleton->ComputeGlobalPose(pSkeleton->m_localBindPose, pSkeleton->m_globalBindPose); String skeletonPath = resourceFolder + filePath.get_path_base() + filePath.get_path_name() + ".skel"; gVars->pFileSystem->CreateFileDir( skeletonPath ); pSkeleton->SaveToFile( skeletonPath ); if ( pLastSkeleton != nullptr ) { delete pLastSkeleton; } pLastSkeleton = pSkeleton; } for (Animation* ani : model->animations) { CAnimation* pAnimation = new CAnimation(); for (NodeAnimation* nodeAnim : ani->nodeAnimations) { int idx = pLastSkeleton->m_boneNameToIndex[nodeAnim->node->id.c_str()]; if (idx < 0) continue; const std::vector< Keyframe* >& keyframes = nodeAnim->keyframes; Transform* trackKeys = new Transform[ keyframes.size() ]; for (size_t iKey = 0; iKey < keyframes.size(); ++iKey) { const Keyframe& k = *(keyframes[ iKey ]); Transform transf; transf.rotation = Quat(k.rotation[3], k.rotation[0], k.rotation[1], k.rotation[2]); if (transf.rotation.w < 0.0f) { transf.rotation = -1.0f * transf.rotation; } transf.position = Vec3(k.translation[0], k.translation[1], k.translation[2]); transf.scale = Vec3(k.scale[0], k.scale[1], k.scale[2]); transf = pLastSkeleton->m_localBindPose.m_boneTransforms[idx].GetInverse() * transf; if (String(nodeAnim->node->id.c_str()).Contains("twist")) { transf = Transform(); } trackKeys[ iKey ] = transf; } pAnimation->AddAnimationTack( new CAnimationTrack( CAnimationTrack::eKFF_Transform, trackKeys, keyframes.size() ), idx ); } String animPath = resourceFolder + filePath.get_path_base() + filePath.get_path_name() + ".anim"; gVars->pFileSystem->CreateFileDir(animPath); pAnimation->SaveToFile(animPath); delete pAnimation; } if (pLastSkeleton != nullptr) { delete pLastSkeleton; } for (Mesh* mesh : model->meshes) { CMeshHelper mh; size_t vertexCount = mesh->vertexCount(); size_t vertexFloatCount = mesh->vertexSize; mh.m_positionArray.reserve(vertexCount); mh.m_normalArray.reserve(vertexCount); size_t attCount = mesh->attributes.length(); for (size_t att = 0; att < attCount; ++att) { size_t idx = mesh->attributes.get(att); unsigned int offset = 0; for (unsigned int i = 0; i < idx; i++) if (mesh->attributes.has(i)) offset += (unsigned int)ATTRIBUTE_SIZE(i); switch (idx) { case ATTRIBUTE_POSITION: { for (size_t i = 0; i < vertexCount; ++i) { mh.AddPosition(*(Vec3*)(&mesh->vertices[vertexFloatCount * i])); } break; } case ATTRIBUTE_NORMAL: { for (size_t i = 0; i < vertexCount; ++i) { mh.AddNormal(*(Vec3*)(&mesh->vertices[offset + vertexFloatCount * i])); } break; } case ATTRIBUTE_BLENDWEIGHT0: case ATTRIBUTE_BLENDWEIGHT1: case ATTRIBUTE_BLENDWEIGHT2: case ATTRIBUTE_BLENDWEIGHT3: case ATTRIBUTE_BLENDWEIGHT4: case ATTRIBUTE_BLENDWEIGHT5: case ATTRIBUTE_BLENDWEIGHT6: case ATTRIBUTE_BLENDWEIGHT7: { size_t attributeIndex = idx - (size_t)ATTRIBUTE_BLENDWEIGHT0; for (size_t i = 0; i < vertexCount; ++i) { mh.AddBlendWeight( attributeIndex, *((SVertexBlendWeight*)(&mesh->vertices[offset + vertexFloatCount * i])) ); } break; } } } for (MeshPart* meshPart : mesh->parts) { mh.AddMeshPart(); CMeshPartHelper* part = mh.GetMeshPart(mh.m_meshParts.size()-1); for (unsigned short indice : meshPart->indices) { part->AddIndex(indice); } } String meshPath = resourceFolder + filePath.get_path_base() + filePath.get_path_name() + ".msh"; gVars->pFileSystem->CreateFileDir( meshPath ); mh.SaveToFile( meshPath ); } }