Slider doesnt work!

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Slider doesnt work!

Postby PJani » Wed Sep 16, 2009 6:46 pm

I have a litle problem...the slider joint doesnt work. I dont know why. in 1.53 have worked. :roll:

I connect two bodies but there is no connection. When I drag one of the bodies around and there is no slightest change to another body. And i keep getting crashes. :shock:
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Slider doesnt work!

Postby Stucuk » Wed Sep 16, 2009 10:01 pm

People like Julio need more to go on than a vague description. Stuff like a demo, source code, etc. Something that they can test.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: Slider doesnt work!

Postby Dave Gravel » Thu Sep 17, 2009 12:00 am

It's surely a problem about your pins setup.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 801
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: Slider doesnt work!

Postby kallaspriit » Thu Sep 17, 2009 3:39 am

Other people are using it without complaints so it's most likely a problem with your setup. Show the code you're using to create the joint.
kallaspriit
 
Posts: 216
Joined: Sun Aug 14, 2005 6:31 pm

Re: Slider doesnt work!

Postby PJani » Thu Sep 17, 2009 9:18 am

Right that im asking if any one else have the same problem with slider...

Ok i will copy some of the code from OgreNewt and slider creation.

//part of cpp
Code: Select all
Slider::Slider( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin ) : Joint()
{
    m_world = world;

    if (parent)
    {
        m_joint = NewtonConstraintCreateSlider( world->getNewtonWorld(), &pos.x, &pin.x,
                                                child->getNewtonBody(), parent->getNewtonBody() );
    }
    else
    {
        m_joint = NewtonConstraintCreateSlider( world->getNewtonWorld(), &pos.x, &pin.x,
                                                child->getNewtonBody(), NULL );
    }

    NewtonJointSetUserData( m_joint, this );
    NewtonJointSetDestructor( m_joint, destructor );
    NewtonSliderSetUserCallback( m_joint, newtonCallback );

    m_callback = NULL;
}

Slider::~Slider()
{
}

Ogre::Vector3 Slider::getJointForce() const
{
    Ogre::Vector3 ret;

    NewtonSliderGetJointForce( m_joint, &ret.x );

    return ret;
}

unsigned _CDECL Slider::newtonCallback( const NewtonJoint* slider, NewtonHingeSliderUpdateDesc* desc )
{
    Slider* me = (Slider*)NewtonJointGetUserData( slider );

    me->m_desc = desc;
    me->m_retval = 0;

    if (me->m_callback)
        (*me->m_callback)( me );

    me->m_desc = NULL;

    return me->m_retval;
}


/////// CALLBACK FUNCTIONS ///////
void Slider::setCallbackAccel( Ogre::Real accel )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_accel = (float)accel;
    }
}

void Slider::setCallbackFrictionMin( Ogre::Real min )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_minFriction = (float)min;
    }
}

void Slider::setCallbackFrictionMax( Ogre::Real max )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_maxFriction = (float)max;
    }
}

Ogre::Real Slider::getCallbackTimestep() const
{
    if (m_desc)
        return (Ogre::Real)m_desc->m_timestep;
    else
        return 0.0;
}

Ogre::Real Slider::calculateStopAccel( Ogre::Real dist ) const
{
    if (m_desc)
        return (Ogre::Real)NewtonSliderCalculateStopAccel( m_joint, m_desc, (float)dist );
    else
        return 0.0;
}

//part of header...
Code: Select all
class _OgreNewtExport Slider : public Joint
{
 
public:

    //! custom slider callback function.
    /*!
         use the setCallback() function to assign your custom function to the joint.
     */
    typedef void(*SliderCallback)( Slider* me );

    //! constructor
    /*!
        \param world pointer to the OgreNewt::World
        \param child pointer to the child rigid body.
        \param parent pointer to the parent rigid body. pass NULL to make the world itself the parent (aka a rigid joint)
        \param pin direction of the joint pin in global space
    */
    Slider( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin );

    //! destructor.
    ~Slider();

    //! get position of child along the pin
    Ogre::Real getJointPosit() const { return (Ogre::Real)NewtonSliderGetJointPosit( m_joint ); }

    //! get rotational velocity along the pin
    Ogre::Real getJointVeloc() const { return (Ogre::Real)NewtonSliderGetJointVeloc( m_joint ); }

    //! get force on the joint.
    Ogre::Vector3 getJointForce() const;

    //! set a custom callback for controlling this joint.
    /*!
        Joint callbacks allow you to make complex joint behavior such as limits or motors.  just make a custom static function that
        accepts a pointer to a OgreNewt::BasicJoints::Slider as the single parameter.  this function will be called automatically every
        time you upate the World.
    */
    void setCallback( SliderCallback callback ) { m_callback = callback; }

    ////////// CALLBACK COMMANDS ///////////
    // the following commands are only valid from inside a hinge callback function

    //! set the acceleration along the pin.
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    void setCallbackAccel( Ogre::Real accel );

    //! set minimum friction for the joint
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    void setCallbackFrictionMin( Ogre::Real min );

    //! set maximum friction for the joint.
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    void setCallbackFrictionMax( Ogre::Real max );

    //! get current physics timestep.
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    Ogre::Real getCallbackTimestep() const;

    //! calculate the acceleration neccesary to stop the joint at the specified distance.
    /*!
        For implementing joint limits.
        This command is only valid when used inside a custom Slider callback.
    */
    Ogre::Real calculateStopAccel( Ogre::Real dist ) const;

protected:

    //! newton callback.  used internally.
    static unsigned _CDECL newtonCallback( const NewtonJoint* slider, NewtonHingeSliderUpdateDesc* desc );

    SliderCallback m_callback;
    NewtonHingeSliderUpdateDesc* m_desc;

    unsigned m_retval;
};


My box creation and slider...
Code: Select all
    std::vector<SceneNodeClass::TSN> tmplt;
    SceneNodeClass::TSN t = {"cali/cali_box_1m.mesh", Ogre::Vector3(0,0,0), Ogre::Quaternion::IDENTITY, Ogre::Vector3(1,1,1)};
    tmplt.push_back(t);

   //my system for creating objects...works with no problems
    SceneNodeManager::getSingleton().CreateMesh("box1",tmplt,Ogre::Vector3(0,10,0),Ogre::Quaternion::IDENTITY,Ogre::Vector3(1,1,1));
    PhysicObject* po1 = ObjectManager::getSingleton().createBody("box1",false,Ogre::Vector3::ZERO,800,false);

    SceneNodeManager::getSingleton().CreateMesh("box2",tmplt,Ogre::Vector3(0,10,2),Ogre::Quaternion::IDENTITY,Ogre::Vector3(1,1,1));
    PhysicObject* po2 = ObjectManager::getSingleton().createBody("box2",false,Ogre::Vector3::ZERO,800,false);

   //creation of slider...
    OgreNewt::BasicJoints::Slider* sl = new OgreNewt::BasicJoints::Slider(m_World,po1->getOgreNewtBody(),po2->getOgreNewtBody(),Ogre::Vector3(0,10,1),Ogre::Vector3::UNIT_Y);

 //Ogre::Vector3::UNIT_Y should be Vector3(0.0,1.0,0.0)
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Slider doesnt work!

Postby Julio Jerez » Thu Sep 17, 2009 11:00 am

The Part I do not undertant is why the OgreNewt do not reuses the joints that are already made instead of insisting in re writing each class each time.
Making the Joint library takes time, is very error prone, and forces a long integration prossess each time there is a new update.

It not a wonder, that I see people having way of a lot of problem than I thought they should have, it is a poor design.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Slider doesnt work!

Postby PJani » Thu Sep 17, 2009 2:22 pm

I am not the author of OgreNewt, im trying what is the cause of my troubles. :)
In the same way was Ogre wrapper created for 1.53, i allocated a slider wrapper with "new" and it worked. And when it was no need for the slider i just deleted it with delete and two bodies were simply disconnected.

