daedar
26-05-2007 15:14:26
Ok it was finally pretty easy, so here's the patch that adds spherical joints to NxOgre (and another method on RevoluteJoints usefull for ragdolls). I'll confirm that it works well (or not) but it seems to be ok:
Index: include/NxOgreJointSet1.h
===================================================================
--- include/NxOgreJointSet1.h (revision 23)
+++ include/NxOgreJointSet1.h (working copy)
@@ -31,18 +31,36 @@
public:
RevoluteJoint(Actor*,Actor*, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
+ RevoluteJoint(Actor*,Actor*, const Ogre::Vector3 &axis1, const Ogre::Vector3 &axis2, const Ogre::Vector3 &anchor1, const Ogre::Vector3 &anchor2);
RevoluteJoint(Actor*, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
~RevoluteJoint();
protected:
void __createJoint(const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
+ void __createJoint(const Ogre::Vector3 &axis1, const Ogre::Vector3 &axis2, const Ogre::Vector3 &anchor1, const Ogre::Vector3 &anchor2);
NxRevoluteJoint* mRevoluteJoint;
NxRevoluteJointDesc mDescription;
};
+ class NxExport SphericalJoint : public Joint {
+
+ public:
+
+ SphericalJoint(Actor*,Actor*, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
+ ~SphericalJoint();
+
+ protected:
+
+ void __createJoint(const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
+
+ NxSphericalJoint* mSphericalJoint;
+ NxSphericalJointDesc mDescription;
+
+ };
+
};
#endif
Index: include/NxOgrePrerequisites.h
===================================================================
--- include/NxOgrePrerequisites.h (revision 23)
+++ include/NxOgrePrerequisites.h (working copy)
@@ -70,6 +70,7 @@
struct RayCastHit;
class RemoteDebuggerConnection;
class RevoluteJoint;
+ class SphericalJoint;
class Scene;
class Shape;
class ShapeDescription;
Index: include/NxOgreScene.h
===================================================================
--- include/NxOgreScene.h (revision 23)
+++ include/NxOgreScene.h (working copy)
@@ -111,6 +111,9 @@
RevoluteJoint* createRevoluteJoint(Actor*, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
RevoluteJoint* createRevoluteJoint(Actor*, Actor*, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
+ RevoluteJoint* createRevoluteJoint(Actor*, Actor*, const Ogre::Vector3 &axis1, const Ogre::Vector3 &axis2, const Ogre::Vector3 &anchor1, const Ogre::Vector3 &anchor2);
+
+ SphericalJoint* createSphericalJoint(Actor*, Actor*, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor);
void releaseJoint(Joint*);
void releaseJoint(const NxString&);
Index: source/NxOgreJointSet1.cpp
===================================================================
--- source/NxOgreJointSet1.cpp (revision 23)
+++ source/NxOgreJointSet1.cpp (working copy)
@@ -35,6 +35,13 @@
////////////////////////////////////////////////////////////////////////////////////
+RevoluteJoint::RevoluteJoint(Actor *a ,Actor *b, const Ogre::Vector3 &axis1, const Ogre::Vector3 &axis2, const Ogre::Vector3 &anchor1, const Ogre::Vector3 &anchor2) : Joint(a,b){
+ mDescription.setToDefault();
+ __createJoint(axis1, axis2, anchor1, anchor2);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
RevoluteJoint::RevoluteJoint(Actor *a, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor) : Joint (a) {
mDescription.setToDefault();
__createJoint(axis,anchor);
@@ -42,6 +49,13 @@
////////////////////////////////////////////////////////////////////////////////////
+SphericalJoint::SphericalJoint(Actor *a, Actor *b, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor) : Joint (a,b) {
+ mDescription.setToDefault();
+ __createJoint(axis,anchor);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
void RevoluteJoint::__createJoint(const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor) {
mDescription.actor[0] = mActorA->getNxActor();
@@ -61,10 +75,82 @@
////////////////////////////////////////////////////////////////////////////////////
+void RevoluteJoint::__createJoint(const Ogre::Vector3 &axis1, const Ogre::Vector3 &axis2, const Ogre::Vector3 &anchor1, const Ogre::Vector3 &anchor2) {
+
+ mDescription.actor[0] = mActorA->getNxActor();
+
+ if (mActorB)
+ mDescription.actor[1] = mActorB->getNxActor();
+ else
+ mDescription.actor[1] = NULL;
+
+ mDescription.localAnchor[0]=toNxVec3(anchor1);
+ mDescription.localAnchor[1]=toNxVec3(anchor2);
+ mDescription.localAxis[0] =toNxVec3(axis1);
+ mDescription.localAxis[1] =toNxVec3(axis2);
+ mDescription.projectionMode = NX_JPM_POINT_MINDIST;
+ mDescription.userData = this;
+
+ mNxJoint = mScene->getNxScene()->createJoint(mDescription);
+ mRevoluteJoint = static_cast<NxRevoluteJoint*>(mNxJoint);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+void SphericalJoint::__createJoint(const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor) {
+
+ mDescription.actor[0] = mActorA->getNxActor();
+
+ if (mActorB)
+ mDescription.actor[1] = mActorB->getNxActor();
+ else
+ mDescription.actor[1] = NULL;
+
+ mDescription.setGlobalAnchor(toNxVec3(anchor));
+ mDescription.setGlobalAxis(toNxVec3(axis));
+
+ mDescription.flags |= NX_SJF_TWIST_LIMIT_ENABLED;
+ mDescription.twistLimit.low.value = -(NxReal)0.025*NxPi;
+ mDescription.twistLimit.low.hardness = 0.5;
+ mDescription.twistLimit.low.restitution = 0.5;
+ mDescription.twistLimit.high.value = (NxReal)0.025*NxPi;
+ mDescription.twistLimit.high.hardness = 0.5;
+ mDescription.twistLimit.high.restitution = 0.5;
+
+ mDescription.flags |= NX_SJF_SWING_LIMIT_ENABLED;
+ mDescription.swingLimit.value = (NxReal)0.25*NxPi;
+ mDescription.swingLimit.hardness = 0.5;
+ mDescription.swingLimit.restitution = 0.5;
+
+ mDescription.flags |= NX_SJF_TWIST_SPRING_ENABLED;
+ mDescription.twistSpring.spring = 0.5;
+ mDescription.twistSpring.damper = 1;
+
+ mDescription.flags |= NX_SJF_SWING_SPRING_ENABLED;
+ mDescription.swingSpring.spring = 0.5;
+ mDescription.swingSpring.damper = 1;
+
+ mDescription.projectionDistance = (NxReal)0.15;
+ mDescription.projectionMode = NX_JPM_POINT_MINDIST;
+
+ mDescription.userData = this;
+
+ mNxJoint = mScene->getNxScene()->createJoint(mDescription);
+ mSphericalJoint = static_cast<NxSphericalJoint*>(mNxJoint);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
RevoluteJoint::~RevoluteJoint() {
mScene->getNxScene()->releaseJoint(*mNxJoint);
}
////////////////////////////////////////////////////////////////////////////////////
+SphericalJoint::~SphericalJoint() {
+ mScene->getNxScene()->releaseJoint(*mNxJoint);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
}; //End of NxOgre namespace.
Index: source/NxOgreScene.cpp
===================================================================
--- source/NxOgreScene.cpp (revision 23)
+++ source/NxOgreScene.cpp (working copy)
@@ -287,6 +287,16 @@
///////////////////////////////////////////////////////////////////////
+SphericalJoint* Scene::createSphericalJoint(Actor* a, Actor* b, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor) {
+ SphericalJoint* j = new SphericalJoint(a,b,axis,anchor);
+ NxString jid = NxCreateID(mJoints.count(), "Joint");
+ mJoints.insert(jid, j);
+ mJoints.lock(jid, true);
+ return j;
+}
+
+///////////////////////////////////////////////////////////////////////
+
RevoluteJoint* Scene::createRevoluteJoint(Actor* a, const Ogre::Vector3 &axis, const Ogre::Vector3 &anchor) {
RevoluteJoint* j = new RevoluteJoint(a,axis,anchor);
NxString jid = NxCreateID(mJoints.count(), "Joint");
@@ -316,6 +326,25 @@
///////////////////////////////////////////////////////////////////////
+RevoluteJoint* Scene::createRevoluteJoint(Actor* a, Actor* b, const Ogre::Vector3 &axis1, const Ogre::Vector3 &axis2, const Ogre::Vector3 &anchor1, const Ogre::Vector3 &anchor2) {
+ RevoluteJoint* j = new RevoluteJoint(a,b,axis1,axis2,anchor1,anchor2);
+ NxString jid;
+
+ if (j->getName() == "") {
+ jid = NxCreateID(mJoints.count(), "Joint");
+ j->setName(jid);
+ }
+ else {
+ jid = j->getName();
+ }
+
+ mJoints.insert(jid, j);
+ mJoints.lock(jid, true);
+ return j;
+}
+
+///////////////////////////////////////////////////////////////////////
+
void Scene::releaseJoint(Joint* j) {
NxString name = j->getName();
Joint* joint = mJoints.get(name);
daedar
27-05-2007 13:20:56
I'm looking forward to your code, and with your permission putting it in 0.9?
Ok no problem, here is the first try. Now I need to read values from an XML file and bind it with skeletons and I think it should be ok (I'll change the comments from French to English too):
NxRagdoll.h:
#ifndef _NX_RAGDOLL_
#define _NX_RAGDOLL_
#include "../../Physics/PhysicEngine.h"
/** Classe de gestion du ragdoll */
class NxRagdoll{
public:
/** Nouveau ragdoll à partir d'un fichier XML*/
NxRagdoll(NxOgre::Scene* scene, string filename, Vector3 position, float scale);
protected:
/** Scene physique */
NxOgre::Scene* nxScene;
/** Nombre d'acteurs*/
unsigned int nb_actor;
/** Position et taille initiale*/
Vector3 iPosition;
float iScale;
/** Liste des acteurs physiques*/
NxOgre::Actor* head;
NxOgre::Actor* torso;
NxOgre::Actor* pelvis;
NxOgre::Actor* leftUpperArm;
NxOgre::Actor* rightUpperArm;
NxOgre::Actor* leftForeArm;
NxOgre::Actor* rightForeArm;
NxOgre::Actor* leftHand;
NxOgre::Actor* rightHand;
NxOgre::Actor* leftThigh;
NxOgre::Actor* rightThigh;
NxOgre::Actor* leftCalf;
NxOgre::Actor* rightCalf;
NxOgre::Actor* leftFoot;
NxOgre::Actor* rightFoot;
/** Liste des joints sphériques */
NxOgre::SphericalJoint* neck;
NxOgre::SphericalJoint* leftShoulder;
NxOgre::SphericalJoint* rightShoulder;
NxOgre::SphericalJoint* spine;
NxOgre::SphericalJoint* leftHip;
NxOgre::SphericalJoint* rightHip;
/** Liste des joints revolute*/
NxOgre::RevoluteJoint* leftElbow;
NxOgre::RevoluteJoint* rightElbow;
NxOgre::RevoluteJoint* leftWrist;
NxOgre::RevoluteJoint* rightWrist;
NxOgre::RevoluteJoint* leftKnee;
NxOgre::RevoluteJoint* rightKnee;
NxOgre::RevoluteJoint* leftAnkle;
NxOgre::RevoluteJoint* rightAnkle;
private:
/** Creation d'une sphere*/
NxOgre::Actor* CreateSphere(Vector3 pos, float radius);
/** Creation d'une capsule*/
NxOgre::Actor* CreateCapsule(Vector3 pos, float height, float radius);
/** Creation d'une boite*/
NxOgre::Actor* CreateBox(Vector3 pos, Vector3 size);
/** Creation d'un revolute joint*/
NxOgre::RevoluteJoint* CreateRevoluteJoint(NxOgre::Actor* actor1, NxOgre::Actor* actor2, Vector3 anchor, Vector3 axis);
NxOgre::RevoluteJoint* CreateRevoluteJoint(NxOgre::Actor* actor1, NxOgre::Actor* actor2, Vector3 anchor1, Vector3 anchor2, Vector3 axis1, Vector3 axis2);
/** Creation d'un spherical joint*/
NxOgre::SphericalJoint* CreateBodySphericalJoint(NxOgre::Actor* actor1, NxOgre::Actor* actor2, Vector3 anchor, Vector3 axis);
};
#endif
NxRagdoll.cpp:
#include "NxRagdoll.h"
/** Nouveau ragdoll */
NxRagdoll::NxRagdoll(NxOgre::Scene* scene, string filename, Vector3 position, float scale){
LogManager::getSingleton().logMessage("Creating ragdoll");
/** Position et taille initiale */
iScale = scale;
iPosition = position;
/** Nombre d'acteurs */
nb_actor = 0;
/** Scene NxOgre */
nxScene = scene;
/** Positions */
Vector3 headPosition(0,10,0);
float headSize = 0.5f;
Vector3 torsoPosition(0,8.6f,0);
float torsoSize = 0.9f;
Vector3 pelvisPosition(0,7,0);
float pelvisSize = 0.7f;
float upperArmLength = 1, upperArmRadius = 0.4f;
Vector3 lupperArmPosition(1.55f,9.4f,0);
Vector3 rupperArmPosition(-1.55f,9.4f,0);
float foreArmLength = 1, foreArmRadius = 0.3f;
Vector3 lforeArmPosition(3.55f,9.4f,0);
Vector3 rforeArmPosition(-3.55f,9.4f,0);
Vector3 handSize(0.3f,0.3f,0.1);
Vector3 lhandPosition(4.85f,9.4f,0);
Vector3 rhandPosition(-4.85f,9.4f,0);
float thighLength = 1.5f, thighRadius = 0.5f;
Vector3 lthighPosition(0.6f,5,0);
Vector3 rthighPosition(-0.6f,5,0);
float calfLength = 1.5f, calfRadius = 0.35f;
Vector3 lcalfPosition(0.6f,2,0);
Vector3 rcalfPosition(-0.6f,2,0);
Vector3 footSize(0.4f,0.2f,0.75f);
Vector3 lfootPosition(0.6f,0.4f,0.2f);
Vector3 rfootPosition(-0.6f,0.4f,0.2f);
/** Quaternion utiles */
Quaternion qRotLeft, qRotRight, qRotAround;
qRotLeft.FromAngleAxis(Degree(90), Vector3(0,0,1));
qRotRight.FromAngleAxis(Degree(-90), Vector3(0,0,1));
qRotAround.FromAngleAxis(Degree(180), Vector3(0,0,1));
/** Creation des acteurs spheriques */
head = CreateSphere(headPosition, headSize);
torso = CreateSphere(torsoPosition, torsoSize);
pelvis = CreateSphere(pelvisPosition, pelvisSize);
/** Bras gauche */
leftUpperArm = CreateCapsule(lupperArmPosition, upperArmLength, upperArmRadius);
leftUpperArm->setGlobalOrientation(qRotRight);
leftForeArm = CreateCapsule(lforeArmPosition, foreArmLength, foreArmRadius);
leftForeArm->setGlobalOrientation(qRotRight);
leftHand = CreateBox(lhandPosition, handSize);
leftHand->setGlobalOrientation(qRotRight);
/** Bras droit */
rightUpperArm = CreateCapsule(rupperArmPosition, upperArmLength, upperArmRadius);
rightUpperArm->setGlobalOrientation(qRotLeft);
rightForeArm = CreateCapsule(rforeArmPosition, foreArmLength, foreArmRadius);
rightForeArm->setGlobalOrientation(qRotLeft);
rightHand = CreateBox(rhandPosition, handSize);
rightHand->setGlobalOrientation(qRotLeft);
/** Jambe gauche */
leftThigh = CreateCapsule(lthighPosition, thighLength, thighRadius);
leftThigh->setGlobalOrientation(qRotAround);
leftCalf = CreateCapsule(lcalfPosition, calfLength, calfRadius);
leftCalf->setGlobalOrientation(qRotAround);
leftFoot = CreateBox(lfootPosition, footSize);
leftFoot->setGlobalOrientation(qRotAround);
/** Jambe droite */
rightThigh = CreateCapsule(rthighPosition, thighLength, thighRadius);
rightThigh->setGlobalOrientation(qRotAround);
rightCalf = CreateCapsule(rcalfPosition, calfLength, calfRadius);
rightCalf->setGlobalOrientation(qRotAround);
rightFoot = CreateBox(rfootPosition, footSize);
rightFoot->setGlobalOrientation(qRotAround);
/**Creation des joints spheriques*/
neck = CreateBodySphericalJoint(head,torso,headPosition-Vector3(0,headSize,0),Vector3(0,1,0));
leftShoulder = CreateBodySphericalJoint(leftUpperArm,torso,lupperArmPosition-Vector3(upperArmLength,0,0),Vector3(1,0,0));
rightShoulder = CreateBodySphericalJoint(rightUpperArm,torso,rupperArmPosition+Vector3(upperArmLength,0,0),Vector3(-1,0,0));
spine = CreateBodySphericalJoint(torso,pelvis,torsoPosition-Vector3(0,torsoSize,0),Vector3(0,-1,0));
leftHip = CreateBodySphericalJoint(leftThigh,pelvis,lthighPosition+Vector3(0,thighLength,0),Vector3(0,-1,0));
rightHip = CreateBodySphericalJoint(rightThigh,pelvis,rthighPosition+Vector3(0,thighLength,0),Vector3(0,-1,0));
/**Creation des joints revolute*/
leftElbow = CreateRevoluteJoint(leftForeArm,leftUpperArm,lforeArmPosition-Vector3(foreArmLength,0,0),Vector3(0,0,-1));
rightElbow = CreateRevoluteJoint(rightForeArm,rightUpperArm,rforeArmPosition+Vector3(foreArmLength,0,0),Vector3(0,0,-1));
leftWrist = CreateRevoluteJoint(leftHand,leftForeArm,lforeArmPosition+Vector3(foreArmLength,0,0),Vector3(0,1,0));
rightWrist = CreateRevoluteJoint(rightHand,rightForeArm,rforeArmPosition-Vector3(foreArmLength,0,0),Vector3(0,1,0));
leftKnee = CreateRevoluteJoint(leftCalf,leftThigh,lcalfPosition+Vector3(0,calfLength,0),Vector3(1,0,0));
rightKnee = CreateRevoluteJoint(rightCalf,rightThigh,rcalfPosition+Vector3(0,calfLength,0),Vector3(-1,0,0));
leftAnkle = CreateRevoluteJoint(leftFoot,leftCalf,lcalfPosition-Vector3(0,calfLength,0),Vector3(1,0,0));
rightAnkle = CreateRevoluteJoint(rightFoot,rightCalf,rcalfPosition-Vector3(0,calfLength,0),Vector3(-1,0,0));
PhysicEngine::getSingleton()->all_physics_shapes.push_back(pelvis);
}
/** Creation d'une sphere*/
NxOgre::Actor* NxRagdoll::CreateSphere(Vector3 pos, float radius){
radius *= iScale;
pos *= iScale;
NxOgre::Actor *actor = nxScene->createBody("ellipsoid.mesh",new NxOgre::SphereShape(radius), pos+iPosition, "mass: 0.1");
((NxOgre::Body*)actor)->getNode()->setScale(radius, radius, radius);
return actor;
}
/** Creation d'une capsule*/
NxOgre::Actor* NxRagdoll::CreateCapsule(Vector3 pos, float height, float radius){
height *= iScale;
radius *= iScale;
pos *= iScale;
NxOgre::Actor *actor = nxScene->createBody("ellipsoid.mesh",new NxOgre::CapsuleShape(radius, height), pos+iPosition, "mass: 0.1");
((NxOgre::Body*)actor)->getNode()->setScale(radius, height, radius);
return actor;
}
/** Creation d'une boite*/
NxOgre::Actor* NxRagdoll::CreateBox(Vector3 pos, Vector3 size){
pos *= iScale;
size *= iScale;
NxOgre::Actor *actor = nxScene->createBody("box.mesh",new NxOgre::CubeShape(size.x, size.y, size.z), pos+iPosition, "mass: 0.1");
((NxOgre::Body*)actor)->getNode()->setScale(size);
return actor;
}
/** Creation d'un revolute joint*/
NxOgre::RevoluteJoint* NxRagdoll::CreateRevoluteJoint(NxOgre::Actor* actor1, NxOgre::Actor* actor2, Vector3 anchor, Vector3 axis){
anchor *= iScale;
return nxScene->createRevoluteJoint(actor1, actor2, axis, anchor+iPosition);
}
/** Creation d'un revolute joint*/
NxOgre::RevoluteJoint* NxRagdoll::CreateRevoluteJoint(NxOgre::Actor* actor1, NxOgre::Actor* actor2, Vector3 anchor1, Vector3 anchor2, Vector3 axis1, Vector3 axis2){
anchor1 *= iScale;
anchor2 *= iScale;
return nxScene->createRevoluteJoint(actor1, actor2, axis1, axis2, anchor1+iPosition, anchor2+iPosition);
}
/** Creation d'un spherical joint*/
NxOgre::SphericalJoint* NxRagdoll::CreateBodySphericalJoint(NxOgre::Actor* actor1, NxOgre::Actor* actor2, Vector3 anchor, Vector3 axis){
anchor *= iScale;
return nxScene->createSphericalJoint(actor1, actor2, axis, anchor+iPosition);
}