A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by arkdemon » Fri Feb 14, 2014 11:12 am
Hello everybody. I want to make meshs using some joints. For example, imagine an airplane. I want it to have 2 wings which can be torn out of the plane when it collides with a tree, for example. However, joints are a new concept for me and I do not understand at all how to use them. There are examples in the SDK: Articulated Joints and Basic Ragdoll but the code is complicated, is long and depends of DemoEntity; it is confusing and on the hundreds of lines(821 for ArticulatedJoints.cpp) I think I will only need 20 lines or even less. So my questions are: How can I implement joints? and if it is possible, how can I make a screw-type joint?
Thank you for your help.
My name is arkdemon and I don't approve this message

-

arkdemon
-
- Posts: 90
- Joined: Sat Jan 18, 2014 12:38 pm
by Julio Jerez » Fri Feb 14, 2014 12:01 pm
look at standardjoints demos
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by arkdemon » Fri Feb 14, 2014 12:23 pm
OK. I built newton to 3.12. While updating (I use MinGW with Qt Creator) the makefile was wrong at some points: it did not include dgMeshEffect6.cpp, dgDeformableBodiesUpdate.cpp and there was dgCollisionCompoundBreakable.cpp at the place of dgCollisionCompoundFractured.cpp. So here is the makefile (updated) which works for me:
- Code: Select all
#*******************************************************
#
# Newton game dynamics
# copy right by Julio Jerez 2002 - 2012
#
#*******************************************************
#
# Generic makefile
# this make file generate the libraries:
# dg, physics, and newton
#
#*******************************************************
# ******************************************************
#
# dg low level library
#
# ******************************************************
# $(DG_PTHREAD_PATH)/pthread.c \
DG_PTHREAD_PATH = ../../source/pthreads.2
DG_INCLUDED_PATH = ../../source/core
DG_PATH = $(DG_INCLUDED_PATH)/
DG_SRCS = \
$(DG_PATH)dgAABBPolygonSoup.cpp \
$(DG_PATH)dgAsyncThread.cpp \
$(DG_PATH)dgConvexHull3d.cpp \
$(DG_PATH)dgConvexHull4d.cpp \
$(DG_PATH)dg.cpp \
$(DG_PATH)dgCRC.cpp \
$(DG_PATH)dgDebug.cpp \
$(DG_PATH)dgDelaunayTetrahedralization.cpp \
$(DG_PATH)dgGeneralMatrix.cpp \
$(DG_PATH)dgGeneralVector.cpp \
$(DG_PATH)dgGoogol.cpp \
$(DG_PATH)dgIntersections.cpp \
$(DG_PATH)dgMatrix.cpp \
$(DG_PATH)dgMemory.cpp \
$(DG_PATH)dgMutexThread.cpp \
$(DG_PATH)dgNode.cpp \
$(DG_PATH)dgPolygonSoupBuilder.cpp \
$(DG_PATH)dgPolyhedra.cpp \
$(DG_PATH)dgPolyhedraMassProperties.cpp \
$(DG_PATH)dgQuaternion.cpp \
$(DG_PATH)dgRandom.cpp \
$(DG_PATH)dgRefCounter.cpp \
$(DG_PATH)dgRef.cpp \
$(DG_PATH)dgSmallDeterminant.cpp \
$(DG_PATH)dgSPDMatrix.cpp \
$(DG_PATH)dgObb.cpp \
$(DG_PATH)dgThread.cpp \
$(DG_PATH)dgThreadHive.cpp \
$(DG_PATH)dgTree.cpp \
$(DG_PATH)dgTypes.cpp
# ******************************************************
#
# Physics engine files
#
# ******************************************************
DG_INCLUDED_PHYSICS_PATH = ../../source/physics
DG_PHYSICS_PATH = $(DG_INCLUDED_PHYSICS_PATH)/
DG_PHYSICS_SRCS = \
$(DG_PHYSICS_PATH)dgBody.cpp \
$(DG_PHYSICS_PATH)dgDynamicBody.cpp \
$(DG_PHYSICS_PATH)dgKinematicBody.cpp \
$(DG_PHYSICS_PATH)dgBallConstraint.cpp \
$(DG_PHYSICS_PATH)dgBilateralConstraint.cpp \
$(DG_PHYSICS_PATH)dgBody.cpp \
$(DG_PHYSICS_PATH)dgDynamicBody.cpp \
$(DG_PHYSICS_PATH)dgKinematicBody.cpp \
$(DG_PHYSICS_PATH)dgBodyMasterList.cpp \
$(DG_PHYSICS_PATH)dgBroadPhase.cpp \
$(DG_PHYSICS_PATH)dgCollisionBox.cpp \
$(DG_PHYSICS_PATH)dgCollisionBVH.cpp \
$(DG_PHYSICS_PATH)dgCollisionCapsule.cpp \
$(DG_PHYSICS_PATH)dgCollisionChamferCylinder.cpp \
$(DG_PHYSICS_PATH)dgCollisionCompoundFractured.cpp \
$(DG_PHYSICS_PATH)dgCollisionCompound.cpp \
$(DG_PHYSICS_PATH)dgCollisionCone.cpp \
$(DG_PHYSICS_PATH)dgCollisionConvex.cpp \
$(DG_PHYSICS_PATH)dgCollisionConvexHull.cpp \
$(DG_PHYSICS_PATH)dgCollisionConvexPolygon.cpp \
$(DG_PHYSICS_PATH)dgCollision.cpp \
$(DG_PHYSICS_PATH)dgCollisionCylinder.cpp \
$(DG_PHYSICS_PATH)dgCollisionDeformableClothPatch.cpp \
$(DG_PHYSICS_PATH)dgCollisionDeformableSolidMesh.cpp \
$(DG_PHYSICS_PATH)dgCollisionDeformableMesh.cpp \
$(DG_PHYSICS_PATH)dgCollisionHeightField.cpp \
$(DG_PHYSICS_PATH)dgCollisionInstance.cpp \
$(DG_PHYSICS_PATH)dgCollisionMesh.cpp \
$(DG_PHYSICS_PATH)dgCollisionNull.cpp \
$(DG_PHYSICS_PATH)dgCollisionScene.cpp \
$(DG_PHYSICS_PATH)dgCollisionSphere.cpp \
$(DG_PHYSICS_PATH)dgCollisionTaperedCapsule.cpp \
$(DG_PHYSICS_PATH)dgCollisionTaperedCylinder.cpp \
$(DG_PHYSICS_PATH)dgCollisionUserMesh.cpp \
$(DG_PHYSICS_PATH)dgConstraint.cpp \
$(DG_PHYSICS_PATH)dgContact.cpp \
$(DG_PHYSICS_PATH)dgCorkscrewConstraint.cpp \
$(DG_PHYSICS_PATH)dgDeformableBody.cpp \
$(DG_PHYSICS_PATH)dgDeformableContact.cpp \
$(DG_PHYSICS_PATH)dgHingeConstraint.cpp \
$(DG_PHYSICS_PATH)dgNarrowPhaseCollision.cpp \
$(DG_PHYSICS_PATH)dgSlidingConstraint.cpp \
$(DG_PHYSICS_PATH)dgUniversalConstraint.cpp \
$(DG_PHYSICS_PATH)dgUpVectorConstraint.cpp \
$(DG_PHYSICS_PATH)dgUserConstraint.cpp \
$(DG_PHYSICS_PATH)dgWorld.cpp \
$(DG_PHYSICS_PATH)dgWorldDynamicsParallelSolver.cpp \
$(DG_PHYSICS_PATH)dgWorldDynamicsSimpleSolver.cpp \
$(DG_PHYSICS_PATH)dgWorldDynamicUpdate.cpp \
$(DG_PHYSICS_PATH)dgDeformableBodiesUpdate.cpp
# ******************************************************
#
# mesh gemotry
#
# ******************************************************
DG_INCLUDED_MESH_PATH = ../../source/meshUtil
DG_MESH_PATH = $(DG_INCLUDED_MESH_PATH)/
DG_MESH_SRCS = \
$(DG_MESH_PATH)dgMeshEffect1.cpp \
$(DG_MESH_PATH)dgMeshEffect2.cpp \
$(DG_MESH_PATH)dgMeshEffect3.cpp \
$(DG_MESH_PATH)dgMeshEffect4.cpp \
$(DG_MESH_PATH)dgMeshEffect5.cpp \
$(DG_MESH_PATH)dgMeshEffect6.cpp
# ******************************************************
#
# open cl
#
# ******************************************************
DG_INCLUDED_OPENCL_PATH = ../../source/openCL
DG_OPENCL_PATH = $(DG_INCLUDED_OPENCL_PATH)/
#DG_OPENCL_SRCS = \
# $(DG_OPENCL_PATH)dgOpencl.cpp \
# $(DG_OPENCL_PATH)dgOpenclInstance.cpp \
# $(DG_OPENCL_PATH)dgOpenclBroadPhase.cpp
# ******************************************************
#
# Newton engine files
#g++ -shared -o libNewton.so libNewton.a
# ******************************************************
DG_INCLUDED_NEWTON_PATH = ../../source/newton
DG_NEWTON_PATH = $(DG_INCLUDED_NEWTON_PATH)/
DG_NEWTON_SRCS = \
$(DG_NEWTON_PATH)Newton.cpp \
$(DG_NEWTON_PATH)NewtonClass.cpp
# ******************************************************
#
# Allsource files
#
# ******************************************************
ALL_SRC_FILES = $(DG_SRCS) $(DG_PHYSICS_SRCS) $(DG_OPENCL_SRCS) $(DG_MESH_SRCS) $(DG_NEWTON_SRCS)
DG_OBJ_FILES = $(ALL_SRC_FILES:.cpp=.o)
COMPILER = gcc
# POSIX options gcc 4.4.2
#CPU_FLAGS = -m32 -O0 -fPIC -g -msse -msse2 -mfpmath=sse
#CPU_FLAGS = -m32 -O0 -fPIC -g -msse -msse4.1 -mfpmath=sse
#CPU_FLAGS = -m32 -O2 -fpic -g -msse -msse4.1 -mfpmath=sse -ffloat-store -ffast-math -freciprocal-math -funsafe-math-optimizations -fsingle-precision-constant
CPU_FLAGS = -m32 -O2 -g -msse -msse3 -mfpmath=sse -ffloat-store -ffast-math -freciprocal-math -funsafe-math-optimizations -fsingle-precision-constant
FLAGS = -c -Wall -Wno-strict-aliasing -DPTW32_BUILD -DPTW32_STATIC_LIB -D_NEWTON_STATIC_LIB -D_MINGW_32_VER $(CPU_FLAGS) -I$(DG_PTHREAD_PATH) -I$(DG_INCLUDED_PATH) -I$(DG_INCLUDED_PHYSICS_PATH) -I$(DG_INCLUDED_MESH_PATH) -I$(DG_INCLUDED_OPENCL_PATH)
INSTALL_PATH = mingw32
.SUFFIXES : .o .cpp
.cpp.o :
$(COMPILER) $(FLAGS) -o $@ $<
# main target
engine : libNewton.a
# clean all objects target
clean :
del /S ..\..\*.o
# libraries targets
libNewton.a : $(DG_OBJ_FILES)
ar r $@ $?
For the Joints, I will look into it and post the results. Thank you for your help
My name is arkdemon and I don't approve this message