Now there is no connection, and i keep getting assertion crashes... Im trying to figure out what is causing this problem and mejbe changing wrapper if is something wrong with it.
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Slider doesnt work!

Postby Julio Jerez » Thu Sep 17, 2009 2:48 pm

I mean that the code seems to suggest that each joint implementation is a native Low level Newton joint.
If instead you make the Joint to have an existing base customJoint class, then you can just write just wrapper function calls to redirect to the joint in teh joint library.
Thsi si a Text Book case of Resusing object in object Oreiented programming. what I see is not OOP.
For what I can see the design of those OgerNewt classes follow very poor CPP programming practices.
which is a surprice to me since this is Ogre, which is supposed to be the “Industry standard for object oriented graphics class design”
Basically that method forces each object to repeat the same code over and over which si error prone, further more it is still using the very all joint of 1.3

The good news is that if done, that joint call can be refectored, so that it can re use all of the Joint at once, rather than implementing one at a time.
If you post the header file of the base Joint class I can post back the header for a class such the you can have all of the joints provided by Newton at the same time.
Plus I can write samples like Slider or Hinge so that oreNewt code base maintainer make the changes and add all other CustomJoints.

If I am correct Integration of a new Joint into Ogre Newt should be a matter of writing and simple Header and few lines of code.
and any programer should be able to do, rather than having to spends day or weeks reverse ingenoering what the Custom joint library is doing.

It is not wonder why people find it so hard, or perhaps I am the one how see seems differently. But that is not the way I program.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Slider doesnt work!

Postby PJani » Thu Sep 17, 2009 3:25 pm

Base Joint header...all joint are allready implemented in OgreNewt, except corkscrew i didnt see anywere.

Basicly i have to write 3 lines of code if i want joint to work...


Code: Select all
/*
    OgreNewt Library

    Ogre implementation of Newton Game Dynamics SDK

    OgreNewt basically has no license, you may use any or all of the library however you desire... I hope it can help you in any way.

        by Walaber
        some changes by melven

*/
#ifndef _INCLUDE_OGRENEWT_JOINT
#define _INCLUDE_OGRENEWT_JOINT


#include "OgreNewt_Prerequisites.h"


// OgreNewt namespace.  all functions and classes use this namespace.
namespace OgreNewt
{


//! base class for all joints.
/*!
    this class is inherited by all other specific joint types.
*/
class _OgreNewtExport Joint
{
public:

    //! constructor
    Joint();

    //! destructor
    virtual ~Joint();

    //! returns collision state
    /*!
        The collision state determines whether collision should be calculated between the parent and child bodies of the joint.
        \return integer value. 1 = collision on, 0 = collision off.
    */
    int getCollisionState() const { return NewtonJointGetCollisionState( m_joint ); }

    //! sets the collision state
    /*!
        The collision state determines whether collision should be calculated between the parent and child bodies of the joint.
        \param state integer value. 1 = collision on, 0 = collision off.
    */
    void setCollisionState( int state ) const { NewtonJointSetCollisionState( m_joint, state ); }


    //! get joint stiffness
    /*!
        Joint stiffness adjusts how much "play" the joint can have.  high stiffness = very small play, but more likely to become unstable.
        \return float representing joint stiffness in range [0,1]
    */
    Ogre::Real getStiffness() const { return (Ogre::Real)NewtonJointGetStiffness( m_joint ); }

    //! set joint stiffness
    /*!
        Joint stiffness adjusts how much "play" the joint can have.  high stiffness = very small play, but more likely to become unstable.
        \param stiffness float representing joint stiffness in range [0,1]
    */
    void setStiffness( Ogre::Real stiffness ) const { NewtonJointSetStiffness( m_joint, stiffness ); }

    const OgreNewt::World* getWorld(void) const {return m_world;}
    //! set user data for this joint
    /*!
        user data can be used to connect this class to other user classes through the use of this general pointer.
    */
#ifndef OGRENEWT_NO_OGRE_ANY
    void setUserData( const Ogre::Any& data ) { m_userdata = data; }
#else
    void setUserData( void* data ) { m_userdata = data; }
#endif

    //! get user data for this joint
    /*!
        user data can be used to connect this class to other user classes through the use of this general pointer.
    */
#ifndef OGRENEWT_NO_OGRE_ANY
    const Ogre::Any& getUserData() const { return m_userdata; }
#else
    void* getUserData() const { return m_userdata; }
#endif


protected:

    NewtonJoint* m_joint;
    const OgreNewt::World* m_world;


#ifndef OGRENEWT_NO_OGRE_ANY
    Ogre::Any                       m_userdata;
#else
    void*                           m_userdata;
#endif

    static void _CDECL destructor( const NewtonJoint* me );

};






//! CustomJoint
/*!
    this class represents a basic class for creating user-defined joints.  this class must be inherited to create discreet joints.
*/
class _OgreNewtExport CustomJoint : public Joint
{

public:

    //! constructor
    CustomJoint( unsigned int maxDOF, const Body* body0, const Body* body1 );

    //! destructor
    virtual ~CustomJoint();

    //! must be over-written for a functioning joint.
    virtual void submitConstraint( Ogre::Real timeStep, int threadIndex ) = 0;

    //! can be overwritten, empty as default
    virtual void feedbackCollector( Ogre::Real timeSte, int threadIndex ) {}

    //! find the local orientation and position of the joint with regards to the 2 bodies in the joint.
    void pinAndDirToLocal( const Ogre::Vector3& pinpt, const Ogre::Vector3& pindir, Ogre::Quaternion& localOrient0, Ogre::Vector3& localPos0, Ogre::Quaternion& localOrient1, Ogre::Vector3& localPos1 ) const;

    //! find the global orientation and position of the joint with regards to the a body in the joint.
    void localToGlobal( const Ogre::Quaternion& localOrient, const Ogre::Vector3& localPos, Ogre::Quaternion& globalOrient, Ogre::Vector3& globalPos, int bodyIndex = 0 ) const;

    //! find the local orientation and position of the joint with regards to the a body in the joint.
    void globalToLocal( const Ogre::Quaternion& localOrient, const Ogre::Vector3& localPos, Ogre::Quaternion& globalOrient, Ogre::Vector3& globalPos, int bodyIndex = 0 ) const;

    //! add a linear row to the constraint.
    void addLinearRow( const Ogre::Vector3& pt0, const Ogre::Vector3& pt1, const Ogre::Vector3& dir ) const;

    //! add an angular row to the constraint.
    void addAngularRow( Ogre::Radian relativeAngleError, const Ogre::Vector3& dir ) const;

    //! set the general jacobian rows directly.
    void addGeneralRow( const Ogre::Vector3& linear0, const Ogre::Vector3& angular0, const Ogre::Vector3& linear1, const Ogre::Vector3& angular1 ) const;

    //! set row minimum friction
    void setRowMinimumFriction( Ogre::Real friction ) const;

    //! set row maximum friction
    void setRowMaximumFriction( Ogre::Real friction ) const;

    //! set row acceleration
    void setRowAcceleration( Ogre::Real accel ) const;

    //! set row stiffness
    void setRowStiffness( Ogre::Real stiffness ) const;

    //! apply a spring to this row, allowing for joints with spring behaviour in 1 or more DoF's
    /*!
        \param springK float spring constant.
        \param springD float natural rest state distance of the spring.
    */
    void setRowSpringDamper( Ogre::Real springK, Ogre::Real springD ) const;

    //! retrieve the force acting on the current row.
    Ogre::Real getRowForce( int row ) const { return NewtonUserJointGetRowForce( m_joint, row ); }

    //! pin vector to arbitrary quaternion utility function.
    Ogre::Quaternion grammSchmidt( const Ogre::Vector3& pin ) const;

protected:

    unsigned int m_maxDOF;

