Example #1
0
CalSpringSystem::CalSpringSystem()
  : m_pModel(0)
{
	m_vGravity = CalVector(0.0f, 0.0f, -98.1f);

	// We add this force to simulate some movement

	m_vForce = CalVector(0.0f, 0.5f, 0.0f);
}
Example #2
0
CalSpringSystem::CalSpringSystem(CalModel* pModel)
{
  assert(pModel);
  m_pModel = pModel;
  
  m_vGravity = CalVector(0.0f, 0.0f, -98.1f);
  // We add this force to simulate some movement
  m_vForce = CalVector(0.0f, 0.5f, 0.0f);
  m_collision=false;
}
Example #3
0
void CalCoreBone::initBoundingBox()
{
   CalQuaternion rot;
   rot=m_rotationBoneSpace;   
  
   rot.invert();
   
   CalVector dir = CalVector(1.0f,0.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[0].setNormal(dir);

   dir = CalVector(-1.0f,0.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[1].setNormal(dir);

   dir = CalVector(0.0f,1.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[2].setNormal(dir);

   dir = CalVector(0.0f,-1.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[3].setNormal(dir);

   dir = CalVector(0.0f,0.0f,1.0f);
   dir*=rot;
   m_boundingBox.plane[4].setNormal(dir);

   dir = CalVector(0.0f,0.0f,-1.0f);
   dir*=rot;
   m_boundingBox.plane[5].setNormal(dir);
}
Example #4
0
/////////////////////////////////////
// Purpose:	set the relative translation
//			of the given bone
// Output:	bone moved
// Return:	none
/////////////////////////////////////
void IgfxObject::BoneSetTrans(s32 boneID, const Vec3D & loc)
{
	if(m_pCalModel)
	{
		Vec3D trans; BoneGetTrans(boneID, &trans);

		CalSkeleton *pSkel = m_pCalModel->getSkeleton();
		CalBone *pBone = pSkel->getBone(boneID);

		if(pBone)
		{
			pBone->setTranslation(CalVector(trans.x+loc.x, trans.y+loc.y, trans.z+loc.z));
			pBone->calculateState();
		}
	}
}
Example #5
0
void CalBone::calculateBoundingBox()
{
   if(!getCoreBone()->isBoundingBoxPrecomputed())
	   return;

   CalVector dir = CalVector(1.0f,0.0f,0.0f);
   dir*=getTransformMatrix();
   m_boundingBox.plane[0].setNormal(dir);

   dir = CalVector(-1.0f,0.0f,0.0f);
   dir*=getTransformMatrix();
   m_boundingBox.plane[1].setNormal(dir);

   dir = CalVector(0.0f,1.0f,0.0f);
   dir*=getTransformMatrix();
   m_boundingBox.plane[2].setNormal(dir);

   dir = CalVector(0.0f,-1.0f,0.0f);
   dir*=getTransformMatrix();
   m_boundingBox.plane[3].setNormal(dir);

   dir = CalVector(0.0f,0.0f,1.0f);
   dir*=getTransformMatrix();
   m_boundingBox.plane[4].setNormal(dir);

   dir = CalVector(0.0f,0.0f,-1.0f);
   dir*=getTransformMatrix();
   m_boundingBox.plane[5].setNormal(dir);
   
   int i;
   
   for(i=0;i< 6; i++)
   {
       CalVector position;
       getCoreBone()->getBoundingData(i,position);
      
       position*=getTransformMatrix();
       position+=getTranslationBoneSpace();

       int planeId;
       for(planeId = 0; planeId < 6; ++planeId)
       {
          if(m_boundingBox.plane[planeId].eval(position) < 0.0f)
          {
             m_boundingBox.plane[planeId].setPosition(position);
          }
       }
       
   }
}
Example #6
0
CalVector CalPhysique::calculateVertex(CalSubmesh *pSubmesh, int vertexId)
{
  // get bone vector of the skeleton
  std::vector<CalBone *>& vectorBone = m_pModel->getSkeleton()->getVectorBone();

  // get vertex of the core submesh
  std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pSubmesh->getCoreSubmesh()->getVectorVertex();

  // get physical property vector of the core submesh
  //std::vector<CalCoreSubmesh::PhysicalProperty>& vectorPhysicalProperty = pSubmesh->getCoreSubmesh()->getVectorPhysicalProperty();

  // get the sub morph target vector from the core sub mesh
  std::vector<CalCoreSubMorphTarget*>& vectorSubMorphTarget =
  pSubmesh->getCoreSubmesh()->getVectorCoreSubMorphTarget();



  // get the number of morph targets
  int morphTargetCount = pSubmesh->getMorphTargetWeightCount();

  // get the vertex
  CalCoreSubmesh::Vertex& vertex = vectorVertex[vertexId];

  // blend the morph targets
  CalVector position=vertex.position;


  {

    int morphTargetId;
    for(morphTargetId=0; morphTargetId < morphTargetCount;++morphTargetId)
    {
      CalCoreSubMorphTarget::BlendVertex	blendVertex;
	  vectorSubMorphTarget[morphTargetId]->getBlendVertex(vertexId, blendVertex);
      float currentWeight = pSubmesh->getMorphTargetWeight(morphTargetId);
      position.x += currentWeight*blendVertex.position.x;
      position.y += currentWeight*blendVertex.position.y;
      position.z += currentWeight*blendVertex.position.z;
    }
  }

  // initialize vertex
  float x, y, z;
  x = 0.0f;
  y = 0.0f;
  z = 0.0f;

  // blend together all vertex influences
  int influenceId;
  int influenceCount=(int)vertex.vectorInfluence.size();
  if(influenceCount == 0)
  {
    x = position.x;
    y = position.y;
    z = position.z;
  }
  else
  {
	  for(influenceId = 0; influenceId < influenceCount; ++influenceId)
	  {
		  // get the influence
		  CalCoreSubmesh::Influence& influence = vertex.vectorInfluence[influenceId];

		  // get the bone of the influence vertex
		  CalBone *pBone;
		  pBone = vectorBone[influence.boneId];

		  // transform vertex with current state of the bone
		  CalVector v(position);
		  v *= pBone->getTransformMatrix();
		  v += pBone->getTranslationBoneSpace();

		  x += influence.weight * v.x;
		  y += influence.weight * v.y;
		  z += influence.weight * v.z;
	  }
  }
  /*
  // save vertex position
  if(pSubmesh->getCoreSubmesh()->getSpringCount() > 0 && pSubmesh->hasInternalData())
  {
    // get the pgysical property of the vertex
    CalCoreSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId];

    // assign new vertex position if there is no vertex weight
    if(physicalProperty.weight == 0.0f)
    {
      pVertexBuffer[0] = x;
      pVertexBuffer[1] = y;
      pVertexBuffer[2] = z;
    }
  }
  else
  {
    pVertexBuffer[0] = x;
    pVertexBuffer[1] = y;
    pVertexBuffer[2] = z;
  }
  */
  // return the vertex
  //return CalVector(x, y, z);
  return CalVector(x*m_axisFactorX,y*m_axisFactorY,z*m_axisFactorZ);
}
Example #7
0
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;
      }
    }
  }
*********************************/
}
Example #8
0
static
void
generateTangentAndHandednessBuffer( osgCal::MeshData* m,
                                    const CalIndex*   indexBuffer )
{
    if ( !m->texCoordBuffer.valid() )
    {
        return;
    }

    int vertexCount = m->vertexBuffer->size();
    int faceCount   = m->getIndicesCount() / 3;    

    m->tangentAndHandednessBuffer = new TangentAndHandednessBuffer( vertexCount );

    CalVector* tan1 = new CalVector[vertexCount];
    CalVector* tan2 = new CalVector[vertexCount];

    const GLfloat* texCoordBufferData = (GLfloat*) m->texCoordBuffer->getDataPointer();

    const GLfloat* vb = (GLfloat*) m->vertexBuffer->getDataPointer();
#ifdef OSG_CAL_BYTE_BUFFERS
    GLfloat* thb = new GLfloat[ vertexCount*4 ];
    const GLfloat* nb = floatNormalBuffer;
#else
    GLfloat* thb = (GLfloat*) m->tangentAndHandednessBuffer->getDataPointer();
//    GLshort* thb = (GLshort*) m->tangentAndHandednessBuffer->getDataPointer();
    const GLfloat* nb = (GLfloat*) m->normalBuffer->getDataPointer();
#endif

    for ( int face = 0; face < faceCount; face++ )
    {
        for ( int j = 0; j < 3; j++ )
        {
            // there seems to be no visual difference in calculating
            // tangent per vertex (as is tan1[i1] += spos(j=0,1,2))
            // or per face (tan1[i1,i2,i3] += spos)
            CalIndex i1 = indexBuffer[face*3+(j+0)%3];
            CalIndex i2 = indexBuffer[face*3+(j+1)%3];
            CalIndex i3 = indexBuffer[face*3+(j+2)%3];
        
            const float* v1 = &vb[i1*3];
            const float* v2 = &vb[i2*3];
            const float* v3 = &vb[i3*3];

            const float* w1 = &texCoordBufferData[i1*2];
            const float* w2 = &texCoordBufferData[i2*2];
            const float* w3 = &texCoordBufferData[i3*2];

#define x(_a) (_a[0])
#define y(_a) (_a[1])
#define z(_a) (_a[2])
        
            float x1 = x(v2) - x(v1);
            float x2 = x(v3) - x(v1);
            float y1 = y(v2) - y(v1);
            float y2 = y(v3) - y(v1);
            float z1 = z(v2) - z(v1);
            float z2 = z(v3) - z(v1);
        
            float s1 = x(w2) - x(w1);
            float s2 = x(w3) - x(w1);
            float t1 = y(w2) - y(w1);
            float t2 = y(w3) - y(w1);

#undef x
#undef y
#undef z
        
            //float r = 1.0F / (s1 * t2 - s2 * t1);
            float r = (s1 * t2 - s2 * t1) < 0 ? -1.0 : 1.0;
            CalVector sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
                           (t2 * z1 - t1 * z2) * r);
            CalVector tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
                           (s1 * z2 - s2 * z1) * r);

            // sdir & tdir can be 0 (when UV unwrap doesn't exists
            // or has errors like coincide points)
            // we ignore them
            if ( sdir.length() > 0 )
            {
                sdir.normalize(); 

                tan1[i1] += sdir;
                //tan1[i2] += sdir;
                //tan1[i3] += sdir;
            }

            if ( tdir.length() > 0 )
            {
                tdir.normalize();

                tan2[i1] += tdir;
                //tan2[i2] += tdir;
                //tan2[i3] += tdir;
            }
        }
    }
    
    for (long a = 0; a < vertexCount; a++)
    {
        CalVector tangent;
        CalVector binormal;
        CalVector t = tan1[a];
        CalVector b = tan2[a];
        CalVector n = CalVector( nb[a*3+0],
                                 nb[a*3+1],
                                 nb[a*3+2] );

        // tangent & bitangent can be zero when UV unwrap doesn't exists
        // or has errors like coincide points
        if ( t.length() > 0 )
        {
            t.normalize();
        
            // Gram-Schmidt orthogonalize
            tangent = t - n * (n*t);
            tangent.normalize();

            // Calculate handedness
            binormal = CalVector(n % tangent) *
                ((((n % t) * b) < 0.0F) ? -1.0f : 1.0f);
            binormal.normalize();
        }
        else if ( b.length() > 0 )
        {
            b.normalize();
        
            // Gram-Schmidt orthogonalize
            binormal = b - n * (n*b);
            binormal.normalize();

            // Calculate handedness
            tangent = CalVector(n % binormal) *
                ((((n % b) * t) < 0.0F) ? -1.0f : 1.0f);
            tangent.normalize();
        }

//         std::cout << "t = " << tangent.x  << '\t' << tangent.y  << '\t' << tangent.z  << '\n';
//         std::cout << "b = " << binormal.x << '\t' << binormal.y << '\t' << binormal.z << '\n';
//            std::cout << "n = " << n.x        << '\t' << n.y        << '\t' << n.z        << '\n';

//         thb[a*4+0] = floatToHalf( tangent.x ); //tangent.x * 0x7FFF;
//         thb[a*4+1] = floatToHalf( tangent.y ); //tangent.y * 0x7FFF;
//         thb[a*4+2] = floatToHalf( tangent.z ); //tangent.z * 0x7FFF;
//         thb[a*4+3] = floatToHalf((((n % tangent) * binormal) > 0.0F) ? -1.0f : 1.0f); // handedness
        thb[a*4+0] = tangent.x; 
        thb[a*4+1] = tangent.y;
        thb[a*4+2] = tangent.z;
        thb[a*4+3] = ((((n % tangent) * binormal) > 0.0F) ? -1.0f : 1.0f); // handedness
    }
    
    delete[] tan1;
    delete[] tan2;

