Sign in to follow this  

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

This topic is 3491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.


Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
// From your first post:
NewtonBodySetUserData(Body, Geom);

// From your last post:
NewtonBodySetTransformCallback(RigidBody, PhysicsSetTransform);


Do Body and RigidBody point to the same thing?

(I'm sorry if this question doesn't make sense. I'm not familiar with Newton so maybe I'm misunderstanding something very basic. If I'm not familiar with Newton then why am I trying to help you? It's because I think that this is a general programming problem and not one that's related to Newton, but I could be wrong.)

Share this post


Link to post
Share on other sites
Yes, Body is actually RigidBody, I did some changing around in between posts.

This may very well be a general programming query, I can't imagine the Newton library would have a bug in something so trivial (well, I assume Setting and Getting a void* pointer is trivial under the hood anyway).


EDIT: Just a thought, would Newton have any other NewtonBodys behind the scenes, other than the ones I create?

Share this post


Link to post
Share on other sites
Right, I think I'm getting somewhere.

After the Load() function is finished, 'this' is no longer valid?


PhysicsBody->SetGeometry(dynamic_cast<SYM_GEOMETRY*>(this));



So, I need to give SetGeometry() the address of the object in the stl::map, yes?

Here is how I add a model to the scene, minus the Octree stuff:


bool SYM_SCENE::AddModel(string Name, string Filename)
{
//New temp model
SYM_MODEL *TempModel = new SYM_MODEL;

//Load model
if (!TempModel->Load(Name, Filename)) return false;

//Push back to models map
Models.insert(pair<string, SYM_MODEL>(Name, *TempModel));

//Delete temp model
delete TempModel;

return true;
}



Any ideas how I can get around this problem? I was thinking of having the Geometry's physics object public, and call SetGeometry in the above AddModel function after retrieving a pointer to the object in the map, but I'd rather have the geometry set its own physics up.

Share this post


Link to post
Share on other sites
Quote:
Original post by deadstar
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:

*** Source Snippet Removed ***

Retrieving the UserData like this:

*** Source Snippet Removed ***

Trying to access any members in *Geometry causes an access violation.


How is that a "math and physics" question?

Share this post


Link to post
Share on other sites
Quote:
Original post by Dmytry
How is that a "math and physics" question?


I thought it was a Newton problem originally, I figured people who used Newton might hang out in a Physics focussed forum.

I've simplified the AddModel function:


//New model
SYM_MODEL Model;

//Load model
if(!Model.Load(Name, Filename)) return false;

//Add to map
Models[Name] = Model;




God knows what I was trying to do previously, what a mess. I think this is still where the problem lies though.

EDIT: Solved. I should have been storing pointers to geometry, not geometry objects themselves in the stl::map. Always something simple...

Thanks for all your help Gage64.

Share this post


Link to post
Share on other sites

This topic is 3491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this