    const OgreNewt::Body* m_body0;
    const OgreNewt::Body* m_body1;

private:
    //! newton callback.  used internally.
    static void _CDECL newtonSubmitConstraint( const NewtonJoint* me, float timeStep, int threadIndex );
    static void _CDECL newtonGetInfo( const NewtonJoint* me, NewtonJointRecord* info );
    static void _CDECL newtonFeedbackCollector( const NewtonJoint* me, float timeStep, int threadIndex );

};



}   // end NAMESPACE OgreNewt

#endif
// _INCLUDE_OGRENEWT_JOINT




//base joint cpp

Code: Select all
#include "OgreNewt_Joint.h"
#include "OgreNewt_Body.h"
#include "OgreNewt_World.h"


namespace OgreNewt
{

   
Joint::Joint()
{
    // nothing here
}

Joint::~Joint()
{

    if(m_joint)
    {
        if (NewtonJointGetUserData(m_joint))
        {
            NewtonJointSetDestructor( m_joint, NULL );
            NewtonDestroyJoint( m_world->getNewtonWorld(), m_joint );
        }
    }

}


void _CDECL Joint::destructor( const NewtonJoint* me )
{
    Joint* jnt;

    jnt = (Joint*)NewtonJointGetUserData( me );

    NewtonJointSetDestructor( me, NULL );
    NewtonJointSetUserData( me, NULL );

    delete jnt;
}




CustomJoint::CustomJoint( unsigned int maxDOF, const Body* body0, const Body* body1 ) : Joint()
{
    m_maxDOF = maxDOF;

    m_body0 = body0;
    m_body1 = body1;

    m_world = m_body0->getWorld();

    if (body1)
        m_joint = NewtonConstraintCreateUserJoint( m_world->getNewtonWorld(), m_maxDOF,
                                                    CustomJoint::newtonSubmitConstraint, CustomJoint::newtonGetInfo,
                                                    m_body0->getNewtonBody(), m_body1->getNewtonBody() );
    else
        m_joint = NewtonConstraintCreateUserJoint( m_world->getNewtonWorld(), m_maxDOF,
                                                    CustomJoint::newtonSubmitConstraint, CustomJoint::newtonGetInfo,
                                                    m_body0->getNewtonBody(), NULL );

    NewtonJointSetUserData (m_joint, this);
    NewtonJointSetDestructor (m_joint, destructor);
    NewtonUserJointSetFeedbackCollectorCallback( m_joint, CustomJoint::newtonFeedbackCollector );

}

CustomJoint::~CustomJoint()
{
}


void CustomJoint::pinAndDirToLocal( const Ogre::Vector3& pinpt, const Ogre::Vector3& pindir,
                                   Ogre::Quaternion& localOrient0, Ogre::Vector3& localPos0, Ogre::Quaternion& localOrient1, Ogre::Vector3& localPos1 ) const
{
    localOrient0 = localOrient1 =  Ogre::Quaternion::IDENTITY;
    localPos0 = localPos1 = Ogre::Vector3::ZERO;

    Ogre::Quaternion bodyOrient0 = Ogre::Quaternion::IDENTITY;
    Ogre::Quaternion bodyOrient1 = Ogre::Quaternion::IDENTITY;
    Ogre::Vector3 bodyPos0 = Ogre::Vector3::ZERO;
    Ogre::Vector3 bodyPos1 = Ogre::Vector3::ZERO;

    Ogre::Quaternion pinOrient = grammSchmidt(pindir);

    m_body0->getPositionOrientation( bodyPos0, bodyOrient0 );

    if (m_body1)
        m_body1->getPositionOrientation( bodyPos1, bodyOrient1 );

    localPos0 = bodyOrient0.Inverse() * (pinpt - bodyPos0);
    localOrient0 = pinOrient * bodyOrient0.Inverse();

    localPos1 = bodyOrient1.Inverse() * (pinpt - bodyPos1);
    localOrient1 = pinOrient * bodyOrient1.Inverse();

}


void CustomJoint::localToGlobal( const Ogre::Quaternion& localOrient, const Ogre::Vector3& localPos, Ogre::Quaternion& globalOrient, Ogre::Vector3& globalPos, int bodyIndex ) const
{
    globalOrient = Ogre::Quaternion::IDENTITY;
    globalPos= Ogre::Vector3::ZERO;

    const Body* bdy = NULL;
    if (bodyIndex == 0)
        bdy = m_body0;
    else if (m_body1)
        bdy = m_body1;

    Ogre::Quaternion bodyOrient = Ogre::Quaternion::IDENTITY;
    Ogre::Vector3 bodyPos = Ogre::Vector3::ZERO;

    if (bdy)
        bdy->getPositionOrientation( bodyPos, bodyOrient );

    globalPos = (bodyOrient * localPos) + bodyPos;
    globalOrient = bodyOrient * localOrient;
}


void CustomJoint::globalToLocal( const Ogre::Quaternion& globalOrient, const Ogre::Vector3& globalPos, Ogre::Quaternion& localOrient, Ogre::Vector3& localPos, int bodyIndex ) const
{
    localOrient = Ogre::Quaternion::IDENTITY;
    localPos= Ogre::Vector3::ZERO;

    const Body* bdy = NULL;
    if (bodyIndex == 0)
        bdy = m_body0;
    else if (m_body1)
        bdy = m_body1;

    Ogre::Quaternion bodyOrient = Ogre::Quaternion::IDENTITY;
    Ogre::Vector3 bodyPos = Ogre::Vector3::ZERO;

    if (bdy)
        bdy->getPositionOrientation( bodyPos, bodyOrient );

    Ogre::Quaternion bodyOrientInv = bodyOrient.Inverse();

    localOrient = bodyOrientInv * globalOrient;
    localPos = bodyOrientInv * (globalPos - bodyPos);
}



void CustomJoint::addLinearRow( const Ogre::Vector3& pt0, const Ogre::Vector3& pt1, const Ogre::Vector3& dir ) const
{
    NewtonUserJointAddLinearRow( m_joint, &pt0.x, &pt1.x, &dir.x );
}

void CustomJoint::addAngularRow( Ogre::Radian relativeAngleError, const Ogre::Vector3& dir ) const
{
    NewtonUserJointAddAngularRow( m_joint, relativeAngleError.valueRadians(), &dir.x );
}

void CustomJoint::addGeneralRow(const Ogre::Vector3& linear0, const Ogre::Vector3& angular0, const Ogre::Vector3& linear1, const Ogre::Vector3& angular1) const
{
    float jacobian0[6], jacobian1[6];

    jacobian0[0] = linear0.x;
    jacobian0[1] = linear0.y;
    jacobian0[2] = linear0.z;
    jacobian0[3] = angular0.x;
    jacobian0[4] = angular0.y;
    jacobian0[5] = angular0.z;

    jacobian1[0] = linear1.x;
    jacobian1[1] = linear1.y;
    jacobian1[2] = linear1.z;
    jacobian1[3] = angular1.x;
    jacobian1[4] = angular1.y;
    jacobian1[5] = angular1.z;

    NewtonUserJointAddGeneralRow( m_joint, jacobian0, jacobian1 );
}


void CustomJoint::setRowMinimumFriction( Ogre::Real friction ) const
{
    NewtonUserJointSetRowMinimumFriction( m_joint, friction );
}


void CustomJoint::setRowMaximumFriction( Ogre::Real friction ) const
{
    NewtonUserJointSetRowMaximumFriction( m_joint, friction );
}


void CustomJoint::setRowAcceleration( Ogre::Real accel ) const
{
    NewtonUserJointSetRowAcceleration( m_joint, accel );
}

void CustomJoint::setRowStiffness( Ogre::Real stiffness ) const
{
    NewtonUserJointSetRowStiffness( m_joint, stiffness );
}

void CustomJoint::setRowSpringDamper(Ogre::Real springK, Ogre::Real springD) const
{
    NewtonUserJointSetRowSpringDamperAcceleration( m_joint, springK, springD );
}


void _CDECL CustomJoint::newtonSubmitConstraint( const NewtonJoint* me, float timeStep, int threadIndex )
{
    CustomJoint* j = (CustomJoint*)NewtonJointGetUserData( me );

    j->submitConstraint( (Ogre::Real)timeStep, threadIndex );
}

void _CDECL CustomJoint::newtonFeedbackCollector( const NewtonJoint* me, float timeStep, int threadIndex )
{
    CustomJoint* j = (CustomJoint*)NewtonJointGetUserData( me );

    j->feedbackCollector( (Ogre::Real)timeStep, threadIndex );
}


void _CDECL CustomJoint::newtonGetInfo(const NewtonJoint *me, NewtonJointRecord *info)
{
    CustomJoint* j = (CustomJoint*)NewtonJointGetUserData( me );
}


Ogre::Quaternion CustomJoint::grammSchmidt( const Ogre::Vector3& pin ) const
{
    Ogre::Vector3 front, up, right;
    front = pin;

    front.normalise();
    if (Ogre::Math::Abs( front.z ) > 0.577f)
        right = front.crossProduct( Ogre::Vector3(-front.y, front.z, 0.0f) );
    else
        right = front.crossProduct( Ogre::Vector3(-front.y, front.x, 0.0f) );
    right.normalise();
    up = right.crossProduct( front );

    Ogre::Matrix3 ret;
    ret.FromAxes( front, up, right );

    Ogre::Quaternion quat;
    quat.FromRotationMatrix( ret );

    return quat;
}




}   // end NAMESPACE OgreNewt