#ifdef OSG_CAL_BYTE_BUFFERS
    GLbyte* tangents = (GLbyte*) tangentBuffer->getDataPointer();
    GLbyte* binormals = (GLbyte*) binormalBuffer->getDataPointer();

    for ( int i = 0; i < vertexCount*3; i++ )
    {
        tangents[i]  = static_cast< GLbyte >( tangentBuffer[i]*127.0 );
        binormals[i] = static_cast< GLbyte >( binormalBuffer[i]*127.0 );
        //std::cout << (int)tangents[i] << '\n';
    }

    delete[] tangentBuffer;
    delete[] binormalBuffer;
#endif
}
bool CPhysxSkeleton::AddSphericalJoint(CXMLTreeNode _XMLObjects)
{
    string l_szActor1, l_szActor2, l_szDirection;

    l_szActor1        = _XMLObjects.GetAttribute<std::string>("Actor1" , "");
    l_szActor2        = _XMLObjects.GetAttribute<std::string>("Actor2" , "");
    l_szDirection = _XMLObjects.GetAttribute<std::string>("Direction" , "");

    SSphericalLimitInfo l_pJointInfo = GetJointParameterInfo(_XMLObjects);

    CPhysxBone* l_pBone1 = GetPhysxBoneByName(l_szActor1);
    CPhysxBone* l_pBone2 = GetPhysxBoneByName(l_szActor2);

    CPhysicActor* l_pActor1 = 0;
    CPhysicActor* l_pActor2 = 0;
    l_pActor1 = l_pBone1->GetPhysxActor();

    CPhysicSphericalJoint* l_pSphericalJoint = 0;
    l_pSphericalJoint = new CPhysicSphericalJoint();


    CalVector l_vCalVect = l_pBone1->GetCalBone()->getTranslationAbsolute();
    Math::Vect3f l_vJointPoint(-l_vCalVect.x, l_vCalVect.y, l_vCalVect.z);
    l_vJointPoint = m_mTransform * l_vJointPoint;
    Math::Vect3f l_vAxis;
    CalVector l_vVect;



    //MES PROVES
    if (l_szDirection == "Out")
    {
        if (l_pBone1->GetChildList().size() > 0)
        {
            int l_pChildId = l_pBone1->GetChildList()[0];
            string l_szNameChild = m_pCalSkeleton->getBone(l_pChildId)->getCoreBone()->getName();
            CPhysxBone* l_pPhysChild = GetPhysxBoneByName(l_szNameChild);
            l_vVect = l_pPhysChild->GetCalBone()->getTranslationAbsolute();
            l_vVect.x = -l_vVect.x;
            /*  l_vAxis = Math::Vect3f(l_vVect.x-l_vJointPoint.x,l_vVect.y-l_vJointPoint.y,l_vVect.z-l_vJointPoint.z);
                l_vAxis.Normalize();*/
        }
        else
        {
            Math::Vect3f l_vMiddle = l_pBone1->GetMiddlePoint();
            l_vVect = CalVector(l_vMiddle.x, l_vMiddle.y, l_vMiddle.z);
            /*  l_vAxis(l_vMiddle.x-l_vJointPoint.x,l_vMiddle.y-l_vJointPoint.y,l_vMiddle.z-l_vJointPoint.z);
                l_vAxis.Normalize();*/
        }
    }
    else if (l_szDirection == "In")
    {
      /*
        if (!l_pBone1->IsBoneRoot())
        {
            int l_pParentID = l_pBone1->GetParentID();
            string l_szNameParent = m_pCalSkeleton->getBone(l_pParentID)->getCoreBone()->getName();
            CPhysxBone* l_pPhysParent = GetPhysxBoneByName(l_szNameParent);
            CalVector l_vVect = l_pPhysParent->GetCalBone()->getTranslationAbsolute();
            l_vVect.x = -l_vVect.x;
            /*  l_vAxis = Math::Vect3f(l_vVect.x-l_vJointPoint.x,l_vVect.y-l_vJointPoint.y,l_vVect.z-l_vJointPoint.z);
                l_vAxis.Normalize();
        }
    */
    }


    Math::Vect3f l_vAxisAux(l_vVect.x, l_vVect.y, l_vVect.z);
    l_vAxisAux = m_mTransform * l_vAxisAux;
    l_vAxis = Math::Vect3f(l_vAxisAux.x - l_vJointPoint.x, l_vAxisAux.y - l_vJointPoint.y, l_vAxisAux.z - l_vJointPoint.z);
    l_vAxis.Normalize();

    l_pJointInfo.m_vAnchor = l_vJointPoint;
    l_pJointInfo.m_vAxis = l_vAxis;



    if (l_szActor2 == "NULL")
    {
        //l_pSphericalJoint->SetInfoComplete(l_vJointPoint,l_vAxis,l_pActor1);
        l_pSphericalJoint->SetInfoRagdoll(l_pJointInfo, l_pActor1);
    }
    else
    {
        l_pActor2 = l_pBone2->GetPhysxActor();
        //l_pSphericalJoint->SetInfoComplete(l_vJointPoint,l_vAxis,l_pActor1,l_pActor2);
        l_pSphericalJoint->SetInfoRagdoll(l_pJointInfo, l_pActor1, l_pActor2);
    }
    PhysXMInstance->AddPhysicSphericalJoint(l_pSphericalJoint);
    m_vSphericalJoints.push_back(l_pSphericalJoint);

    return true;
}
Example #10
0
void IKTagger::update( float elapsed )
{
	bool do_ik = false; 
	float ik_fade_speed = 1.0f;
	bool sidestep_allowed = false;
	model.updateAnimation( elapsed );
		
	switch( state )
	{
		case TS_WAITING:
			break;
	
		case TS_WALKON:
		{
			// check for walk cycle
			CalVector loop_root_pos;
			if ( model.animationDidLoop( "walk", &loop_root_pos ) )
			{
				printf("-- walk looped\n");
				root_pos += (loop_root_pos)-model.getRootBonePosition();
				if ( fabsf(root_pos.x-tag_start_x) < fabsf(walk_cycle_dx) )
				{
					// stop the walk
					model.stopCycle( WALK_ANIM );
					model.startCycle( IDLE_ANIM );
					model.doAction( WALK_TO_TURN_ANIM );
					// turning
					state = TS_WALK_TO_TURN;
					printf(" --> turning\n");
				}
			}

		}			
			break;
			
		
		case TS_WALK_TO_TURN:
		{
			do_ik = false;
			ik_target_weight = 1.0f;
			ik_fade_speed = 0.33f;
			if ( model.actionDidFinish( WALK_TO_TURN_ANIM ) )
			{
				// animation finished: update root position from animation displacement
				setRootPosition( root_pos+walk_to_turn_root_displacement );
				// now tagging 
				state = TS_TAGGING;
				printf(" --> tagging\n");
			}
		}
			break;
			
		case TS_TAGGING:
		{
			do_ik = true;
			if ( ik_weight > 0.9f )
				sidestep_allowed = true;
			ik_target_weight = 1.0f;

			// check for sidestep
			// if finished, update root position from sidestep displacement
			if ( sidestep_running && model.actionDidFinish( SIDESTEP_L_ANIM ) )
			{
				printf("sidestep l finished\n");
				sidestep_running = false;
				setRootPosition( root_pos+sidestep_l_root_displacement );
			}
			if ( sidestep_running && model.actionDidFinish( SIDESTEP_R_ANIM )  )
			{
				printf("sidestep r finished\n");
				sidestep_running = false;
				setRootPosition( root_pos+sidestep_r_root_displacement );
			}
			if ( sidestep_running && model.actionDidFinish( SIDESTEP_BIG_L_ANIM ) )
			{
				printf("sidestep big l finished\n");
				sidestep_running = false;
				setRootPosition( root_pos+sidestep_big_l_root_displacement );
			}
			if ( sidestep_running && model.actionDidFinish( SIDESTEP_BIG_R_ANIM )  )
			{
				printf("sidestep big r finished\n");
				sidestep_running = false;
				setRootPosition( root_pos+sidestep_big_r_root_displacement );
			}
			
			// wait for sidesteps to finish
			if ( !sidestep_running && should_walk_off )
			{
				state = TS_TURN_TO_WALK;
				model.doAction( TURN_TO_WALK_ANIM );
				sidestep_allowed = false;
				
				printf(" --> turn_to_walk\n") ;
			}
		}
			break;
			


		case TS_TURN_TO_WALK:
		{
			do_ik = true;
			ik_target_weight = 0.0f;
			
			// check if turn is finished the walkoff
			if ( model.actionDidFinish( TURN_TO_WALK_ANIM ) )
			{
				setRootPosition( root_pos+turn_to_walk_root_displacement );
				model.stopCycle( IDLE_ANIM );
				model.startCycle( WALK_ANIM );
				// push through the new cycle immediately
				model.updateAnimation( 0.000001f );
				state = TS_WALKOFF;
				do_ik = false;
				printf(" --> walkoff\n");
			}
		}
			break;
			
			
		case TS_WALKOFF:
		{
			if ( model.animationDidLoop( "walk" ) )
			{
				printf("-- walk looped\n");
				setRootPosition( root_pos + walk_root_displacement );
				if ( root_pos.x < SCREEN_VISIBLE_RIGHT )
				{
					state = TS_FINISHED;
					model.stopCycle( WALK_ANIM );
				}
			}
		}
			break;
			

		case TS_FINISHED:
			break;
			
			
		default:
			break;
	}

	
	if ( do_ik )
	{
		// update ik weight
		float inc = elapsed*ik_fade_speed;
		if ( ik_weight > ik_target_weight )
			ik_weight -= min(inc,ik_weight-ik_target_weight);
		else
			ik_weight += min(inc,ik_target_weight-ik_weight);
		// ease in/out
		float ik_weight_eased = 0.5f+0.5f*cosf((1.0f-ik_weight)*PI);
		//printf("ik weight: target %7.5f, curr %7.5f\n", ik_target_weight, ik_weight );
		//ik_weight += (ik_target_weight-ik_weight)*speed;
		
		character.pullFromModel();
		character.solve( 2 );
		character.pushToModel( true, ik_weight_eased );
		model.updateMesh();
		
		CalVector arm_actual_position = model.getBonePosition( tag_arm );
		ofxVec3f arm_target = character.getTarget(tag_arm);
		CalVector bone_target_delta = CalVector(arm_target.x,arm_target.y,arm_target.z)-arm_actual_position;
		// vertical distance has less effect
		bone_target_delta.y *= 0.5f;
		float distance = bone_target_delta.length();
		float discomfort = distance/COMFORT_DISTANCE_THRESH;
		if ( discomfort > 1.0f && !sidestep_running && sidestep_allowed )
		{
			// need to move feet
			string anim;
			if ( bone_target_delta.x < 0 )
			{
				if (bone_target_delta.x < -0.75f )
					anim = SIDESTEP_BIG_L_ANIM;
				else
					anim = SIDESTEP_L_ANIM;
			}
			else
			{
				if (bone_target_delta.x > 0.75f )
					anim = SIDESTEP_BIG_R_ANIM;
				else
					anim = SIDESTEP_R_ANIM;
			}
			printf("starting %s, target delta is %f, discomfort %f\n", anim.c_str(), bone_target_delta.x, discomfort );
			model.doAction( anim, 1.0f );
			sidestep_running = true;
		}
		last_discomfort = discomfort;
	}
	else
		last_discomfort = 100.0f;
}
Example #11
0
void CalCoreBone::calculateBoundingBox(CalCoreModel * pCoreModel)
{
   int boneId =  m_pCoreSkeleton->getCoreBoneId(m_strName);
   bool bBoundsComputed=false;
   int planeId;
   
   CalQuaternion rot;
   rot=m_rotationBoneSpace;   
  
   rot.invert();
   
   CalVector dir = CalVector(1.0f,0.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[0].setNormal(dir);

   dir = CalVector(-1.0f,0.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[1].setNormal(dir);

   dir = CalVector(0.0f,1.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[2].setNormal(dir);

   dir = CalVector(0.0f,-1.0f,0.0f);
   dir*=rot;
   m_boundingBox.plane[3].setNormal(dir);

   dir = CalVector(0.0f,0.0f,1.0f);
   dir*=rot;
   m_boundingBox.plane[4].setNormal(dir);

   dir = CalVector(0.0f,0.0f,-1.0f);
   dir*=rot;
   m_boundingBox.plane[5].setNormal(dir);
   
   int meshId;
   for(meshId=0; meshId < pCoreModel->getCoreMeshCount(); ++meshId)
   {
       CalCoreMesh * pCoreMesh = pCoreModel->getCoreMesh(meshId);
	   
       int submeshId;
       for(submeshId=0;submeshId<pCoreMesh->getCoreSubmeshCount();submeshId++)
       {
		   CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId);
		   
		   if(pCoreSubmesh->getSpringCount()==0)
		   {
			   
			   std::vector<CalCoreSubmesh::Vertex>& vectorVertex =  pCoreSubmesh->getVectorVertex();
			   for(size_t vertexId=0;vertexId <vectorVertex.size(); ++vertexId)
			   {
				   for(size_t influenceId=0;influenceId<vectorVertex[vertexId].vectorInfluence.size();++influenceId)
				   {
					   if(vectorVertex[vertexId].vectorInfluence[influenceId].boneId == boneId && vectorVertex[vertexId].vectorInfluence[influenceId].weight > 0.5f)
					   {						   
						   for(planeId = 0; planeId < 6; ++planeId)
						   {
							   if(m_boundingBox.plane[planeId].eval(vectorVertex[vertexId].position) < 0.0f)
							   {
								   m_boundingBox.plane[planeId].setPosition(vectorVertex[vertexId].position);
								   m_boundingPosition[planeId]=vectorVertex[vertexId].position;
								   bBoundsComputed=true;
							   }
						   }
					   }
				   }
			   }	
		   }
	   }
   }

   // To handle bones with no vertices assigned 
   if(!bBoundsComputed) 
   { 
	   for(planeId = 0; planeId < 6; ++planeId) 
	   { 
		   m_boundingBox.plane[planeId].setPosition(m_translation); 
		   m_boundingPosition[planeId] = m_translation; 
	   } 
   } 
   
   m_boundingBoxPrecomputed = true;
}
Example #12
0
void CalCoreSkeleton::rotate(CalQuaternion &rot) {
    cal3d::RotateTranslate rt(rot, CalVector(0, 0, 0));
    rotateTranslate(rt);
}