[Solved] NewtonBodyGetUserData() doesn't return valid pointer

Started by
13 comments, last by deadstar 15 years, 11 months ago
Hi, I'm trying to use NewtonBodySetUserData and NewtonBodyGetUserData to store a pointer to geometry data in a NewtonBody, but I can't get it to return a valid pointer. Setting the UserData like this:

void SYM_PHYSICSBODY::SetGeometry(SYM_GEOMETRY *Geom)
	{
	    NewtonBodySetUserData(Body, Geom);
	}


Retrieving the UserData like this:

void  PhysicsSetTransform (const NewtonBody* body, const dFloat* matrix)
    {
        //Get geometry
        SYM_GEOMETRY *Geometry = (SYM_GEOMETRY*)NewtonBodyGetUserData(body);

...


Trying to access any members in *Geometry causes an access violation. [Edited by - deadstar on May 27, 2008 4:21:48 PM]

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

Advertisement
Are you sure that you are calling the Get function on the same body you called Set on? Can you post the code that shows how these functions interact?
Did you ever allocate any memory for geom, and if so, are you sure you didn't delete it somehow? Are you sure you actually set the user data for this particular geom?
[size=2]
This question has nothing to do with Newton, your SYS_GEOMETRY pointer is invalid.
Sure.

SYM_GEOMETRY is a base class for all renderables, it contains a *Mesh, Position and Rotation vectors, and functions for transformation and setting Mass, Velocity, etc.

SYM_MODEL is derived from the Geometry class, and contains just a Load() function for my proprietary format. Here is the Load():

bool SYM_MODEL::Load(string ModelName, string Filename)	{		//Load mesh from resource manager		Mesh = Engine->ResourceManager.Meshes.Get(Filename);		//Check for errors		if(!Mesh) return false;		//Set name		Name = ModelName;		//New physics body		PhysicsBody = new SYM_PHYSICSBODY;		//Create physics body from AABB		PhysicsBody->CreateBox(Mesh->AABB.Size);		//Set physics geometry		PhysicsBody->SetGeometry(dynamic_cast<SYM_GEOMETRY*>(this));		return true;	}


SYM_BRUSH is derived from the Geometry class, and contains functions to create default geometry objects using the *Mesh. Here is the constructor:

SYM_BRUSH::SYM_BRUSH(string BrushName, int GeomType, SYM_VECTOR3 Dimentions, SYM_VECTOR3 Pos)	{		//Create new mesh		Mesh = new SYM_MESH;		//Create new mesh subset		MeshSubset = new SYM_MESHSUBSET;		//Switch type		switch(GeomType)		{			case SYM_BOX:				//Create a box				break;			case SYM_PLANE:				//Create a plane				//Mesh->CreatePlane(Dimentions);				//Create geometry				CreatePlane(Dimentions);				break;			case SYM_CYLINDER:				//Create a cylinder				break;			case SYM_SPHERE:				//Create a sphere				break;			default:				return;		}		//Process vertex/face data		MeshSubset->Process();		//Add subset to mesh		Mesh->Subsets.push_back(*MeshSubset);		//Set name		Name = BrushName;		//New physics body		PhysicsBody = new SYM_PHYSICSBODY;		//Setup collision body		PhysicsBody->CreateCustom(Mesh->Subsets[0].Vertices, Mesh->Subsets[0].Faces);		//Set physics geometry		PhysicsBody->SetGeometry(dynamic_cast<SYM_GEOMETRY*>(this));		//Set position		SetPosition(Pos);	}


Those are the only objects that contain a NewtonBody, and both make sure to call SetGeometry().

I've tested the dynamic_cast from Model/Brush to the base class, they work fine. I've also cout-ed a few geometry details in SetGeometry() to make sure the pointer is valid, and it's fine.


"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

That code doesn't call PhysicsSetTransform() anywhere...
Quote:Original post by wild_pointer
Did you ever allocate any memory for geom, and if so, are you sure you didn't delete it somehow? Are you sure you actually set the user data for this particular geom?


All the Geometry objects are in an stl::map int he scene manager, all there and rendering fine.

Every object that contains a NewtonBody has SetGeometry() called on it.

Quote:Original post by agi_shi
This question has nothing to do with Newton, your SYS_GEOMETRY pointer is invalid.


That was my original thought, but I output the geometry's name in SetGeometry(0 and it seems the pointer is fine.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

Quote:Original post by Gage64
That code doesn't call PhysicsSetTransform() anywhere...


PhysicsSetTransform is one of Newton's callbacks. This where the exception is caught.


"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

Well, post the code that sets up the callback (I'm grasping, I know).

Also, I guess it doesn't hurt to ask - did you step through the program with the debugger and made sure the sequence of events is as it should be?
No problem.

CreateBox() and CreateCustom() set the callbacks:

bool SYM_PHYSICSBODY::CreateBox(SYM_VECTOR3 Dimentions)	{		//Create collision object		Collision = NewtonCreateBox(Engine->Physics.GetWorld(), Dimentions.x, Dimentions.y, Dimentions.z, NULL);		//Create rigid body		RigidBody = NewtonCreateBody(Engine->Physics.GetWorld(), Collision);		//Set tranform callback		NewtonBodySetTransformCallback(RigidBody, PhysicsSetTransform);		//Set force and torque callback to rigid body		NewtonBodySetForceAndTorqueCallback(RigidBody, PhysicsApplyForceAndTorque);		//Release collision object		NewtonReleaseCollision(Engine->Physics.GetWorld(), Collision);		//Set the mass distribution matrix		NewtonBodySetMassMatrix(RigidBody, Mass, 1.0f, 1.0f, 1.0f);		//Get AABB		NewtonBodyGetAABB(RigidBody, AABBMin, AABBMax);		return true;	}


CreateCustom() is almost identical, but builds the collision body using a vertex list.

I've stepped through the program, everything is called in order, and everything is fine up until the line:

SYM_GEOMETRY *Geometry = (SYM_GEOMETRY*)NewtonBodyGetUserData(body);


This returns what seems like a garbage pointer. I've also tried the following:

//Get geometry        SYM_GEOMETRY *Geometry = 0;        Geometry = (SYM_GEOMETRY*)NewtonBodyGetUserData(body);        //Check geometry exists        if(Geometry)        {            cout << Geometry->Name << endl;        }        else        {            Engine->Logger.AddEntry("Error: PhysicsSetTransform called with no geometry set");        }


The log message is never called, so GetUserData seems to be returning something nonsensical rather than the non-initialised pointer being the problem.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

This topic is closed to new replies.

Advertisement