//Basic Joints header
Code: Select all
/*
    OgreNewt Library

    Ogre implementation of Newton Game Dynamics SDK

    OgreNewt basically has no license, you may use any or all of the library however you desire... I hope it can help you in any way.

        by Walaber
        some changes by melven

*/
#ifndef _INCLUDE_OGRENEWT_BASICJOINTS
#define _INCLUDE_OGRENEWT_BASICJOINTS

#include "OgreNewt_Prerequisites.h"
#include "OgreNewt_Joint.h"

// OgreNewt namespace.  all functions and classes use this namespace.
namespace OgreNewt
{


//! Namespace for ready-made joints
namespace BasicJoints
{

//! Ball and Socket joint.
/*!
    simple ball and socket joint, with limits.
*/
class _OgreNewtExport BallAndSocket : public Joint
{
 
public:
    //! custom ballandsocket callback function.
    /*!
         use the setCallback() function to assign your custom function to the joint.
     */
    typedef void(*BallAndSocketCallback)( BallAndSocket* me, Ogre::Real timestep );

    //! constructor
    /*!
        \param world pointer to the OgreNewt::World
        \param child pointer to the child rigid body.
        \param parent pointer to the parent rigid body. pass NULL to make the world itself the parent (aka a rigid joint)
        \param pos position of the joint in global space
    */
    BallAndSocket( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos );
   
    //! destructor.
    ~BallAndSocket();

    //! retrieve the current joint angle
    Ogre::Vector3 getJointAngle() const;

    //! retrieve the current joint omega
    Ogre::Vector3 getJointOmega() const;

    //! retrieve the current joint force.
    /*!
        This can be used to find the "stress" on the joint.  you can do special effects like break the joint if the force exceedes some value, etc.
    */
    Ogre::Vector3 getJointForce() const;

    //! set limits for the joints rotation
    /*!
        \param pin pin direction in global space
        \param maxCone max angle for "swing" (in radians)
        \param maxTwist max angle for "twist"  (in radians)
    */
    void setLimits( const Ogre::Vector3& pin, Ogre::Radian maxCone, Ogre::Radian maxTwist ) const { NewtonBallSetConeLimits( m_joint, &pin.x, (float)maxCone.valueRadians(), (float)maxTwist.valueRadians() ); }

    //! set callback function
    void setCallback(BallAndSocketCallback *callback) {m_callback = callback;}


protected:
    BallAndSocketCallback *m_callback;

private:
    static void _CDECL newtonBallCallback(const NewtonJoint* ball, float timestep);
   
};


//! hinge joint.
/*!
    simple hinge joint.  implement motors/limits through a callback.
*/
class _OgreNewtExport Hinge : public Joint
{
 
public:

    //! custom hinge callback function.
    /*!
         use the setCallback() function to assign your custom function to the joint.
     */
    typedef void(*HingeCallback)( Hinge* me );

    //! constructor
    /*!
        \param world pointer to the OgreNewt::World
        \param child pointer to the child rigid body.
        \param parent pointer to the parent rigid body. pass NULL to make the world itself the parent (aka a rigid joint)
        \param pin direction of the joint pin in global space
    */
    Hinge( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin );

    //! destructor
    ~Hinge();

    //! retrieve the angle around the pin.
    Ogre::Radian getJointAngle() const { return Ogre::Radian(NewtonHingeGetJointAngle( m_joint )); }

    //! retrieve the rotational velocity around the pin.
    Ogre::Real getJointOmega() const { return (Ogre::Real)NewtonHingeGetJointOmega( m_joint ); }

    //! get the force on the joint.
    Ogre::Vector3 getJointForce() const;

    //! set a custom callback for controlling this joint.
    /*!
        Joint callbacks allow you to make complex joint behavior such as limits or motors.  just make a custom static function that
        accepts a pointer to a OgreNewt::BasicJoints::Hinge as the single parameter.  this function will be called automatically every
        time you upate the World.
    */
    void setCallback( HingeCallback callback ) { m_callback = callback; }


    ////////// CALLBACK COMMANDS ///////////
    // the following commands are only valid from inside a hinge callback function

    //! set acceleration around the joint pin
    /*!
        This command is only valid when used inside a custom Hinge callback.
    */
    void setCallbackAccel( Ogre::Real accel );

    //! set minimum joint friction.
    /*!
        This command is only valid when used inside a custom Hinge callback.
    */
    void setCallbackFrictionMin( Ogre::Real min );

    //! set maximum joint friction
    /*!
        This command is only valid when used inside a custom Hinge callback.
    */
    void setCallbackFrictionMax( Ogre::Real max );

    //! get the current physics timestep.
    /*!
        This command is only valid when used inside a custom Hinge callback.
    */
    Ogre::Real getCallbackTimestep() const;

    //! calculate the acceleration neccesary to stop the joint at the specified angle.
    /*!
        For implementing joint limits.
        This command is only valid when used inside a custom Hinge callback.
    */
    Ogre::Real calculateStopAlpha( Ogre::Radian angle ) const;

protected:

    //! newton callback, used internally.
    static unsigned _CDECL newtonCallback( const NewtonJoint* hinge, NewtonHingeSliderUpdateDesc* desc );

    HingeCallback m_callback;
    NewtonHingeSliderUpdateDesc* m_desc;

    unsigned m_retval;
};


//! slider joint.
/*!
    simple slider joint.  implement motors/limits through a callback.
*/
class _OgreNewtExport Slider : public Joint
{
 
public:

    //! custom slider callback function.
    /*!
         use the setCallback() function to assign your custom function to the joint.
     */
    typedef void(*SliderCallback)( Slider* me );

    //! constructor
    /*!
        \param world pointer to the OgreNewt::World
        \param child pointer to the child rigid body.
        \param parent pointer to the parent rigid body. pass NULL to make the world itself the parent (aka a rigid joint)
        \param pin direction of the joint pin in global space
    */
    Slider( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin );

    //! destructor.
    ~Slider();

    //! get position of child along the pin
    Ogre::Real getJointPosit() const { return (Ogre::Real)NewtonSliderGetJointPosit( m_joint ); }

    //! get rotational velocity along the pin
    Ogre::Real getJointVeloc() const { return (Ogre::Real)NewtonSliderGetJointVeloc( m_joint ); }

    //! get force on the joint.
    Ogre::Vector3 getJointForce() const;

