Karan
09-06-2009 22:32:34
Hi,
I want to create an actor made of two partly overlapping spheres:
NxOgre::Shapes blobbSpheres;
blobbSpheres.insert(new NxOgre::Sphere(BV3D::BLOBB_SHAPE_DATA[0][1]+0.05)); //lower horizontal radius
blobbSpheres.insert(new NxOgre::Sphere(BV3D::BLOBB_SHAPE_DATA[0][3])); //upper horizontal radius
blobbSpheres[1]->setLocalPose(NxOgre::Matrix44(NxOgre::Real3(0, 0.7, 0)));
NxOgre::RigidBodyDescription rbd;
rbd.mMass = 10.0;
mBody = mApp->mNxRenderSystem->createBody(blobbSpheres, NxOgre::Real3(position.x, position.y, position.z), "Blobb.mesh", rbd);
The problem ist that only one sphere is actually used, and it's always the one inserted second (seen with the visual debugger).
In Bleeding the very similar code I had posted
here worked fine.
My second (unrelated) problem is that after I create an NxOgre::Material via NxOgre::Scene::createMaterial() the member Material::mMaterial is NULL (as I already posted
there.
Any ideas?
Karan
11-06-2009 21:48:45
I think the problem with Shapes is a bug, it also happens with SceneGeometry: (see comments)
NxOgre::Shapes wallPlanes;
wallPlanes.insert(new NxOgre::PlaneGeometry(-arenaExtent.x/2, NxOgre::Real3(1,0,0)));
wallPlanes.insert(new NxOgre::PlaneGeometry(-arenaExtent.x/2, NxOgre::Real3(-1,0,0)));
wallPlanes.insert(new NxOgre::PlaneGeometry(-arenaExtent.z/2, NxOgre::Real3(0,0,1)));
wallPlanes.insert(new NxOgre::PlaneGeometry(-arenaExtent.z/2, NxOgre::Real3(0,0,-1)));
// doesn't work - only last inserted plane is simulated (wallPlanes[3])
//mPhysicsScene->createSceneGeometry(wallPlanes);
// works fine
mPhysicsScene->createSceneGeometry(wallPlanes[0]);
mPhysicsScene->createSceneGeometry(wallPlanes[1]);
mPhysicsScene->createSceneGeometry(wallPlanes[2]);
mPhysicsScene->createSceneGeometry(wallPlanes[3]);
I also looked further into the Material creation problem, and I noted that the created NxMaterial* isn't assigned to mMaterial on NxOgreMaterial.cpp:69 (method Material::create(MaterialPrototype* prototype)). So I changed the line to mMaterial = mScene->getScene()->createMaterial(description);
But it's still NULL after the assignment, so maybe the NxMaterialDesc is invalid or so? The values do look a bit strange in the debugger (e.g. -1.0737418e+008 for the friction and restitution values).
betajaen
11-06-2009 21:59:19
Thanks for the debugging;
I have some free time next week. I'll take a long look at the problem and see if I can come up with a fix (or with the changes to the shapes already perhaps it has).
However if you can come up with why before I do. I'll would appreciate it.
Karan
11-06-2009 22:18:21
Ok, now I found the cause for the material problem: NxOgre::MaterialDescription has no proper constructor (members are not initialized), so the values are "undefined" (and obviously not in the allowed range).
I already looked into the Shapes thing, but your code isn't always easy to understand and so far it looked correct.
betajaen
11-06-2009 23:01:37
Do'h! I see it now.
Internally, the shapes code has changed a little since then, but it should be good to go.
Karan
11-06-2009 23:20:18
I don't know the cause (I don't even understand what the code is supposed to do), but maybe the
Shapes problem manifests here (NxOgreRigidBody.cpp):
void RigidBody::create(RigidBodyPrototype* prototype, Scene* scene)
{
...
...
NxShape*const* shapes = mActor->getShapes();
NxU32 nShapes = mActor->getNbShapes();
while (nShapes--)
{
NxShape* physxShape = shapes[nShapes];
int index = (int) physxShape->userData;
Shape* shape = prototype->mShapes[index];
if (physxShape->getType() == NX_SHAPE_BOX)
{
NxBoxShape* actualShape = physxShape->isBox();
shape->assign(actualShape);
}
else if (physxShape->getType() == NX_SHAPE_SPHERE)
{
NxSphereShape* actualShape = physxShape->isSphere();
shape->assign(actualShape);
}
...
physxShape->userData = NxOgre_New(PhysXPointer)(shape, shape->getClassType(), this);
}
For both of my spheres (see code in first post) the variable
index is 1, so one sphere is assigned twice in the loop. And the iteration seems to be in inverse order, that would explain why only the last shape is simulated.
And by the way, it's spelled "D'oh"
betajaen
11-06-2009 23:43:24
Yeah. That code is a little messed up.
The index is used to identify the shape; it's assigned in the loop above. You see I can't guarantee the order of the NxShapes will match the order of the NxOgre Shapes; due to the user giving invalid shape parameters. So before, I give each NxShape an unique ID which is matched to a Shape. Send the descriptions to PhysX then sort out which shapes were created and those which are not. Looking briefly over the code, I can see at least one error.
Currently; I'm getting 19 errors compiling NxOgre (due to an unrelated problem). Once I've sorted that out, I'll come back and rewrite the code. Perhaps using the PhysXPointer class.
AnTeevY
01-07-2009 21:25:47
Hm, I've got the same problem with creating a material. Is there a working way or do I have to change the NxOgre::MaterialDescription constructor and recompile that? I just want to change the restitution value of the material of my ball's shape.
betajaen
01-07-2009 21:50:42
Sadly, at the moment change the MaterialDescription constructor.
I believe I've fixed it for 1.5.5 - but I wouldn't wait for 1.5.5 to come out, it'll be a few weeks before I've finished it. Implementing BloodyFloor is a pain.
AnTeevY
02-07-2009 15:10:23
Changed the constructor to:
MaterialDescription::MaterialDescription(void) : mDynamicFriction(0), mStaticFriction(0), mRestitution(0),
mVDynamicFriction(0), mVStaticFriction(0), mDirectionOfAnisotropy(NxOgre::Real3(0,0,0)), mFlags(0),
mFrictionCombineMode(Enums::CombineMode::CombineMode_Average), mResitutionCombineMode(Enums::CombineMode::CombineMode_Average)
{
reset();
}
But my programm still crashes. I think the problem is not the MaterialDescription, but the Material itself. The crash occurs if I want to access the mMaterial from NxOgre::Material. It seems that createMaterial() of NxOgre::Scene does not give a NxMaterial to the NxOgre::Material.. So the only way to get a initialized mMaterial is to call the Material::Material(NxMaterial* material, Scene* scene) constructor?
Or am I missing something completely?
Well, if not, I have to create a new NxMaterial with PhysX by myself?
Karan
02-07-2009 17:21:54
As I mentioned earlier in this thread, you've got to assign the created NxMaterial to Material::mMaterial.
AnTeevY
02-07-2009 17:37:22
Meh, thanks, didn't read that. Didn't change anything though, hmmm.. mMaterial is now 0x00000000 when it crashes.
betajaen
02-07-2009 18:34:43
I get that too. I'm working on trying find the problem, then presenting a fix.
Then because of the amount of bugs and errors; I'm going to release 1.5.5 as "unstable" today, and complete the rest of the features I wanted in 1.5.6.
betajaen
02-07-2009 18:50:48
MaterialDescription mat_desc;
mat_desc.mRestitution = 1.0f;
NxOgre::Material* bouncey = mScene->createMaterial(mat_desc);
ShapeBlueprint* sb = new ShapeBlueprint();
sb->mMaterial = bouncey->getIdentifier();
myBody = mRenderSystem->createBody(new NxOgre::Convex(mesh, sb), Vec3(0, 1, 0), "barrel.mesh");
Compiles and Runs. I'll be uploading 1.5.5 in a bit.
AnTeevY
03-07-2009 13:14:56
Works fine now with 1.5.5, thank you!