Exemplo n.º 1
0
void RotationMC::BeginLive(TimeValue t)
	{
	// Set the base point to the controller value at the start time.
	Quat q;
	cont->GetValue(t,&q,FOREVER,CTRL_ABSOLUTE);	
	QuatToEuler(q,base);	
	}
Exemplo n.º 2
0
void RotationMC::BeginCapture(Interval record,TimeValue sampSize)
	{
	// Set the base point to the controller value at the start time.
	Quat q;
	cont->GetValue(record.Start(),&q,FOREVER,CTRL_ABSOLUTE);	
	QuatToEuler(q,base);

	// Allocate a data buffer
	sampleCount = record.Duration()/sampSize + 1;
	data = new Point3[sampleCount];
	for (int i=0; i<sampleCount; i++) data[i] = Point3(0,0,0);
	}
void Unreal3DExport::WriteTracking()
{
    Tab<Point3> Loc;
    Tab<Quat> Quat;
    Tab<Point3> Euler;

    Loc.SetCount(FrameCount);
    Quat.SetCount(FrameCount);
    Euler.SetCount(FrameCount);

    for( int n=0; n<TrackedNodes.Count(); ++n )
    {
        IGameNode* node = TrackedNodes[n];

        for( int t=0; t<FrameCount; ++t )
        {            
            // Progress
            CheckCancel();
            
            // Set frame
            int curframe = FrameStart + t;
            pScene->SetStaticFrame(curframe);

            // Write tracking
            GMatrix objTM = node->GetWorldTM();
            Loc[t] = objTM.Translation();
            Quat[t] = objTM.Rotation();

            float eu[3];
            QuatToEuler(Quat[t],eu);
            Euler[t]=Point3(eu[0],eu[1],eu[2]);
            Euler[t] *= 180.0f/pi;

            eu[1] *= -1;
            EulerToQuat(eu,Quat[t],EULERTYPE_YXZ);
        }
        
        for( int t=0; t<FrameCount; ++t )
        {    
            _ftprintf( fLog, _T("%sLoc[%d]=(X=%f,Y=%f,Z=%f)\n"), node->GetName(), t, Loc[t].x, Loc[t].y, Loc[t].z );
        }
        
        for( int t=0; t<FrameCount; ++t )
        {    
            _ftprintf( fLog, _T("%sQuat[%d]=(W=%f,X=%f,Y=%f,Z=%f)\n"), node->GetName(), t, Quat[t].w, Quat[t].x, Quat[t].y, Quat[t].z ); 
        }
        
        for( int t=0; t<FrameCount; ++t )
        {    
            _ftprintf( fLog, _T("%sEuler[%d]=(X=%f,Y=%f,Z=%f)\n"), node->GetName(), t, Euler[t].x, Euler[t].y, Euler[t].z ); 
        }
    }
}
Exemplo n.º 4
0
//=================================================================
// Methods for DumpFrameRotationsTEP
//
int DumpFrameRotationsTEP::callback(INode *pnode)
{
	ASSERT_MBOX(!(pnode)->IsRootNode(), "Encountered a root node!");

	if (::FNodeMarkedToSkip(pnode))
		return TREE_CONTINUE;

	int iNode = ::GetIndexOfINode(pnode);

	TSTR strNodeName(pnode->GetName());

	// The model's root is a child of the real "scene root"
	INode *pnodeParent = pnode->GetParentNode();
	BOOL fNodeIsRoot = pnodeParent->IsRootNode( );

	// Get Node's "Local" Transformation Matrix
	Matrix3 mat3NodeTM		= pnode->GetNodeTM(m_tvToDump);
	Matrix3 mat3ParentTM	= pnodeParent->GetNodeTM(m_tvToDump);
	mat3NodeTM.NoScale();		// Clear these out because they apparently
	mat3ParentTM.NoScale();		// screw up the following calculation.
	Matrix3 mat3NodeLocalTM	= mat3NodeTM * Inverse(mat3ParentTM);
	Point3 rowTrans = mat3NodeLocalTM.GetTrans();

	// check to see if the parent bone was mirrored.  If so, mirror invert this bones position
	if (m_phec->m_rgmaxnode[iNode].imaxnodeParent >= 0 && m_phec->m_rgmaxnode[m_phec->m_rgmaxnode[iNode].imaxnodeParent].isMirrored)
	{
		rowTrans = rowTrans * -1.0f;
	}

	// Get the rotation (via decomposition into "affine parts", then quaternion-to-Euler)
	// Apparently the order of rotations returned by QuatToEuler() is X, then Y, then Z.
	AffineParts affparts;
	float rgflXYZRotations[3];

	decomp_affine(mat3NodeLocalTM, &affparts);
	QuatToEuler(affparts.q, rgflXYZRotations);

	float xRot = rgflXYZRotations[0];		// in radians
	float yRot = rgflXYZRotations[1];		// in radians
	float zRot = rgflXYZRotations[2];		// in radians

	// Get rotations in the -2pi...2pi range
	xRot = ::FlReduceRotation(xRot);
	yRot = ::FlReduceRotation(yRot);
	zRot = ::FlReduceRotation(zRot);
	
	// Print rotations
	fprintf(m_pfile, "%3d %f %f %f %f %f %f\n", 
		// Node:%-15s Rotation (x,y,z)\n",
		iNode, rowTrans.x, rowTrans.y, rowTrans.z, xRot, yRot, zRot);

	return TREE_CONTINUE;
}
Exemplo n.º 5
0
// ===================================================================
void Listener::callbackUpdate()
{
    // need to first call the superclass update method (specifically, GroupNode)
    // which will update _globalMatrix
    DSPNode::callbackUpdate();

    // now, we can get the global position and orientation, and we can forward
    // it to SpatOSC

#ifdef WITH_SPATOSC
    if (spinApp::Instance().hasAudioRenderer)
    {
        osg::Vec3 myPos = _globalMatrix.getTrans();
        osg::Vec3 myRot = QuatToEuler(_globalMatrix.getRotate());

        spatOSCListener->setPosition(myPos.x(), myPos.y(), myPos.z());
        spatOSCListener->setOrientation(myRot.x(), myRot.y(), myRot.z());
    }
#endif
}
Exemplo n.º 6
0
void ConstraintsNode::applyConstrainedTranslation(osg::Vec3 v)
{
    osg::Vec3 localPos = this->getTranslation();
    osg::ref_ptr<ReferencedNode> hitNode;
    ReferencedNode *testNode;

    // with really big velocities (or small enclosures), and if the surface
    // doesn't damp the velocity, it's possible to get see an infinite recursion
    // occur. So, we keep a recursionCounter, and stop prevent this occurrence:
    if (++recursionCounter > 10) return;

    /*
    std::cout << std::endl << "checking for collisions" << std::endl;
    std::cout << "start =  " << localPos.x()<<","<<localPos.y()<<","<<localPos.z() << std::endl;
    std::cout << "v =      " << v.x()<<","<<v.y()<<","<<v.z() << std::endl;
    */

    osg::ref_ptr<ReferencedNode> targetNode = dynamic_cast<ReferencedNode*>(_target->s_thing);

    if (targetNode.valid())
    {
        // get current position (including offset from previous bounces)
        osg::Matrix thisMatrix = osg::computeLocalToWorld(this->currentNodePath);
        osg::Vec3 worldPos = thisMatrix.getTrans();

        // set up intersector:
        osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(worldPos, worldPos + v);
        osgUtil::IntersectionVisitor iv(intersector.get());

        // apply intersector:
        targetNode->accept(iv);

        if (intersector->containsIntersections())
        {
            osgUtil::LineSegmentIntersector::Intersections intersections;
            osgUtil::LineSegmentIntersector::Intersections::iterator itr;

            intersections = intersector->getIntersections();

            for (itr = intersections.begin(); itr != intersections.end(); ++itr)
            {
                //std::cout << "testing intersection with " << (*itr).nodePath[0]->getName() << std::endl;

                // first check if the hit is with our target (should be first in
                // the nodepath):

                testNode = dynamic_cast<ReferencedNode*>((*itr).nodePath[0]);
                if (testNode!=targetNode) continue;

                // The intersection has a nodepath that we have to walk down to
                // see which exact node has been hit. It's possible that there
                // are other SPIN nodes in the targetNode's subgraph that are
                // the real source of intersection:

                hitNode = 0;
                testNode = 0;
                for (unsigned int i=0; i<(*itr).nodePath.size(); i++)
                {
                    testNode = dynamic_cast<ReferencedNode*>((*itr).nodePath[i]);
                    if (testNode) hitNode = testNode;
                }

                if (hitNode.valid())
                {

                    //std::cout << id->s_name << " collision!!! with " << (*itr).drawable->getName() << "[" << (*itr).primitiveIndex << "] @ " << std::endl;
                    //std::cout << "localHitPoint:\t" << localHitPoint.x()<<","<<localHitPoint.y()<<","<<localHitPoint.z() << std::endl;
                    //std::cout << "localHitNormal:\t" << localHitNormal.x()<<","<<localHitNormal.y()<<","<<localHitNormal.z() << std::endl;


                    // For BOUNCE mode, we need to check if we've intersected
                    // with the same primitive again. This may occur since we
                    // do recursive translations after repositioning the node at
                    // the bounce point (and there may be numerical imprecision)
                    // If so, we skip this intersection:
                    if ((_mode==BOUNCE) &&
                            (lastDrawable.get()==(*itr).drawable.get()) &&
                            (lastPrimitiveIndex==(int)(*itr).primitiveIndex))
                    {
                        //std::cout << "... skipping" << std::endl;
                        continue;
                    }
                    else
                    {
                        lastDrawable=(*itr).drawable;
                        lastPrimitiveIndex=(*itr).primitiveIndex;
                    }


                    osg::Vec3 localHitPoint = (*itr).getWorldIntersectPoint();
                    osg::Vec3 localHitNormal = (*itr).getWorldIntersectNormal();
                    localHitNormal.normalize();


                    // current direction vector:
                    osg::Vec3 dirVec = v;
                    dirVec.normalize();

                    // Find the rotation between the direction vector and the
                    // surface normal at the hit point:
                    osg::Quat rot;
                    rot.makeRotate(dirVec, localHitNormal);
                    //std::cout << "rot =     " << rot.x()<<","<<rot.y()<<","<<rot.z()<<","<<rot.w() << " ... angle=" << acos(rot.w())*2 << ", indegrees=" << osg::RadiansToDegrees(acos(rot.w()))*2 << std::endl;

                    // the surface normal may be in the opposite direction
                    // from us. If so, we need to flip it:
                    if (acos(rot.w()) * 2 > osg::PI_2)
                    {
                        localHitNormal *= -1;
                        rot.makeRotate(dirVec, localHitNormal);
                        //std::cout << "flipped = " << rot.x()<<","<<rot.y()<<","<<rot.z()<<","<<rot.w() << " ... angle=" << acos(rot.w())*2 << ", indegrees=" << osg::RadiansToDegrees(acos(rot.w()))*2 << std::endl;
                    }


                    osg::Vec3 rotEulers = QuatToEuler(rot);
                    //std::cout << "newHitNormal:\t" << localHitNormal.x()<<","<<localHitNormal.y()<<","<<localHitNormal.z() << std::endl;


                    if ((_mode==COLLIDE)||(_mode==COLLIDE_THRU)||(_mode==STICK))
                    {
                        // Let the collisionPoint be just a bit before the real
                        // hitpoint (to avoid numerical imprecision placing the
                        // node behind the plane):
                        osg::Vec3 collisionPoint = localHitPoint - (localHitNormal * 0.01);

                        // place the node at the collision point
                        setTranslation(collisionPoint.x(), collisionPoint.y(), collisionPoint.z());

                        BROADCAST(this, "ssfff", "collide", hitNode->id->s_name, osg::RadiansToDegrees(rotEulers.x()), osg::RadiansToDegrees(rotEulers.y()), osg::RadiansToDegrees(rotEulers.z()));


                        if (_mode==COLLIDE)
                        {
                            // SLIDE along the hit plane with the left over energy:
                            // ie, project the remaining vector onto the surface we
                            // just intersected with.
                            //
                            // using:
                            //   cos(theta) = distToSurface / remainderVector length
                            //
                            double cosTheta = (dirVec * -localHitNormal) ; // dot product
                            osg::Vec3 remainderVector = (localPos + v) - localHitPoint;
                            double distToSurface = cosTheta * remainderVector.length();
                            osg::Vec3 slideVector = remainderVector + (localHitNormal * distToSurface);

                            // pseudo-recursively apply remainder of bounce:
                            applyConstrainedTranslation( slideVector );
                        }
                        else if (_mode==COLLIDE_THRU)
                        {
                            // allow the node to pass thru (ie, just apply the
                            // translation):
                            //setTranslation(v.x(), v.y(), v.z());
                            osg::Vec3 newPos = localPos + v;
                            setTranslation(newPos.x(), newPos.y(), newPos.z());
                        }

                        return;
                    }


                    else if (_mode==BOUNCE)
                    {
                        // bounce returns a translation mirrored about the hit
                        // normal to the surface



                        // the new direction vector is a rotated version
                        // of the original, about the localHitNormal:
                        //osg::Vec3 newDir = (rot * 2.0) * -dirVec;
                        osg::Vec3 newDir = (rot * (rot * -dirVec));
                        newDir.normalize();
                        //std::cout << "newDir = " << newDir.x()<<","<<newDir.y()<<","<<newDir.z() << std::endl;


                        // amount of distance still to travel after bounce:
                        double dist = v.length() - (localHitPoint-localPos).length();
                        //std::cout << "dist =   " << dist << std::endl;



                        // in node is translating (ie, changing position
                        // independently from it's orientatino), then we need to
                        // flip the velocity vector.
                        if (_velocityMode == GroupNode::TRANSLATE)
                        {
                            osg::Vec3 newVel = newDir * _velocity.length();
                            setVelocity(newVel.x(), newVel.y(), newVel.z());
                        }

                        // if the node is moving along it's orientation vector,
                        // we need to update the orientation of so that it
                        // points in 'bounced' direction
                        else if (_velocityMode == GroupNode::MOVE)
                        {
                            osg::Quat newQuat;
                            newQuat.makeRotate(osg::Vec3(0,1,0),  newDir);
                            osg::Vec3 newRot = Vec3inDegrees(QuatToEuler(newQuat));
                            //std::cout << "newrot = " << newRot.x()<<","<<newRot.y()<<","<<newRot.z() << std::endl;
                            setOrientation(newRot.x(), newRot.y(), newRot.z());

                        }

                        // the new position will be just a hair before hitpoint
                        // (because numerical imprecision may place the hitpoint
                        // slightly beyond the surface, and when we bounce the
                        // node, we don't want to  intersect with the same
                        // surface again)
                        double HAIR = 0.0000001;
                        setTranslation(localHitPoint.x()-dirVec.x()*HAIR, localHitPoint.y()-dirVec.y()*HAIR, localHitPoint.z()-dirVec.z()*HAIR);
                        //setTranslation(localHitPoint.x(), localHitPoint.y(), localHitPoint.z());

                        //std::cout << "rotEulers = " << osg::RadiansToDegrees(rotEulers.x())<<","<<osg::RadiansToDegrees(rotEulers.y())<<","<<osg::RadiansToDegrees(rotEulers.z()) << std::endl;
                        BROADCAST(this, "ssfff", "bounce", hitNode->id->s_name, osg::RadiansToDegrees(rotEulers.x()), osg::RadiansToDegrees(rotEulers.y()), osg::RadiansToDegrees(rotEulers.z()));

                        // pseudo-recursively apply remainder of bounce:
                        applyConstrainedTranslation(newDir*dist);

                        return;

                    }
                }
            }
        } //else std::cout << "no intersections" << std::endl;
    }


    // no intersections, so just do regular translation:
    osg::Vec3 newPos = localPos + v;
    setTranslation(newPos.x(), newPos.y(), newPos.z());
}
Exemplo n.º 7
0
// MilkShape 3D
void ExportMS3D_M2(Attachment *att, Model *m, const char *fn, bool init)
{
	wxFFileOutputStream f(wxString(fn, wxConvUTF8), wxT("w+b"));

	if (!f.IsOk()) {
		wxLogMessage(wxT("Error: Unable to open file '%s'. Could not export model."), fn);
		return;
	}
	LogExportData(wxT("MS3D"),m->modelname,wxString(fn, wxConvUTF8));
	unsigned short numVerts = 0;
	unsigned short numFaces = 0;
	unsigned short numGroups = 0;
	ModelData *verts = NULL;
	GroupData *groups = NULL;

	//we need the initial position anyway
	InitCommon(att, true, verts, groups, numVerts, numGroups, numFaces);
	//wxLogMessage(wxT("Num Verts: %i, Num Faces: %i, Num Groups: %i"), numVerts, numFaces, numGroups);
	//wxLogMessage(wxT("Vert[0] BoneID: %i, Group[0].m.name = %s"),verts[0].boneid, groups[0].m->name);
	wxLogMessage(wxT("Init Common Complete."));

	// Write the header
	ms3d_header_t header;
	strncpy(header.id, "MS3D000000", sizeof(header.id));
	header.version = 4;

	// Header
	f.Write(reinterpret_cast<char *>(&header), sizeof(ms3d_header_t));
	wxLogMessage(wxT("Header Data Written."));
	// Vertex Count
	f.Write(reinterpret_cast<char *>(&numVerts), sizeof(numVerts));
	//wxLogMessage(wxT("NumVerts: %i"),numVerts);
	
	// Write Vertex data?
	for (size_t i=0; i<numVerts; i++) {
		ms3d_vertex_t vert;
		vert.boneId = verts[i].boneid;
		vert.flags = 0; //SELECTED;
		vert.referenceCount = 0; // what the?
		vert.vertex[0] = verts[i].vertex.x;
		vert.vertex[1] = verts[i].vertex.y;
		vert.vertex[2] = verts[i].vertex.z;
		f.Write(reinterpret_cast<char *>(&vert), sizeof(ms3d_vertex_t));
	}
	wxLogMessage(wxT("Vertex Data Written."));
	// ---------------------------

	// Triangle Count
	f.Write(reinterpret_cast<char *>(&numFaces), sizeof(numFaces));
	//wxLogMessage(wxT("NumFaces: %i"),numFaces);

	// Write Triangle Data?
	for (size_t i=0; i<(unsigned int)numVerts; i+=3) {
		ms3d_triangle_t tri;
		tri.flags = 0; //SELECTED;
		tri.groupIndex = (unsigned char)verts[i].groupIndex;
		tri.smoothingGroup = 1; // 1 - 32

		for (ssize_t j=0; j<3; j++) {
			tri.vertexIndices[j] = (word)i+j;
			tri.s[j] = verts[i+j].tu;
			tri.t[j] = verts[i+j].tv;
			
			tri.vertexNormals[j][0] = verts[i+j].normal.x;
			tri.vertexNormals[j][1] = verts[i+j].normal.y;
			tri.vertexNormals[j][2] = verts[i+j].normal.z;
		}

		f.Write(reinterpret_cast<char *>(&tri), sizeof(ms3d_triangle_t));
	}
	wxLogMessage(wxT("Triangle Data Written."));
	// ---------------------------

	// Number of groups
	f.Write(reinterpret_cast<char *>(&numGroups), sizeof(numGroups));
	//wxLogMessage(wxT("NumGroups: %i"),numGroups);

	unsigned short indiceCount = 0;
	for (unsigned short i=0; i<(unsigned int)numGroups; i++) {
		wxString groupName(wxString::Format(wxT("Geoset_%i"), i));

		const char flags = 0; // SELECTED
		f.Write(&flags, sizeof(flags));

		char name[32];
		strncpy(name, groupName.mb_str(), sizeof(name));
		f.Write(name, sizeof(name));

		unsigned short faceCount = groups[i].p.indexCount / 3;
		f.Write(reinterpret_cast<char *>(&faceCount), sizeof(faceCount));
		
		for (ssize_t k=0; k<faceCount; k++) {
			//triIndices[k] = indiceCount;
			f.Write(reinterpret_cast<char *>(&indiceCount), sizeof(indiceCount));
			indiceCount++;
		}

		unsigned char gIndex = (char)i;
		f.Write(reinterpret_cast<char *>(&gIndex), sizeof(gIndex));
	}
	wxLogMessage(wxT("Group Data Written."));

	// Number of materials (pretty much identical to groups, each group has its own material)
	f.Write(reinterpret_cast<char *>(&numGroups), sizeof(numGroups));
	
	for (unsigned short i=0; i<(unsigned int)numGroups; i++) {
		wxString matName(wxString::Format(wxT("Material_%i"), i));

		ModelRenderPass p = groups[i].p;
		if (p.init(groups[i].m)) {
			ms3d_material_t mat;
			memset(mat.alphamap, '\0', sizeof(mat.alphamap));

			strncpy(mat.name, matName.mb_str(), sizeof(mat.name));
			mat.ambient[0] = 0.7f;
			mat.ambient[1] = 0.7f;
			mat.ambient[2] = 0.7f;
			mat.ambient[3] = 1.0f;
			mat.diffuse[0] = p.ocol.x;
			mat.diffuse[1] = p.ocol.y;
			mat.diffuse[2] = p.ocol.z;
			mat.diffuse[3] = p.ocol.w;
			mat.specular[0] = 0.0f;
			mat.specular[1] = 0.0f;
			mat.specular[2] = 0.0f;
			mat.specular[3] = 1.0f;
			mat.emissive[0] = p.ecol.x;
			mat.emissive[1] = p.ecol.y;
			mat.emissive[2] = p.ecol.z;
			mat.emissive[3] = p.ecol.w;
			mat.transparency = p.ocol.w;

			if (p.useEnvMap) {
				mat.shininess = 30.0f;
				mat.mode = 1;
			} else {
				mat.shininess = 0.0f;
				mat.mode = 0;
			}
/*
			unsigned int bindtex = 0;
			if (groups[i].m->specialTextures[p.tex]==-1) 
				bindtex = groups[i].m->textures[p.tex];
			else 
				bindtex = groups[i].m->replaceTextures[groups[i].m->specialTextures[p.tex]];
*/
			wxString texName = GetM2TextureName(m,p,i);
			texName << wxT(".tga");
			strncpy(mat.texture, texName.mb_str(), sizeof(mat.texture));

			f.Write(reinterpret_cast<char *>(&mat), sizeof(ms3d_material_t));

			wxString texFilename(fn, wxConvUTF8);
			texFilename = texFilename.BeforeLast(SLASH);
			texFilename += SLASH;
			texFilename += texName;
			wxLogMessage(wxT("Exporting Image: %s"),texFilename.c_str());
			SaveTexture(texFilename);
		}
	}
	wxLogMessage(wxT("Material Data Written."));

	if (init)
	{
		float fps = 1.0f;
		float fCurTime = 0.0f;
		int totalFrames = 0;

		f.Write(reinterpret_cast<char *>(&fps), sizeof(fps));
		f.Write(reinterpret_cast<char *>(&fCurTime), sizeof(fCurTime));
		f.Write(reinterpret_cast<char *>(&totalFrames), sizeof(totalFrames));
		
		// number of joints
		unsigned short numJoints = 0;

		f.Write(reinterpret_cast<char *>(&numJoints), sizeof(numJoints));
	}
	else
	{
		float fps = 25.0f;
		float fCurTime = 0.0f;
		int totalFrames = ceil((m->anims[m->anim].timeEnd - m->anims[m->anim].timeStart) / 1000.0f * fps);

		f.Write(reinterpret_cast<char *>(&fps), sizeof(fps));
		f.Write(reinterpret_cast<char *>(&fCurTime), sizeof(fCurTime));
		f.Write(reinterpret_cast<char *>(&totalFrames), sizeof(totalFrames));
		
		// number of joints
		unsigned short numJoints = (unsigned short)m->header.nBones;

		f.Write(reinterpret_cast<char *>(&numJoints), sizeof(numJoints));

		for (size_t i=0; i<numJoints; i++)
		{
			ms3d_joint_t joint;

			int parent = m->bones[i].parent;

			joint.flags = 0; // SELECTED
			memset(joint.name, '\0', sizeof(joint.name));
			snprintf(joint.name, sizeof(joint.name), "Bone_%i", i);
			memset(joint.parentName, '\0', sizeof(joint.parentName));
			if (parent != -1) snprintf(joint.parentName, sizeof(joint.parentName), "Bone_%i", parent);

			joint.rotation[0] = 0;
			joint.rotation[1] = 0;
			joint.rotation[2] = 0;

			Vec3D p = FixPivot(m, (int)i, m->bones[i].pivot);
			joint.position[0] = p.x;
			joint.position[1] = p.y;
			joint.position[2] = p.z;

			joint.numKeyFramesRot = (unsigned short)m->bones[i].rot.data[m->anim].size();
			joint.numKeyFramesTrans = (unsigned short)m->bones[i].trans.data[m->anim].size();

			f.Write(reinterpret_cast<char *>(&joint), sizeof(ms3d_joint_t));

			if (joint.numKeyFramesRot > 0)
			{
				ms3d_keyframe_rot_t *keyFramesRot = new ms3d_keyframe_rot_t[joint.numKeyFramesRot];
				for (size_t j=0; j<joint.numKeyFramesRot; j++)
				{
					keyFramesRot[j].time = m->bones[i].rot.times[m->anim][j] / 1000.0f;
					Vec3D euler = QuatToEuler(m->bones[i].rot.data[m->anim][j]);
					keyFramesRot[j].rotation[0] = euler.x;
					keyFramesRot[j].rotation[1] = euler.y;
					keyFramesRot[j].rotation[2] = euler.z;
				}

				f.Write(reinterpret_cast<char *>(keyFramesRot), sizeof(ms3d_keyframe_rot_t) * joint.numKeyFramesRot);
				wxDELETEA(keyFramesRot);
			}

			if (joint.numKeyFramesTrans > 0)
			{
				ms3d_keyframe_pos_t *keyFramesTrans = new ms3d_keyframe_pos_t[joint.numKeyFramesTrans];
				for (size_t j=0; j<joint.numKeyFramesTrans; j++)
				{
					keyFramesTrans[j].time = m->bones[i].trans.times[m->anim][j] / 1000.0f;
					keyFramesTrans[j].position[0] = m->bones[i].trans.data[m->anim][j].x;
					keyFramesTrans[j].position[1] = m->bones[i].trans.data[m->anim][j].y;
					keyFramesTrans[j].position[2] = m->bones[i].trans.data[m->anim][j].z;
				}

				f.Write(reinterpret_cast<char *>(keyFramesTrans), sizeof(ms3d_keyframe_pos_t) * joint.numKeyFramesTrans);
				wxDELETEA(keyFramesTrans);
			}
		}
	}
	f.Close();
	wxLogMessage(wxT("Finished Milkshape Export."));

	if (verts){
		//wxLogMessage("verts found. Deleting...");
		wxDELETEA(verts);
	}
	if (groups){
		//wxLogMessage("groups found. Deleting...");
		wxDELETEA(groups);
	}

	//wxLogMessage(wxT("Finished Milkshape Cleanup.\n"));
}
Exemplo n.º 8
0
   void BulletPhysicsEngine::update()
   {
      for (U32 i = 0; i < 1024; ++i)
      {
         BulletPhysicsObject* obj = &mPhysicsObjects[i];
         if ( obj->deleted )
            continue;

         if ( obj->shouldBeDeleted )
         {
            if ( obj->initialized )
            {
               mDynamicsWorld->removeRigidBody(obj->_rigidBody);
               obj->destroy();
            }

            obj->deleted = true;
            continue;
         }
      }

      for (U32 i = 0; i < 1024; ++i)
      {
         BulletPhysicsObject* obj = &mPhysicsObjects[i];
         if ( obj->deleted )
            continue;

         if ( !obj->initialized )
         {
            obj->initialize();
            mDynamicsWorld->addRigidBody(obj->_rigidBody);
         } else {
            // Pull updates from Physics thread.
            btMotionState* objMotion = obj->_rigidBody->getMotionState();
            if ( objMotion )
            {
               btTransform trans;
               objMotion->getWorldTransform(trans);

               F32 mat[16];
               trans.getOpenGLMatrix(mat);

               obj->mPosition.set(mat[12], mat[13], mat[14]);
               btQuaternion rot = trans.getRotation();
               obj->mRotation.set(QuatToEuler(rot.x(), rot.y(), rot.z(), rot.w()));
            }

            // Apply actions from Game thread.
            while ( obj->mPhysicsActions.size() > 0 )
            {
               Physics::PhysicsAction action = obj->mPhysicsActions.front();

               switch(action.actionType)
               {
                  case Physics::PhysicsAction::setPosition:
                     obj->mPosition = action.vector3Value;
                     obj->_rigidBody->setWorldTransform(btTransform(btQuaternion(0, 0, 0, 1),btVector3(action.vector3Value.x, action.vector3Value.y, action.vector3Value.z)));
                     obj->_rigidBody->activate();
                     break;

                  case Physics::PhysicsAction::setLinearVelocity:
                     obj->_rigidBody->setLinearVelocity(btVector3(action.vector3Value.x * 25.0f, action.vector3Value.y * 25.0f, action.vector3Value.z * 25.0f));
                     obj->_rigidBody->activate();
                     break;
               }

               obj->mPhysicsActions.pop_front();
            }
         }
      }
   }