-

arkdemon
-
- Posts: 90
- Joined: Sat Jan 18, 2014 12:38 pm
by Julio Jerez » Fri Feb 14, 2014 12:37 pm
in what sub directory is that make file?
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by arkdemon » Fri Feb 14, 2014 12:44 pm
It's here: ../coreLibrary_300/projects/mingw32
It works! Thanks for your help
My name is arkdemon and I don't approve this message

-

arkdemon
-
- Posts: 90
- Joined: Sat Jan 18, 2014 12:38 pm
by arkdemon » Fri Feb 14, 2014 12:45 pm
PS: I did not use the CustomJoint class because I could not compile it. Anyway, here is the code I used (It is nearly a copy/paste but I replaced dMatrix by dgMatrix and dVector by dgVector and little other things)
Attention: I replaced dSin, dCos, ... by glm functions
customjoint.h:
- Code: Select all
class CustomAlloc
{
public:
void* operator new (size_t size){
return NewtonAlloc(int (size));
}
void operator delete (void* ptr){
NewtonFree(ptr);
}
CustomAlloc() { }
virtual ~CustomAlloc() { }
};
struct NewtonUserJoint;
typedef void (*JointUserDestructorCallback) (const NewtonUserJoint* const me);
typedef void (*JointUserSubmitConstraintCallback) (const NewtonUserJoint* const me, dFloat timestep, int threadIndex);
// this is the base class to implement custom joints, it is not a joint it just provide functionality
// for the user to implement it own joints
class CustomJoint: public CustomAlloc
{
public:
struct AngularIntegration
{
AngularIntegration()
{
m_angle = 0.0f;
}
dFloat CalculateJointAngle (dFloat newAngleCos, dFloat newAngleSin)
{
// the joint angle can be determine by getting the angle between any two non parallel vectors
dFloat sinJointAngle = glm::sin(m_angle);
dFloat cosJointAngle = glm::cos(m_angle);
dFloat sin_da = newAngleSin * cosJointAngle - newAngleCos * sinJointAngle;
dFloat cos_da = newAngleCos * cosJointAngle + newAngleSin * sinJointAngle;
m_angle += atan2 (sin_da, cos_da);
return m_angle;
}
dFloat m_angle;
};
CustomJoint();
CustomJoint(int maxDOF, NewtonBody* const body0, NewtonBody* const body1);
virtual ~CustomJoint();
void SetBodiesCollisionState (int state);
int GetBodiesCollisionState () const;
NewtonBody* GetBody0 () const;
NewtonBody* GetBody1 () const;
NewtonJoint* GetJoint () const;
void JointSetSolverMode (bool mode, int maxContactJoints) const;
// the application needs to implement this function for serialization
virtual void GetInfo (NewtonJointRecord* const info) const;
virtual void ProjectError () const;
// these member function are only used by the C interface or for hooking callback to customize a particular
// joint without deriving a new one
// note: this is not a extension of a virtual function, DO NOT CALL the base class SubmitConstraints!!
void SetUserData (void* userData) {m_userData = userData;}
void* GetUserData () const {return m_userData;}
void SetUserDestructorCallback (JointUserDestructorCallback callback) {m_userDestructor = callback;}
void SetUserSubmintConstraintCallback (JointUserSubmitConstraintCallback callback) {m_userConstrationCallback = callback;}
private:
// this are the callback needed to have transparent c++ method interfaces
static void Destructor (const NewtonJoint* me);
static void SubmitConstraints (const NewtonJoint* const me, dFloat timestep, int threadIndex);
static void GetInfo (const NewtonJoint* const me, NewtonJointRecord* info);
protected:
void Init (int maxDOF, NewtonBody* const body0, NewtonBody* const body1);
// the application needs to implement this function for each derived joint. See examples for more detail
virtual void SubmitConstraints (dFloat timestep, int threadIndex);
void CalculateGlobalMatrix (const dgMatrix& localMatrix0, const dgMatrix& localMatrix1, dgMatrix& matrix0, dgMatrix& matrix1) const;
void CalculateLocalMatrix (const dgMatrix& pinsAndPivotFrame, dgMatrix& localMatrix0, dgMatrix& localMatrix1) const;
void* m_userData;
NewtonBody* m_body0;
NewtonBody* m_body1;
NewtonJoint* m_joint;
NewtonWorld* m_world;
JointUserDestructorCallback m_userDestructor;
JointUserSubmitConstraintCallback m_userConstrationCallback;
int m_maxDof;
int m_autoDestroy;
};
class CustomDistance: public CustomJoint
{
public:
CustomDistance (const dgVector& pivotInChildInGlobalSpace, const dgVector& pivotInParentInGlobalSpace, NewtonBody* const child, NewtonBody* const parent)
:CustomJoint(3, child, parent)
{
dgVector dist (pivotInChildInGlobalSpace - pivotInParentInGlobalSpace) ;
m_distance = glm::sqrt (dist % dist);
dgMatrix childMatrix (dgGetIdentityMatrix());
dgMatrix parentMatrix (dgGetIdentityMatrix());
childMatrix.m_posit = pivotInChildInGlobalSpace;
parentMatrix.m_posit = pivotInParentInGlobalSpace;
childMatrix.m_posit.m_w = 1.0f;
parentMatrix.m_posit.m_w = 1.0f;
dgMatrix dummy;
CalculateLocalMatrix (childMatrix, m_localPivot, dummy);
CalculateLocalMatrix (parentMatrix, dummy, m_parentPivot);
}
void SubmitConstraints (dFloat timestep, int threadIndex)
{
dgMatrix matrix0;
dgMatrix matrix1;
// calculate the position of the pivot point and the Jacobian direction vectors, in global space.
CalculateGlobalMatrix (m_localPivot, m_parentPivot, matrix0, matrix1);
dgVector p0 (matrix0.m_posit);
dgVector p1 (matrix1.m_posit);
dgVector dist (p1 - p0);
dFloat mag2 = dist % dist;
if (mag2 > 0.0f) {
dist = dist.Scale3(1.0f / glm::sqrt (mag2));
p0 += dist.Scale3(m_distance);
}
// Restrict the movement on the pivot point along all tree orthonormal direction
NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_front[0]);
NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_up[0]);
NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_right[0]);
}
dgMatrix m_localPivot;
dgMatrix m_parentPivot;
dFloat m_distance;
};
customjoint.cpp:
- Code: Select all
#include "joint.h"
CustomJoint::CustomJoint ()
:m_userData(NULL)
,m_body0(NULL)
,m_body1(NULL)
,m_joint(NULL)
,m_world(NULL)
,m_userDestructor(NULL)
,m_userConstrationCallback(NULL)
,m_maxDof(0)
,m_autoDestroy(0)
{
}
CustomJoint::CustomJoint (int maxDOF, NewtonBody* const body0, NewtonBody* const body1)
{
Init (maxDOF, body0, body1);
}
CustomJoint::~CustomJoint()
{
//dAssert (m_joint);
//if the joint has user data it means the application is destroying the joint
// if there is a C destructor call it form here
CustomJoint* const joint = (CustomJoint*) NewtonJointGetUserData (m_joint);
if (joint->m_userDestructor) {
joint->m_userDestructor ((const NewtonUserJoint*) joint);
}
// if (NewtonJointGetUserData (m_joint)) {
if (!m_autoDestroy) {
// set the joint call to NULL to prevent infinite recursion
NewtonJointSetUserData (m_joint, NULL);
NewtonJointSetDestructor (m_joint, NULL);
// destroy this joint
NewtonDestroyJoint(m_world, m_joint);
}
}
void CustomJoint::Init (int maxDOF, NewtonBody* const body0, NewtonBody* const body1)
{
m_autoDestroy = 0;
m_joint = NULL;
m_body0 = body0;
m_body1 = body1;
m_maxDof = maxDOF;
m_world = NewtonBodyGetWorld (body0);
m_joint = NewtonConstraintCreateUserJoint (m_world, maxDOF, SubmitConstraints, GetInfo, m_body0, m_body1);
NewtonJointSetUserData (m_joint, this);
NewtonJointSetDestructor (m_joint, Destructor);
m_userData = NULL;
m_userDestructor = NULL;
m_userConstrationCallback = NULL;
}
NewtonBody* CustomJoint::GetBody0 () const
{
return m_body0;
}
NewtonBody* CustomJoint::GetBody1 () const
{
return m_body1;
}
NewtonJoint* CustomJoint::GetJoint () const
{
return m_joint;
}
void CustomJoint::Destructor (const NewtonJoint* me)
{
// get the pointer to the joint class
CustomJoint* const joint = (CustomJoint*) NewtonJointGetUserData (me);
joint->m_autoDestroy = 1;
// delete the joint class
delete joint;
}
void CustomJoint::SubmitConstraints (const NewtonJoint* const me, dFloat timestep, int threadIndex)
{
// get the pointer to the joint class
CustomJoint* const joint = (CustomJoint*) NewtonJointGetUserData (me);
// call the constraint call back
joint->SubmitConstraints(timestep, threadIndex);
// if there is a user define callback call it from here;
if (joint->m_userConstrationCallback) {
joint->m_userConstrationCallback ((const NewtonUserJoint*) joint, timestep, threadIndex);
}
}
void CustomJoint::GetInfo (const NewtonJoint* const me, NewtonJointRecord* info)
{
// get the pointer to the joint class
CustomJoint* const joint = (CustomJoint*) NewtonJointGetUserData (me);
joint->GetInfo(info);
}
void CustomJoint::CalculateLocalMatrix (const dgMatrix& pinsAndPivotFrame, dgMatrix& localMatrix0, dgMatrix& localMatrix1) const
{
dgMatrix matrix0;
// Get the global matrices of each rigid body.
NewtonBodyGetMatrix(m_body0, &matrix0[0][0]);
dgMatrix matrix1 (dgGetIdentityMatrix());
if (m_body1) {
NewtonBodyGetMatrix(m_body1, &matrix1[0][0]);
}
// calculate the relative matrix of the pin and pivot on each body
localMatrix0 = pinsAndPivotFrame * matrix0.Inverse();
localMatrix1 = pinsAndPivotFrame * matrix1.Inverse();
}
void CustomJoint::CalculateGlobalMatrix (const dgMatrix& localMatrix0, const dgMatrix& localMatrix1, dgMatrix& matrix0, dgMatrix& matrix1) const
{
dgMatrix body0Matrix;
// Get the global matrices of each rigid body.
NewtonBodyGetMatrix(m_body0, &body0Matrix[0][0]);
dgMatrix body1Matrix (dgGetIdentityMatrix());
if (m_body1) {
NewtonBodyGetMatrix(m_body1, &body1Matrix[0][0]);
}
matrix0 = localMatrix0 * body0Matrix;
matrix1 = localMatrix1 * body1Matrix;
}
void CustomJoint::GetInfo (NewtonJointRecord* const info) const
{
}
void CustomJoint::ProjectError () const
{
}
void CustomJoint::SetBodiesCollisionState (int state)
{
NewtonJointSetCollisionState (m_joint, state);
}
int CustomJoint::GetBodiesCollisionState () const
{
return NewtonJointGetCollisionState (m_joint);
}
void CustomJoint::JointSetSolverMode (bool mode, int maxContactJoints) const
{
NewtonUserJointSetSolver (m_joint, mode, maxContactJoints);
}
void CustomJoint::SubmitConstraints (dFloat timestep, int threadIndex)
{
}
My name is arkdemon and I don't approve this message

-

arkdemon
-
- Posts: 90
- Joined: Sat Jan 18, 2014 12:38 pm
by arkdemon » Sat Feb 15, 2014 9:17 am
Hi again. I have a problem with the joints when I try to make a Screw: the body 1 (child) does not rotate when the Body 0 (parent) rotates and I do not know how to make it work. I am trying to make the body 1 do exactly the same thing the body 0 does (ie rotate and move) and it should not be allowed to move at all otherwise like airplane wings for example. In a way, it should be attached to the parent body but should be detached when there is a strong collision. Thank you for your answers
My name is arkdemon and I don't approve this message

-

arkdemon
-
- Posts: 90
- Joined: Sat Jan 18, 2014 12:38 pm
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 1 guest