    //! set a custom callback for controlling this joint.
    /*!
        Joint callbacks allow you to make complex joint behavior such as limits or motors.  just make a custom static function that
        accepts a pointer to a OgreNewt::BasicJoints::Slider as the single parameter.  this function will be called automatically every
        time you upate the World.
    */
    void setCallback( SliderCallback callback ) { m_callback = callback; }

    ////////// CALLBACK COMMANDS ///////////
    // the following commands are only valid from inside a hinge callback function

    //! set the acceleration along the pin.
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    void setCallbackAccel( Ogre::Real accel );

    //! set minimum friction for the joint
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    void setCallbackFrictionMin( Ogre::Real min );

    //! set maximum friction for the joint.
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    void setCallbackFrictionMax( Ogre::Real max );

    //! get current physics timestep.
    /*!
        This command is only valid when used inside a custom Slider callback.
    */
    Ogre::Real getCallbackTimestep() const;

    //! calculate the acceleration neccesary to stop the joint at the specified distance.
    /*!
        For implementing joint limits.
        This command is only valid when used inside a custom Slider callback.
    */
    Ogre::Real calculateStopAccel( Ogre::Real dist ) const;

protected:

    //! newton callback.  used internally.
    static unsigned _CDECL newtonCallback( const NewtonJoint* slider, NewtonHingeSliderUpdateDesc* desc );

    SliderCallback m_callback;
    NewtonHingeSliderUpdateDesc* m_desc;

    unsigned m_retval;
};



//! this class represents a Universal joint.
/*!
    simple universal joint.  implement motors/limits through a callback.
*/
class _OgreNewtExport Universal : public Joint
{
 
public:
   
    //! custom universal callback function.
    /*!
         use the setCallback() function to assign your custom function to the joint.
     */
    typedef void(*UniversalCallback)( Universal* me );

    //! constructor
    /*!
        \param world pointer to the OgreNewt::World
        \param child pointer to the child rigid body.
        \param parent pointer to the parent rigid body. pass NULL to make the world itself the parent (aka a rigid joint)
        \param pos position of the joint in global space
        \param pin0 direction of the first axis of rotation in global space
        \param pin1 direction of the second axis of rotation in global space
    */
    Universal( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin0, const Ogre::Vector3& pin1 );

    //! destructor
    ~Universal();

    //! get the angle around pin0.
    Ogre::Radian getJointAngle0() const { return Ogre::Radian(NewtonUniversalGetJointAngle0( m_joint )); }

    //! get the angle around pin1.
    Ogre::Radian getJointAngle1() const { return Ogre::Radian(NewtonUniversalGetJointAngle1( m_joint )); }

    //! get the rotational velocity around pin0.
    Ogre::Real getJointOmega0() const { return (Ogre::Real)NewtonUniversalGetJointOmega0( m_joint ); }

    //! get the rotational velocity around pin1.
    Ogre::Real getJointOmega1() const { return (Ogre::Real)NewtonUniversalGetJointOmega1( m_joint ); }

    //! get the force on the joint.
    Ogre::Vector3 getJointForce() const;

    //! set a custom callback for controlling this joint.
    /*!
        Joint callbacks allow you to make complex joint behavior such as limits or motors.  just make a custom static function that
        accepts a pointer to a OgreNewt::BasicJoints::Universal as the single parameter.  this function will be called automatically every
        time you upate the World.
    */
    void setCallback( UniversalCallback callback ) { m_callback = callback; }

    ////////// CALLBACK COMMANDS ///////////
    // the following commands are only valid from inside a hinge callback function

    //! set the acceleration around a particular pin.
    /*
        this function can only be called from within a custom callback.
        \param accel desired acceleration
        \param axis which pin to use (0 or 1)
    */
    void setCallbackAccel( Ogre::Real accel, unsigned axis );

    //! set the minimum friction around a particular pin
    /*
        this function can only be called from within a custom callback.
        \param min minimum friction
        \param axis which pin to use (0 or 1)
    */
    void setCallbackFrictionMin( Ogre::Real min, unsigned axis );

    //! set the maximum friction around a particular pin.
    /*
        this function can only be called from within a custom callback.
        \param max maximum friction
        \param axis which pin to use (0 or 1)
    */
    void setCallbackFrictionMax( Ogre::Real max, unsigned axis );

    //! get the current phsics timestep.
    /*
        this function can only be called from within a custom callback.
    */
    Ogre::Real getCallbackTimestep() const;

    //! calculate the acceleration neccesary to stop the joint at the specified angle on pin 0.
    /*!
        For implementing joint limits.
        This command is only valid when used inside a custom  callback.
    */
    Ogre::Real calculateStopAlpha0( Ogre::Real angle ) const;

    //! calculate the acceleration neccesary to stop the joint at the specified angle on pin 1.
    /*!
        For implementing joint limits.
        This command is only valid when used inside a custom  callback.
    */
    Ogre::Real calculateStopAlpha1( Ogre::Real angle ) const;

protected:
   
    //! newton callback.  used internally.
    static unsigned _CDECL newtonCallback( const NewtonJoint* universal, NewtonHingeSliderUpdateDesc* desc );

    UniversalCallback m_callback;
    NewtonHingeSliderUpdateDesc* m_desc;

    unsigned m_retval;
};



//! UpVector joint.
/*!
    simple upvector joint.  upvectors remove all rotation except for a single pin.  useful for character controllers, etc.
*/
class _OgreNewtExport UpVector : public Joint
{
 
public:
    //! constructor
    /*
        \param world pointer to the OgreNewt::World.
        \param body pointer to the body to apply the upvector to.
        \param pin direction of the upvector in global space.
    */
    UpVector( const World* world, const Body* body, const Ogre::Vector3& pin );

    //! destructor
    ~UpVector();

    //! set the pin direction.
    /*
        by calling this function in realtime, you can effectively "animate" the pin.
    */
    void setPin( const Ogre::Vector3& pin ) const { NewtonUpVectorSetPin( m_joint, &pin.x ); }

    //! get the current pin direction.
    Ogre::Vector3 getPin() const;
};


}   // end NAMESPACE BasicJoints


//! namespace for pre-built custom joints
namespace PrebuiltCustomJoints
{

    //! Custom2DJoint class
    /*!
        This class represents a joint that limits movement to a plane, and rotation only around the normal of that
        plane.  This can be used to create simple 2D simulations.  it also supports limits and acceleration for spinning.
        This joint has been used in a few projects, but is not 100% fully-tested.
    */
    class _OgreNewtExport Custom2DJoint : public OgreNewt::CustomJoint
    {
    public:
        //! constructor
        Custom2DJoint( const OgreNewt::Body* body, const Ogre::Vector3& pin );

        //! destructor
        ~Custom2DJoint() {}

        //! overloaded function that applies the actual constraint.
        void submitConstraint( Ogre::Real timeStep, int threadIndex );

        //! get the current angle of the joint.
        Ogre::Radian getAngle() const { return mAngle; }

        //! set rotational limits for the joint.
        void setLimits( Ogre::Degree min, Ogre::Degree max ) { mMin = min, mMax = max; }
       
        //! sets whether to enable limits or not for the joint.
        void setLimitsOn( bool onoff ) { mLimitsOn = onoff; }

        //! returns whether limits are turned on or off for the joint.
        bool getLimitsOn() const { return mLimitsOn; }

        //! adds rotational acceleration to the joint (like a motor)
        void addAccel( Ogre::Real accel ) { mAccel = accel; }

        //! resets the joint angle to 0.  this simply sets the internal variable to zero.
        //! you might want to call this for example after resetting a body.
        void resetAngle() { mAngle = Ogre::Radian(0.0f); }

        //! get the pin.
        Ogre::Vector3 getPin() { return mPin; }

    private:
        Ogre::Vector3 mPin;
        Ogre::Quaternion mLocalOrient0, mLocalOrient1;
        Ogre::Vector3 mLocalPos0, mLocalPos1;

