void CalMixer::applyBoneAdjustments() { CalSkeleton * pSkeleton = m_pModel->getSkeleton(); std::vector<CalBone *>& vectorBone = pSkeleton->getVectorBone(); unsigned int i; for( i = 0; i < m_numBoneAdjustments; i++ ) { CalMixerBoneAdjustmentAndBoneId * ba = & m_boneAdjustmentAndBoneIdArray[ i ]; CalBone * bo = vectorBone[ ba->boneId_ ]; CalCoreBone * cbo = bo->getCoreBone(); if( ba->boneAdjustment_.flags_ & CalMixerBoneAdjustmentFlagMeshScale ) { bo->setMeshScaleAbsolute( ba->boneAdjustment_.meshScaleAbsolute_ ); } if( ba->boneAdjustment_.flags_ & CalMixerBoneAdjustmentFlagPosRot ) { const CalVector & localPos = cbo->getTranslation(); CalVector adjustedLocalPos = localPos; CalQuaternion adjustedLocalOri = ba->boneAdjustment_.localOri_; static float const scale = 1.0f; float rampValue = ba->boneAdjustment_.rampValue_; static bool const replace = true; static float const unrampedWeight = 1.0f; bo->blendState( unrampedWeight, adjustedLocalPos, adjustedLocalOri, scale, replace, rampValue ); } } }
void Model::renderBoundingBox() { CalSkeleton *pCalSkeleton = m_calModel->getSkeleton(); std::vector<CalBone*> &vectorCoreBone = pCalSkeleton->getVectorBone(); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINES); for(size_t boneId=0;boneId<vectorCoreBone.size();++boneId) { CalBoundingBox & calBoundingBox = vectorCoreBone[boneId]->getBoundingBox(); CalVector p[8]; calBoundingBox.computePoints(p); glVertex3f(p[0].x,p[0].y,p[0].z); glVertex3f(p[1].x,p[1].y,p[1].z); glVertex3f(p[0].x,p[0].y,p[0].z); glVertex3f(p[2].x,p[2].y,p[2].z); glVertex3f(p[1].x,p[1].y,p[1].z); glVertex3f(p[3].x,p[3].y,p[3].z); glVertex3f(p[2].x,p[2].y,p[2].z); glVertex3f(p[3].x,p[3].y,p[3].z); glVertex3f(p[4].x,p[4].y,p[4].z); glVertex3f(p[5].x,p[5].y,p[5].z); glVertex3f(p[4].x,p[4].y,p[4].z); glVertex3f(p[6].x,p[6].y,p[6].z); glVertex3f(p[5].x,p[5].y,p[5].z); glVertex3f(p[7].x,p[7].y,p[7].z); glVertex3f(p[6].x,p[6].y,p[6].z); glVertex3f(p[7].x,p[7].y,p[7].z); glVertex3f(p[0].x,p[0].y,p[0].z); glVertex3f(p[4].x,p[4].y,p[4].z); glVertex3f(p[1].x,p[1].y,p[1].z); glVertex3f(p[5].x,p[5].y,p[5].z); glVertex3f(p[2].x,p[2].y,p[2].z); glVertex3f(p[6].x,p[6].y,p[6].z); glVertex3f(p[3].x,p[3].y,p[3].z); glVertex3f(p[7].x,p[7].y,p[7].z); } glEnd(); }
void TextureModel::Update(){ CoreAnimation* pAnimation = (CoreAnimation*)m_pObject; if(pAnimation){ pAnimation->update(GetGlobalSetting().m_ShaderParam.m_fEngineTimeDelta*m_fAnimationSpeed); CalSkeleton* pSkel = pAnimation->getSkeleton(); std::vector<CalBone*>& lstBone = pSkel->getVectorBone(); UInt uiBoneCount = lstBone.size(); static Float44 g_TempBoneMatrix[256]; for(UInt i=0;i<uiBoneCount;i++){ const CalQuaternion& q = lstBone[i]->getRotationBoneSpace(); const CalVector& v = lstBone[i]->getTranslationBoneSpace(); Float44 m(Float4(q.w,q.x,q.y,q.z)); Float3* pP = (Float3*)&v; static Float3 vScale(1,1,1); g_TempBoneMatrix[i] = Float44(*pP,vScale,Float4(q));//(m.transpose(); //g_TempBoneMatrix[i].(*pP); // Float44 m(Float4(q.w,q.x,q.y,q.z)); // // m[3][0] = v.x; // m[3][1] = v.y; // m[3][2] = v.z; // g_TempBoneMatrix[i] = m;//.transpose(); } // Render::ITexture::LockRectOption option; // option.pData = NULL; // option.pitch = 1024*16; // if(m_pTempBoneTexture->Lock(&option)){ // memcpy(option.pData,&g_TempBoneMatrix[0],sizeof(Float44)*uiBoneCount); // m_pTempBoneTexture->UnLock(); // // // } //UpdateAttachObject(); } }
void CalSpringSystem::calculateVertices(CalSubmesh *pSubmesh, float deltaTime) { // get the vertex vector of the submesh std::vector<CalVector>& vectorVertex = pSubmesh->getVectorVertex(); // get the physical property vector of the submesh std::vector<CalSubmesh::PhysicalProperty>& vectorPhysicalProperty = pSubmesh->getVectorPhysicalProperty(); // get the physical property vector of the core submesh std::vector<CalCoreSubmesh::PhysicalProperty>& vectorCorePhysicalProperty = pSubmesh->getCoreSubmesh()->getVectorPhysicalProperty(); // loop through all the vertices int vertexId; for(vertexId = 0; vertexId < (int)vectorVertex.size(); ++vertexId) { // get the vertex CalVector& vertex = vectorVertex[vertexId]; // get the physical property of the vertex CalSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId]; // get the physical property of the core vertex CalCoreSubmesh::PhysicalProperty& corePhysicalProperty = vectorCorePhysicalProperty[vertexId]; // store current position for later use CalVector position; position = physicalProperty.position; // only take vertices with a weight > 0 into account if(corePhysicalProperty.weight > 0.0f) { // do the Verlet step physicalProperty.position += (position - physicalProperty.positionOld) * 0.99f + physicalProperty.force / corePhysicalProperty.weight * deltaTime * deltaTime; CalSkeleton *pSkeleton = m_pModel->getSkeleton(); if(m_collision) { std::vector<CalBone *> &m_vectorbone = pSkeleton->getVectorBone(); unsigned long boneId; for(boneId=0; boneId < m_vectorbone.size(); boneId++) { CalBoundingBox p = m_vectorbone[boneId]->getBoundingBox(); bool in=true; float min=1e10; int index=-1; int faceId; for(faceId=0; faceId < 6 ; faceId++) { if(p.plane[faceId].eval(physicalProperty.position)<=0) { in=false; } else { float dist=p.plane[faceId].dist(physicalProperty.position); if(dist<min) { index=faceId; min=dist; } } } if(in && index!=-1) { CalVector normal = CalVector(p.plane[index].a,p.plane[index].b,normal.z = p.plane[index].c); normal.normalize(); physicalProperty.position = physicalProperty.position - min*normal; } in=true; for(faceId=0; faceId < 6 ; faceId++) { if(p.plane[faceId].eval(physicalProperty.position) < 0 ) { in=false; } } if(in) { physicalProperty.position = vectorVertex[vertexId]; } } } } else { physicalProperty.position = vectorVertex[vertexId]; } // make the current position the old one physicalProperty.positionOld = position; // set the new position of the vertex vertex = physicalProperty.position; // clear the accumulated force on the vertex physicalProperty.force.clear(); } // get the spring vector of the core submesh std::vector<CalCoreSubmesh::Spring>& vectorSpring = pSubmesh->getCoreSubmesh()->getVectorSpring(); // iterate a few times to relax the constraints int iterationCount; #define ITERATION_COUNT 2 for(iterationCount = 0; iterationCount < ITERATION_COUNT; ++iterationCount) { // loop through all the springs std::vector<CalCoreSubmesh::Spring>::iterator iteratorSpring; for(iteratorSpring = vectorSpring.begin(); iteratorSpring != vectorSpring.end(); ++iteratorSpring) { // get the spring CalCoreSubmesh::Spring& spring = *iteratorSpring; // compute the difference between the two spring vertices CalVector distance; distance = vectorVertex[spring.vertexId[1]] - vectorVertex[spring.vertexId[0]]; // get the current length of the spring float length; length = distance.length(); if(length > 0.0f) { /*if (spring.springCoefficient == 0) { vectorVertex[spring.vertexId[1]] = vectorVertex[spring.vertexId[0]]; vectorPhysicalProperty[spring.vertexId[1]].position = vectorVertex[spring.vertexId[0]]; } else {*/ float factor[2]; factor[0] = (length - spring.idleLength) / length; factor[1] = factor[0]; if(vectorCorePhysicalProperty[spring.vertexId[0]].weight > 0.0f) { factor[0] /= 2.0f; factor[1] /= 2.0f; } else { factor[0] = 0.0f; } if(vectorCorePhysicalProperty[spring.vertexId[1]].weight <= 0.0f) { factor[0] *= 2.0f; factor[1] = 0.0f; } vectorVertex[spring.vertexId[0]] += distance * factor[0]; vectorPhysicalProperty[spring.vertexId[0]].position = vectorVertex[spring.vertexId[0]]; vectorVertex[spring.vertexId[1]] -= distance * factor[1]; vectorPhysicalProperty[spring.vertexId[1]].position = vectorVertex[spring.vertexId[1]]; //} } } } /* DEBUG-CODE ******************** CalVector spherePosition(Sphere.x, Sphere.y, Sphere.z); float sphereRadius = Sphere.radius; // loop through all the vertices for(vertexId = 0; vertexId < (int)vectorVertex.size(); ++vertexId) { // get the vertex CalVector& vertex = vectorVertex[vertexId]; // get the physical property of the vertex CalSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId]; // get the physical property of the core vertex CalCoreSubmesh::PhysicalProperty& corePhysicalProperty = vectorCorePhysicalProperty[vertexId]; // only take vertices with a weight > 0 into account if(corePhysicalProperty.weight > 0.0f) { CalVector position; position = physicalProperty.position; position -= spherePosition; float length; length = position.normalize(); if(length < sphereRadius) { position *= sphereRadius; position += spherePosition; physicalProperty.position = position; physicalProperty.positionOld = position; vertex = physicalProperty.position; } } } *********************************/ }
void CalMixer::updateSkeleton() { // get the skeleton we need to update CalSkeleton *pSkeleton; pSkeleton = m_pModel->getSkeleton(); if(pSkeleton == 0) return; // clear the skeleton state pSkeleton->clearState(); // get the bone vector of the skeleton std::vector<CalBone *>& vectorBone = pSkeleton->getVectorBone(); // The bone adjustments are "replace" so they have to go first, giving them // highest priority and full influence. Subsequent animations affecting the same bones, // including subsequent replace animations, will have their incluence attenuated appropriately. applyBoneAdjustments(); // loop through all animation actions std::list<CalAnimationAction *>::iterator itaa; for( itaa = m_listAnimationAction.begin(); itaa != m_listAnimationAction.end(); itaa++ ) { // get the core animation instance CalAnimationAction * aa = * itaa; // Manual animations can be on or off. If they are off, they do not apply // to the bone. if( aa->on() ) { CalCoreAnimation * pCoreAnimation = aa->getCoreAnimation(); // get the list of core tracks of above core animation std::list<CalCoreTrack *>& listCoreTrack = pCoreAnimation->getListCoreTrack(); // loop through all core tracks of the core animation std::list<CalCoreTrack *>::iterator itct; for( itct = listCoreTrack.begin(); itct != listCoreTrack.end(); itct++ ) { // get the appropriate bone of the track CalCoreTrack * ct = * itct; if( ct->getCoreBoneId() >= int(vectorBone.size()) ) { continue; } CalBone * pBone = vectorBone[ ct->getCoreBoneId() ]; // get the current translation and rotation CalVector translation; CalQuaternion rotation; ct->getState( aa->getTime(), translation, rotation); // Replace and CrossFade both blend with the replace function. bool replace = aa->getCompositionFunction() != CalAnimation::CompositionFunctionAverage; float scale = aa->getScale(); pBone->blendState( aa->getWeight(), translation, rotation, scale, replace, aa->getRampValue() ); } } } // === What does lockState() mean? Why do we need it at all? It seems only to allow us // to blend all the animation actions together into a temporary sum, and then // blend all the animation cycles together into a different sum, and then blend // the two sums together according to their relative weight sums. I believe this is mathematically // equivalent of blending all the animation actions and cycles together into a single sum, // according to their relative weights. pSkeleton->lockState(); // let the skeleton calculate its final state pSkeleton->calculateState(); }
void CalMixer::updateSkeleton() { // get the skeleton we need to update CalSkeleton *pSkeleton; pSkeleton = m_pModel->getSkeleton(); if(pSkeleton == 0) return; // clear the skeleton state pSkeleton->clearState(); // get the bone vector of the skeleton std::vector<CalBone *>& vectorBone = pSkeleton->getVectorBone(); // loop through all animation actions std::list<CalAnimationAction *>::iterator iteratorAnimationAction; for(iteratorAnimationAction = m_listAnimationAction.begin(); iteratorAnimationAction != m_listAnimationAction.end(); ++iteratorAnimationAction) { // get the core animation instance CalCoreAnimation *pCoreAnimation; pCoreAnimation = (*iteratorAnimationAction)->getCoreAnimation(); // Ask the animation for the pose at the given time std::vector<CalTransform> pose; pose.resize(pCoreAnimation->getTrackCount()); pCoreAnimation->getPose((*iteratorAnimationAction)->getTime(), pose); // Blend the pose into the current bone states for (unsigned bone_id = 0; bone_id < pSkeleton->getCoreSkeleton()->getVectorCoreBone().size(); ++bone_id) { int track_number = pCoreAnimation->getTrackAssignment(bone_id); // Skip this bone if the bone does not have a track assigned in the animation if (track_number == -1) { continue; } // Blend the animation pose with the skeleton CalBone* pBone = vectorBone[bone_id]; pBone->blendState((*iteratorAnimationAction)->getWeight(), pose[track_number].getTranslation(), pose[track_number].getRotation()); } } // lock the skeleton state pSkeleton->lockState(); // loop through all animation cycles std::list<CalAnimationCycle *>::iterator iteratorAnimationCycle; for(iteratorAnimationCycle = m_listAnimationCycle.begin(); iteratorAnimationCycle != m_listAnimationCycle.end(); ++iteratorAnimationCycle) { // get the core animation instance CalCoreAnimation *pCoreAnimation; pCoreAnimation = (*iteratorAnimationCycle)->getCoreAnimation(); // calculate adjusted time float animationTime; if((*iteratorAnimationCycle)->getState() == CalAnimation::STATE_SYNC) { if(m_animationDuration == 0.0f) { animationTime = 0.0f; } else { animationTime = m_animationTime * pCoreAnimation->getDuration() / m_animationDuration; } } else { animationTime = (*iteratorAnimationCycle)->getTime(); } // Ask the animation for the pose at the given time std::vector<CalTransform> pose; pose.resize(pCoreAnimation->getTrackCount()); pCoreAnimation->getPose(animationTime, pose); // Blend the pose into the current bone states for (unsigned index = 0; index < pose.size(); ++index) { int track_number = pCoreAnimation->getTrackAssignment(index); // Skip this bone if the bone does not have a track assigned in the animation if (track_number == -1) { continue; } CalBone* pBone = vectorBone[index]; pBone->blendState((*iteratorAnimationCycle)->getWeight(), pose[track_number].getTranslation(), pose[track_number].getRotation()); } } // lock the skeleton state pSkeleton->lockState(); // let the skeleton calculate its final state pSkeleton->calculateState(); }
void CCal3DSceneNode::render() { if ( bInitialized ) { irr::video::IVideoDriver* driver = SceneManager->getVideoDriver(); driver->setTransform( irr::video::ETS_WORLD, AbsoluteTransformation ); irr::video::S3DVertex tmp; irr::scene::SMeshBuffer mb; unsigned char meshColor[4]; // r g b a // get the renderer of the model CalRenderer* pCalRenderer; pCalRenderer = m_calModel->getRenderer(); pCalRenderer->setNormalization( true ); if ( this->DebugDataVisible ) { irr::video::SMaterial mat; mat.Wireframe = false; mat.Lighting = false; driver->setMaterial( mat ); driver->draw3DBox( Box ); CalSkeleton* pCalSkeleton = m_calModel->getSkeleton(); pCalSkeleton->calculateBoundingBoxes(); std::vector<CalBone*>& vectorCoreBone = pCalSkeleton->getVectorBone(); irr::core::aabbox3df b; CalVector p[8]; Vector3 v[8]; for ( size_t boneId = 0; boneId < vectorCoreBone.size(); ++boneId ) { CalBone* bone = vectorCoreBone[boneId]; CalBoundingBox& calBoundingBox = bone->getBoundingBox(); calBoundingBox.computePoints( p ); for ( int i = 0; i < 8; ++i ) { v[i].set( p[i].x, p[i].y, p[i].z ); } driver->setMaterial( mat ); // draw the box driver->draw3DLine( v[0], v[1], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[0], v[2], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[1], v[3], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[2], v[3], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[4], v[5], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[4], v[6], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[5], v[7], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[6], v[7], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[0], v[4], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[1], v[5], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[2], v[6], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[3], v[7], irr::video::SColor( 255, 0, 0, 255 ) ); //printf("F: %f\n", v[0].X); } } // begin the rendering loop if ( pCalRenderer->beginRendering() ) { // get the number of meshes int meshCount; meshCount = pCalRenderer->getMeshCount(); // render all meshes of the model int meshId; for ( meshId = 0; meshId < meshCount; meshId++ ) { // get the number of submeshes int submeshCount; submeshCount = pCalRenderer->getSubmeshCount( meshId ); // render all submeshes of the mesh int submeshId; for ( submeshId = 0; submeshId < submeshCount; submeshId++ ) { // select mesh and submesh for further data access if ( pCalRenderer->selectMeshSubmesh( meshId, submeshId ) ) { // set the material ambient color pCalRenderer->getAmbientColor( &meshColor[0] ); material.AmbientColor.set( meshColor[3], meshColor[0], meshColor[1], meshColor[2] ); // set the material diffuse color pCalRenderer->getDiffuseColor( &meshColor[0] ); material.DiffuseColor.set( meshColor[3], meshColor[0], meshColor[1], meshColor[2] ); // set the material specular color pCalRenderer->getSpecularColor( &meshColor[0] ); material.SpecularColor.set( meshColor[3], meshColor[0], meshColor[1], meshColor[2] ); // set the material shininess factor material.Shininess = pCalRenderer->getShininess(); // get the transformed vertices of the submesh static float meshVertices[3000][3]; int vertexCount = 0; // TODO: //if (KERNEL.GetTicks() % 3 == 0) //- make lod dependent? vertexCount = pCalRenderer->getVertices( &meshVertices[0][0] ); // get the transformed normals of the submesh static float meshNormals[3000][3]; int normalsCount = 0; // if (KERNEL.GetTicks() % 3 == 0) normalsCount = pCalRenderer->getNormals( &meshNormals[0][0] ); // get the texture coordinates of the submesh static float meshTextureCoordinates[3000][2]; int textureCoordinateCount = 0; textureCoordinateCount = pCalRenderer->getTextureCoordinates( 0, &meshTextureCoordinates[0][0] ); // get the faces of the submesh static CalIndex meshFaces[5000][3]; int faceCount = 0; //if (KERNEL.GetTicks() % 12 == 0) faceCount = pCalRenderer->getFaces( &meshFaces[0][0] ); if ( ( pCalRenderer->getMapCount() > 0 ) && ( textureCoordinateCount > 0 ) ) { irr::video::ITexture* t = static_cast<irr::video::ITexture*>( pCalRenderer->getMapUserData( 0 ) ); material.Texture1 = t; } static S3DVertex vs[5000]; for ( int i = 0; i < vertexCount; i++ ) { vs[i].Pos.set( meshVertices[i][0], meshVertices[i][1], meshVertices[i][2] ); vs[i].Normal.set( meshNormals[i][0], meshNormals[i][1], meshNormals[i][2] ); vs[i].TCoords.set( meshTextureCoordinates[i][0], meshTextureCoordinates[i][1] ); vs[i].Color = irr::video::SColor( 255, 255, 255, 255 ); } static u16 is[5000]; for ( int i = 0; i < faceCount; i += 1 ) { is[i * 3 + 0] = meshFaces[i][0]; is[i * 3 + 1] = meshFaces[i][1]; is[i * 3 + 2] = meshFaces[i][2]; } //mb.Vertices.clear(); //mb.Vertices.reallocate(vertexCount); //for(int i=0;i<vertexCount;i++) //{ // tmp.Pos.set(meshVertices[i][0],meshVertices[i][1],meshVertices[i][2]); // tmp.Normal.set(meshNormals[i][0],meshNormals[i][1],meshNormals[i][2]); // tmp.TCoords.set(meshTextureCoordinates[i][0],meshTextureCoordinates[i][1]); // tmp.Color=irr::video::SColor(255,255,255,255); // mb.Vertices.push_back(tmp); //} //mb.Indices.clear(); //mb.Indices.reallocate(faceCount); //for(int i=0; i<faceCount; ++i) //{ // mb.Indices.push_back(meshFaces[i][0]); // mb.Indices.push_back(meshFaces[i][1]); // mb.Indices.push_back(meshFaces[i][2]); //} // draw driver->setMaterial( material ); //driver->drawIndexedTriangleList(mb.Vertices.const_pointer(),mb.Vertices.size(),mb.Indices.const_pointer(),faceCount); driver->drawIndexedTriangleList( vs, vertexCount, is, faceCount ); //driver->drawMeshBuffer(&mb); //CONSOLE.addx("#Verts %d #Norm %d #Tex %d #Faces %d #Map %d", // vertexCount,normalsCount,textureCoordinateCount,faceCount, pCalRenderer->getMapCount()); } } } // end the rendering pCalRenderer->endRendering(); } } }