Exemplo n.º 9
0
void RandKeysUtil::Apply()
	{
	BOOL timeMode   = iu->GetMajorMode()==TVMODE_EDITTIME;
	BOOL fcurveMode = iu->GetMajorMode()==TVMODE_EDITFCURVE;
	Interval iv = iu->GetTimeSelection();
	if (!doTime && !doVal) return;

	theHold.Begin();

	// Turn animation on
	SuspendAnimate();
	AnimateOn();

	for (int i=0; i<iu->GetNumTracks(); i++) {
		if ((timeMode||fcurveMode) && !iu->IsSelected(i)) continue;
		
		// Get Interfaces
		Animatable *anim   = iu->GetAnim(i);
		Animatable *client = iu->GetClient(i);
		int subNum         = iu->GetSubNum(i);
		Control *cont      = GetControlInterface(anim);
		IKeyControl *ikc   = GetKeyControlInterface(anim);
		IKey *key          = GetKeyPointer(anim->SuperClassID(),anim->ClassID());				
		if (!ikc || !cont || !key) continue;						
		if (fcurveMode && !anim->IsCurveSelected()) continue;

		// Get the param dim
		float min = negVal, max = posVal;
		ParamDimension *dim = client->GetParamDimension(subNum);
		if (dim) {
			min = dim->UnConvert(min);
			max = dim->UnConvert(max);
			}

		for (int j=0; j<ikc->GetNumKeys(); j++) {
			// Get the key data
			ikc->GetKey(j,key);
			
			// Check if it's selected
			if (timeMode && !iv.InInterval(key->time)) continue;
			if (!timeMode && !(key->flags&IKEY_SELECTED)) continue;			

			// Randomize time
			if (doTime) {
				key->time = (int)CompRand(
					float(key->time-negTime),
					float(key->time+posTime));
				ikc->SetKey(j,key);
				}
			}

		if (doTime) ikc->SortKeys();

		for (j=0; j<ikc->GetNumKeys(); j++) {
			// Get the key data
			ikc->GetKey(j,key);
			
			// Check if it's selected
			if (timeMode && !iv.InInterval(key->time)) continue;
			if (!timeMode && !(key->flags&IKEY_SELECTED)) continue;			

			// Randomize value
			if (doVal) {
				Point3 pt, ang;
				Point4 p4;
				float f;
				Quat q;
				ScaleValue s;				
				BOOL doX, doY, doZ, doW;
				doX = doY = doZ = doW = TRUE;
				if (!fcurveMode) {
					if (!(key->flags&IKEY_XSEL)) doX = FALSE;
					if (!(key->flags&IKEY_YSEL)) doY = FALSE;
					if (!(key->flags&IKEY_ZSEL)) doZ = FALSE;
					if (!(key->flags&IKEY_WSEL)) doW = FALSE;
					}

				switch (anim->SuperClassID()) {
					case CTRL_FLOAT_CLASS_ID:			
						cont->GetValue(key->time,&f,FOREVER);
						f = CompRand(f-min,f+max);
						cont->SetValue(key->time,&f);
						break;

					case CTRL_POSITION_CLASS_ID:
					case CTRL_POINT3_CLASS_ID:
						cont->GetValue(key->time,&pt,FOREVER);
						if (doX) pt.x = CompRand(pt.x-min,pt.x+max);
						if (doY) pt.y = CompRand(pt.y-min,pt.y+max);
						if (doZ) pt.z = CompRand(pt.z-min,pt.z+max);
						cont->SetValue(key->time,&pt);
						break;
					
					case CTRL_POINT4_CLASS_ID:
						cont->GetValue(key->time,&p4,FOREVER);
						if (doX) p4.x = CompRand(p4.x-min,p4.x+max);
						if (doY) p4.y = CompRand(p4.y-min,p4.y+max);
						if (doZ) p4.z = CompRand(p4.z-min,p4.z+max);
						if (doW) p4.w = CompRand(p4.w-min,p4.w+max);
						cont->SetValue(key->time,&p4);
						break;

					case CTRL_ROTATION_CLASS_ID:
						cont->GetValue(key->time,&q,FOREVER);
						QuatToEuler(q, ang);
						ang.x = CompRand(ang.x-min,ang.x+max);
						ang.y = CompRand(ang.y-min,ang.y+max);
						ang.z = CompRand(ang.z-min,ang.z+max);
						EulerToQuat(ang,q);
						cont->SetValue(key->time,&q);
						break;

					case CTRL_SCALE_CLASS_ID:
						cont->GetValue(key->time,&s,FOREVER);
						if (doX) s.s.x = CompRand(s.s.x-min,s.s.x+max);
						if (doY) s.s.y = CompRand(s.s.y-min,s.s.y+max);
						if (doZ) s.s.z = CompRand(s.s.z-min,s.s.z+max);
						cont->SetValue(key->time,&s);
						break;
					}
				}
			}

		
		}

	ResumeAnimate();

	theHold.Accept(GetString(IDS_RB_RANDOMIZEKEYS));
	ip->RedrawViews(ip->GetTime());
	}