        Ogre::Radian mAngle;

        Ogre::Radian mMin;
        Ogre::Radian mMax;

        bool mLimitsOn;

        Ogre::Real mAccel;
    };

    //! CustomFixedJoint
    /*!
        This joint implements a fully fixed joint, which removes all DOF, creating a completely fixed connection between bodies.
        This is probably the most expensive kind of joint, and should only be used when really needed.
    */
    class _OgreNewtExport CustomRigidJoint : public OgreNewt::CustomJoint
    {
    public:
        CustomRigidJoint( OgreNewt::Body* child, OgreNewt::Body* parent, Ogre::Vector3 dir, Ogre::Vector3 pos);
        ~CustomRigidJoint();

        void submitConstraint( Ogre::Real timeStep, int threadIndex );

    private:
        Ogre::Vector3 mLocalPos0;
        Ogre::Vector3 mLocalPos1;

        Ogre::Quaternion mLocalOrient0;
        Ogre::Quaternion mLocalOrient1;
    };

    //! CustomDryRollingFriction
    /*!
     * This joint is usefully to simulate the rolling friction of a rolling ball over a flat surface.
     * Normally this is not important for non spherical objects, but for games like poll, pinball, bolling, golf
     * or any other where the movement of balls is the main objective the rolling friction is a real big problem.
    */
    /* // not tested yet
    class _OgreNewtExport CustomDryRollingFriction : public OgreNewt::CustomJoint
    {
        public:
            CustomDryRollingFriction( OgreNewt::Body* child, Ogre::Real radius, Ogre::Real rollingFrictionCoefficient );
            ~CustomDryRollingFriction();

            void submitConstraint( Ogre::Real timestep, int threadIndex );

        private:
            Ogre::Real mFrictionCoefficient;
            Ogre::Real mFrictionTorque;
            OgreNewt::Body* mChild;
    };
    */

}   // end NAMESPACE PrebuiltCustomJoints


}   // end NAMESPACE OgreNewt

#endif
// _INCLUDE_OGRENEWT_BASICJOINTS



//basic joints header
Code: Select all
#include "OgreNewt_BasicJoints.h"
#include "OgreNewt_World.h"
#include "OgreNewt_Body.h"

#ifdef __APPLE__
#   include <Ogre/OgreLogManager.h>
#   include <Ogre/OgreStringConverter.h>
#else
#   include <OgreLogManager.h>
#   include <OgreStringConverter.h>
#endif

namespace OgreNewt
{

namespace BasicJoints
{

BallAndSocket::BallAndSocket( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos ) : Joint()
{
    m_world = world;

    if (parent)
        m_joint = NewtonConstraintCreateBall( world->getNewtonWorld(), &pos.x, child->getNewtonBody(), parent->getNewtonBody() );
    else
        m_joint = NewtonConstraintCreateBall( world->getNewtonWorld(), &pos.x, child->getNewtonBody(), NULL );


    // all constructors inherited from Joint MUST call these 2 functions to make the joint function properly.
    NewtonJointSetUserData( m_joint, this );
    NewtonJointSetDestructor( m_joint, destructor );

    m_callback = NULL;
}

BallAndSocket::~BallAndSocket()
{
    // nothing, the ~Joint() function will take care of us.
}

Ogre::Vector3 BallAndSocket::getJointAngle() const
{
    Ogre::Vector3 ret;

    NewtonBallGetJointAngle( m_joint, &ret.x );

    return ret;
}


Ogre::Vector3 BallAndSocket::getJointOmega() const
{
    Ogre::Vector3 ret;

    NewtonBallGetJointOmega( m_joint, &ret.x );

    return ret;
}


Ogre::Vector3 BallAndSocket::getJointForce() const
{
    Ogre::Vector3 ret;

    NewtonBallGetJointForce( m_joint, &ret.x );

    return ret;
}


void _CDECL BallAndSocket::newtonBallCallback(const NewtonJoint* ball, float timestep)
{
    BallAndSocket* me = (BallAndSocket*)NewtonJointGetUserData(ball);
    if( me->m_callback != NULL )
        ( *me->m_callback )(me, timestep);
}


///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////


Hinge::Hinge( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin ) : Joint()
{
    m_world = world;

    if (parent)
    {
        m_joint = NewtonConstraintCreateHinge( world->getNewtonWorld(), &pos.x, &pin.x,
                                                child->getNewtonBody(), parent->getNewtonBody() );
    }
    else
    {
        m_joint = NewtonConstraintCreateHinge( world->getNewtonWorld(), &pos.x, &pin.x,
                                                child->getNewtonBody(), NULL );
    }

    NewtonJointSetUserData( m_joint, this );
    NewtonJointSetDestructor( m_joint, destructor );
    NewtonHingeSetUserCallback( m_joint, newtonCallback );

    m_callback = NULL;
}

Hinge::~Hinge()
{
}


Ogre::Vector3 Hinge::getJointForce() const
{
    Ogre::Vector3 ret;

    NewtonHingeGetJointForce( m_joint, &ret.x );

    return ret;
}

unsigned _CDECL Hinge::newtonCallback( const NewtonJoint* hinge, NewtonHingeSliderUpdateDesc* desc )
{
    Hinge* me = (Hinge*)NewtonJointGetUserData( hinge );

    me->m_desc = desc;
    me->m_retval = 0;

    if (me->m_callback)
        (*me->m_callback)( me );

    me->m_desc = NULL;

    return me->m_retval;
}

/////// CALLBACK FUNCTIONS ///////
void Hinge::setCallbackAccel( Ogre::Real accel )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_accel = (float)accel;
    }
}

void Hinge::setCallbackFrictionMin( Ogre::Real min )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_minFriction = (float)min;
    }
}

void Hinge::setCallbackFrictionMax( Ogre::Real max )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_maxFriction = (float)max;
    }
}

Ogre::Real Hinge::getCallbackTimestep() const
{
    if (m_desc)
        return (Ogre::Real)m_desc->m_timestep;
    else
        return 0.0;
}

Ogre::Real Hinge::calculateStopAlpha( Ogre::Radian angle ) const
{
    if (m_desc)
        return (Ogre::Real)NewtonHingeCalculateStopAlpha( m_joint, m_desc, (float)angle.valueRadians() );
    else
        return 0.0;
}



///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////



Slider::Slider( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin ) : Joint()
{
    m_world = world;
    //std::cout << "EJ WTF pos" << pos << " pin" << pin << "\n";
    float pi[3];float po[3];
    pi[0] = pin.x;
    pi[1] = pin.y;
    pi[2] = pin.z;

    po[0] = pos.x;
    po[1] = pos.y;
    po[2] = pos.z;

    if (parent)
    {
        m_joint = NewtonConstraintCreateSlider( world->getNewtonWorld(), po, pi,
                                                child->getNewtonBody(), parent->getNewtonBody() );
    }
    else
    {
        m_joint = NewtonConstraintCreateSlider( world->getNewtonWorld(), po, pi,
                                                child->getNewtonBody(), NULL );
    }

    NewtonJointSetUserData( m_joint, this );
    NewtonJointSetDestructor( m_joint, destructor );
    NewtonSliderSetUserCallback( m_joint, newtonCallback );

    m_callback = NULL;
}

Slider::~Slider()
{
}

Ogre::Vector3 Slider::getJointForce() const
{
    Ogre::Vector3 ret;

    NewtonSliderGetJointForce( m_joint, &ret.x );

    return ret;
}

unsigned _CDECL Slider::newtonCallback( const NewtonJoint* slider, NewtonHingeSliderUpdateDesc* desc )
{
    Slider* me = (Slider*)NewtonJointGetUserData( slider );

    me->m_desc = desc;
    me->m_retval = 0;

    if (me->m_callback)
        (*me->m_callback)( me );

    me->m_desc = NULL;

    return me->m_retval;
}


/////// CALLBACK FUNCTIONS ///////
void Slider::setCallbackAccel( Ogre::Real accel )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_accel = (float)accel;
    }
}

void Slider::setCallbackFrictionMin( Ogre::Real min )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_minFriction = (float)min;
    }
}

void Slider::setCallbackFrictionMax( Ogre::Real max )
{
    if (m_desc)
    {
        m_retval = 1;
        m_desc->m_maxFriction = (float)max;
    }
}

Ogre::Real Slider::getCallbackTimestep() const
{
    if (m_desc)
        return (Ogre::Real)m_desc->m_timestep;
    else
        return 0.0;
}

Ogre::Real Slider::calculateStopAccel( Ogre::Real dist ) const
{
    if (m_desc)
        return (Ogre::Real)NewtonSliderCalculateStopAccel( m_joint, m_desc, (float)dist );
    else
        return 0.0;
}



///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////



Universal::Universal( const World* world, const OgreNewt::Body* child, const OgreNewt::Body* parent, const Ogre::Vector3& pos, const Ogre::Vector3& pin0, const Ogre::Vector3& pin1 ) : Joint()
{
    m_world = world;

    if (parent)
    {
        m_joint = NewtonConstraintCreateUniversal( world->getNewtonWorld(), &pos.x, &pin0.x, &pin1.x,
                                                child->getNewtonBody(), parent->getNewtonBody() );
    }
    else
    {
        m_joint = NewtonConstraintCreateUniversal( world->getNewtonWorld(), &pos.x, &pin0.x, &pin1.x,
                                                child->getNewtonBody(), NULL );
    }

    NewtonJointSetUserData( m_joint, this );
    NewtonJointSetDestructor( m_joint, destructor );
    NewtonUniversalSetUserCallback( m_joint, newtonCallback );

    m_callback = NULL;
}

Universal::~Universal()
{
}

Ogre::Vector3 Universal::getJointForce() const
{
    Ogre::Vector3 ret;

    NewtonUniversalGetJointForce( m_joint, &ret.x );

    return ret;
}

unsigned _CDECL Universal::newtonCallback( const NewtonJoint* universal, NewtonHingeSliderUpdateDesc* desc )
{
    Universal* me = (Universal*)NewtonJointGetUserData( universal );

    me->m_desc = desc;
    me->m_retval = 0;

    if (me->m_callback)
        (*me->m_callback)( me );

    me->m_desc = NULL;

    return me->m_retval;
}


/////// CALLBACK FUNCTIONS ///////
void Universal::setCallbackAccel( Ogre::Real accel, unsigned int axis )
{
    if (axis > 1) { return; }

    if (m_desc)
    {
        m_retval |= axis;
        m_desc[axis].m_accel = (float)accel;
    }
}

void Universal::setCallbackFrictionMax( Ogre::Real max, unsigned int axis )
{
    if (axis > 1) { return; }

    if (m_desc)
    {
        m_retval |= axis;
        m_desc[axis].m_maxFriction = (float)max;
    }
}

void Universal::setCallbackFrictionMin( Ogre::Real min, unsigned int axis )
{
    if (axis > 1) { return; }

    if (m_desc)
    {
        m_retval |= axis;
        m_desc[axis].m_minFriction = (float)min;
    }
}

Ogre::Real Universal::getCallbackTimestep() const
{
    if (m_desc)
        return (Ogre::Real)m_desc->m_timestep;
    else
        return 0.0;
}

Ogre::Real Universal::calculateStopAlpha0( Ogre::Real angle ) const
{
    if (m_desc)
        return (Ogre::Real)NewtonUniversalCalculateStopAlpha0( m_joint, m_desc, (float)angle );
    else
        return 0.0;
}

Ogre::Real Universal::calculateStopAlpha1( Ogre::Real angle ) const
{
    if (m_desc)
        return (Ogre::Real)NewtonUniversalCalculateStopAlpha1( m_joint, m_desc, (float)angle );
    else
        return 0.0;
}


///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////



UpVector::UpVector( const World* world, const Body* body, const Ogre::Vector3& pin )
{
    m_world = world;

    m_joint = NewtonConstraintCreateUpVector( world->getNewtonWorld(), &pin.x, body->getNewtonBody() );

    NewtonJointSetUserData( m_joint, this );
    NewtonJointSetDestructor( m_joint, destructor );

}

UpVector::~UpVector()
{
}

Ogre::Vector3 UpVector::getPin() const
{
    Ogre::Vector3 ret;

    NewtonUpVectorGetPin( m_joint, &ret.x );

    return ret;
}





}   // end NAMESPACE BasicJoints




///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////


namespace PrebuiltCustomJoints
{

Custom2DJoint::Custom2DJoint(const OgreNewt::Body* body, const Ogre::Vector3& pin ) : CustomJoint( 4, body, NULL )
{
    mPin = pin;
    Ogre::Quaternion bodyorient;
    Ogre::Vector3 bodypos;

    body->getPositionOrientation( bodypos, bodyorient );

    pinAndDirToLocal( bodypos, pin, mLocalOrient0, mLocalPos0, mLocalOrient1, mLocalPos1 );

    // initialize variables
    mMin = mMax = Ogre::Degree(0);
    mLimitsOn = false;
    mAccel = 0.0f;

}


void Custom2DJoint::submitConstraint( Ogre::Real timeStep, int threadIndex )
{
    // get the global orientations.
    Ogre::Quaternion globalOrient0, globalOrient1;
    Ogre::Vector3 globalPos0, globalPos1;

    localToGlobal( mLocalOrient0, mLocalPos0, globalOrient0, globalPos0, 0 );
    localToGlobal( mLocalOrient1, mLocalPos1, globalOrient1, globalPos1, 1 );

    // calculate all main 6 vectors.
    Ogre::Vector3 bod0X = globalOrient0 * Ogre::Vector3( Ogre::Vector3::UNIT_X );
    Ogre::Vector3 bod0Y = globalOrient0 * Ogre::Vector3( Ogre::Vector3::UNIT_Y );
    Ogre::Vector3 bod0Z = globalOrient0 * Ogre::Vector3( Ogre::Vector3::UNIT_Z );

    Ogre::Vector3 bod1X = globalOrient1 * Ogre::Vector3( Ogre::Vector3::UNIT_X );
    Ogre::Vector3 bod1Y = globalOrient1 * Ogre::Vector3( Ogre::Vector3::UNIT_Y );
    Ogre::Vector3 bod1Z = globalOrient1 * Ogre::Vector3( Ogre::Vector3::UNIT_Z );

#ifdef _DEBUG
    Ogre::LogManager::getSingletonPtr()->logMessage(" Submit Constraint   bod0X:"+Ogre::StringConverter::toString( bod0X )+
        "   bod1X:"+Ogre::StringConverter::toString( bod1X ) );
#endif

    // ---------------------------------------------------------------
    // first add a linear row to keep the body on the plane.
    addLinearRow( globalPos0, globalPos1, bod0X );

    // have we strayed from the plane along the normal?
    Ogre::Plane thePlane( bod0X, globalPos0 );
    Ogre::Real stray = thePlane.getDistance( globalPos1 );
    if (stray > 0.0001f)
    {
        // we have strayed, apply acceleration to move back to 0 in one timestep.
        Ogre::Real accel = (stray / timeStep);
        if (thePlane.getSide( globalPos1 ) == Ogre::Plane::NEGATIVE_SIDE) { accel = -accel; }

        setRowAcceleration( accel );
    }

    // see if the main axis (pin) has wandered off.
    Ogre::Vector3 latDir = bod0X.crossProduct( bod1X );
    Ogre::Real latMag = latDir.squaredLength();

    if (latMag > 1.0e-6f)
    {
        // has wandered a bit, we need to correct.  first find the angle off.
        latMag = Ogre::Math::Sqrt( latMag );
        latDir.normalise();
        Ogre::Radian angle = Ogre::Math::ASin( latMag );

        // ---------------------------------------------------------------
        addAngularRow( angle, latDir );

        // ---------------------------------------------------------------
        // secondary correction for stability.
        Ogre::Vector3 latDir2 = latDir.crossProduct( bod1X );
        addAngularRow( Ogre::Radian(0.0f), latDir2 );
    }
    else
    {
        // ---------------------------------------------------------------
        // no major change, just add 2 simple constraints.
        addAngularRow( Ogre::Radian(0.0f), bod1Y );
        addAngularRow( Ogre::Radian(0.0f), bod1Z );
    }

    // calculate the current angle.
    Ogre::Real cos = bod0Y.dotProduct( bod1Y );
    Ogre::Real sin = (bod0Y.crossProduct( bod1Y )).dotProduct( bod0X );

    mAngle = Ogre::Math::ATan2( sin, cos );

    if (mLimitsOn)
    {
        if (mAngle > mMax)
        {
            Ogre::Radian diff = mAngle - mMax;

            addAngularRow( diff, bod0X );
            setRowStiffness( 1.0f );
        }
        else if (mAngle < mMin)
        {
            Ogre::Radian diff = mAngle - mMin;

            addAngularRow( diff, bod0X );
            setRowStiffness( 1.0f );
        }
    }
    else
    {
        if (mAccel != 0.0f)
        {
            addAngularRow( Ogre::Radian(0.0f), bod0X );
            setRowAcceleration( mAccel );

            mAccel = 0.0f;
        }
    }

}


CustomRigidJoint::CustomRigidJoint(OgreNewt::Body *child, OgreNewt::Body *parent, Ogre::Vector3 dir, Ogre::Vector3 pos) : OgreNewt::CustomJoint(6,child,parent)
{
    // calculate local offsets.
    pinAndDirToLocal( pos, dir, mLocalOrient0, mLocalPos0, mLocalOrient1, mLocalPos1 );
}

CustomRigidJoint::~CustomRigidJoint()
{
}

void CustomRigidJoint::submitConstraint( Ogre::Real timeStep, int threadIndex )
{
    // get globals.
    Ogre::Vector3 globalPos0, globalPos1;
    Ogre::Quaternion globalOrient0, globalOrient1;

    localToGlobal( mLocalOrient0, mLocalPos0, globalOrient0, globalPos0, 0 );
    localToGlobal( mLocalOrient1, mLocalPos1, globalOrient1, globalPos1, 1 );

    // apply the constraints!
    addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_X );
    addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Y );
    addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Z );

    // now find a point off 10 units away.
    globalPos0 = globalPos0 + (globalOrient0 * (Ogre::Vector3::UNIT_X * 10.0f));
    globalPos1 = globalPos1 + (globalOrient1 * (Ogre::Vector3::UNIT_X * 10.0f));

    // apply the constraints!
    addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Y );
    addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Z );

    Ogre::Vector3 xdir0 = globalOrient0 * Ogre::Vector3::UNIT_X;
    Ogre::Vector3 xdir1 = globalOrient1 * Ogre::Vector3::UNIT_X;

    Ogre::Radian angle = Ogre::Math::ACos( xdir0.dotProduct( xdir1 ) );
    addAngularRow( angle, globalOrient0 * Ogre::Vector3::UNIT_X );
}

/*
CustomDryRollingFriction::CustomDryRollingFriction( OgreNewt::Body* child, Ogre::Real radius, Ogre::Real rollingFrictionCoefficient ) :
    OgreNewt::CustomJoint(1, child, NULL),
    mChild(child)
{
    Ogre::Real mass;
    Ogre::Vector3 inertia;

    child->getMassMatrix( mass, inertia );

    mFrictionCoefficient =  rollingFrictionCoefficient;
    mFrictionTorque = inertia.x * radius;
}

CustomDryRollingFriction::~CustomDryRollingFriction()
{
}


// copied from CustomDryRollingFriction joint in newton
void CustomDryRollingFriction::submitConstraint( Ogre::Real timestep, int threadIndex )
{
    Ogre::Vector3 omega;
    Ogre::Real omegaMag;
    Ogre::Real torqueFriction;


    omega = mChild->getOmega();
    omegaMag = omega.length();

    if( omegaMag > 0.1f )
    {
        addAngularRow(Ogre::Radian(0), omega.normalisedCopy());
        setRowAcceleration( -omegaMag/timestep );
        torqueFriction = mFrictionTorque*mFrictionCoefficient;
        setRowMinimumFriction(-torqueFriction);
        setRowMaximumFriction(torqueFriction);
    }
    else
    {
        mChild->setOmega(omega*0.2f);
    }

}
*/


}   // end NAMESPACE PrebuiltCustomJoints




}   // end NAMESPACE OgreNewt

| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Slider doesnt work!

Postby Julio Jerez » Thu Sep 17, 2009 5:01 pm

I see and it is not how I would expect it to be.
I can see that the code implement two joints types, the build in Joints, and the Custom joint
Build in joints do re use the existing the funtionality of the build in code in newton and that is fine,

but the Custom joints re implemnet the function of the Custom joint library instead of reusing it.
as a result the joints are imcompleded, and hard to maitain. Beacse to add ne joint it requeres a person with a better than average knowledge of how Newton work.
As a result teh library is imcoplete.
It is my opnion that a good programere soudl eb able to use any of teh Joint atht comes with teh joint library even of theer are no impelmneted in OgreNewt.
I will modify the Ogre Custom Joint so that I res uses the joint library and I will try to keep teh same interface that is already there,
It will still required a expecilist to make New Joints, but is sodul be triavail to add existing joints.
I will post the full class tonight, then you will see what I mean, I cannot do it now


I do not like to interfere with people how make newton Wrapers, but I see lot of contrive implemention there,
I will make an expation and try to make a modification since it looks like many people use OgreNewt.
How can I download Ogrenewt SDK, so tah I cna make a better job than joint writing untested code?
I will not make everything just enought for the people who keep it can continue, plus it is optional for for every one the take.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Slider doesnt work!

Postby PJani » Thu Sep 17, 2009 6:02 pm

You can download OgreNewt from svn

this is svn link: https://svn.ogre3d.org/svnroot/ogreaddo ... t/newton20
you will need something like TortoiseSVN on windows (http://tortoisesvn.net/) or on linux im not sure what to use...
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Slider doesnt work!

Postby Julio Jerez » Thu Sep 17, 2009 6:13 pm

Is there a link whe I can download an archive file form soem webside, maybe rapishare?
I do not like to spend much time with the SNV mombojombo
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Slider doesnt work!

Postby PJani » Thu Sep 17, 2009 6:26 pm

http://rapidshare.com/files/281511118/O ... 9.zip.html
MD5: 1EC1313A79C21ED087B9A195A82639BE
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
User avatar
PJani
 
Posts: 448
Joined: Mon Feb 02, 2009 7:18 pm
Location: Slovenia

Re: Slider doesnt work!

Postby Julio Jerez » Fri Sep 18, 2009 10:55 pm

Ok I downloaded this, and I opened with Visual studion 2008 (which is cool)
I am suprice how small OgreNewt is. :mrgreen:

I tried to builld it and I get a bunch of errors I guess I need to download Ogre to build it, don't it?.
I will do that now to see if I get i ready for tomorrow.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Slider doesnt work!

Postby Julio Jerez » Fri Sep 18, 2009 11:37 pm

you are going to have to help me out here.

I dowloaded Ogre and It is building know,
I asume I need to copy NgreNewt to some Ogre forder, but I am a lost here.
I do no really undertand how Ogre work, I have never bee able to build it on windows (just in linux),
with the exection of demos that are already compiled I do not know how to even run an Ogre Demo.

I am reading this tutorial but this asume I know Ogre already and I do not
http://www.newtondynamics.com/wiki/index.php5?title=Tutorial_-_Ogre_and_Newton_with_OgreNewt_beginners_guide

In what folder I need put OgreNewt in the Ogre folder?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron