Page MenuHome

BGE : Fix crash during physics mesh update.
ClosedPublic

Authored by Porteries Tristan (panzergame) on Apr 28 2015, 10:40 PM.

Details

Summary

Currently we can't update the physics mesh of an added rigid body.
The cause is that that we need to update all shapes to say that the mesh was changed, for static object we don't do that previously because we use a odd way to reallocate memory at the same place.
So now when a mesh is changed we iterate all physics controllers which use the same shape info and recreate its shape with the correct mesh.

example file :

Diff Detail

Repository
rB Blender

Event Timeline

I made some tests with an actual Blender build (without your patch), but updating the physics mesh of an added rigid body will work and don't cause a crash on Windows 32 bit.
Please upload your test file.

It would be also fine if you provide your test files for your other patches.

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
2582–2583

0.0f

Your test file is working for me. Still no crash and reinstancePhysicsMesh also works with the current windows 32 bit release build.
But the debug build will crash.

Please, when attaching Blend files that react to user input, tell us how to use it. It makes it so much easier for us to test a patch, when you tell us "press space" or "click on the cube and Blender crashes".

Sybren A. Stüvel (sybren) requested changes to this revision.Apr 30 2015, 3:56 PM

Pressing space while running your blend file makes Blender crash, and this patch fixes that, so that's good. There are a few things to consider, though -- see the inline comments.

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
610

Why is this no longer needed?

671

Same here: why is this no longer needed?

1734

if you're going to rewrite it, just remove /* || spc->GetSoftBody()*/ too -- I doubt that anyone still knows why it was commented out.

2614

m_unscaledShape->getOptimizedBvh() == NULL is changed to m_unscaledShape->getOptimizedBvh(), which means exactly the opposite. Either it's a mistake, or it warrants an explanation.

source/gameengine/Physics/Bullet/CcdPhysicsController.h
549

Please add comments about how "replace" is different from "recreate". Let's make the BGE a well-commented piece of software :)

source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
233

Add a comment that explains what the method does, and in which cases you would call it.

This revision now requires changes to proceed.Apr 30 2015, 3:56 PM
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
610

The old mesh Interface is the new m_triangleIndexVertexArray shared between physics controllers so we can delete the it.

671

We have the same behavior in RefreshCcdPhysicsController, and this loop is totaly wrong because each physics controllers has a unique shape.

1734

It was commented out because (i think) previously we didn't support shape update for softbody, indeed we need a special operation for softbody in ReplaceControllerShape.

2614

Oops i forgot this o.O

Porteries Tristan (panzergame) edited edge metadata.

Add documentation, fix mistake on check and remove useless comments.

Sybren A. Stüvel (sybren) requested changes to this revision.May 1 2015, 5:02 AM
Sybren A. Stüvel (sybren) edited edge metadata.

Just one small nag about the comment, otherwise it looks good to me.

source/gameengine/Physics/Bullet/CcdPhysicsController.h
552

Style: either use:

/* single opening star
 * and closing on this line. */

or use

/**
 * API documentation for Doxygen with two opening stars on their own line
 * and closing on new line.
 */

You may want to capitalize Bullet to emphasize it's the name of the physics system; "bullet shape" is also simply the shape of a bullet.
Also include *why* you should call this method.

This revision now requires changes to proceed.May 1 2015, 5:02 AM
source/gameengine/Physics/Bullet/CcdPhysicsController.h
200

"an indexes", probably a typo. Also include an article ("the" or "a") between "for" and "triangle". Capitalize "Bullet" whenever you refer to the physics engine, and end sentences with a comma.

Mitchell Stokes (moguri) requested changes to this revision.May 3 2015, 8:59 PM
Mitchell Stokes (moguri) edited edge metadata.

The heavy amount of style changes make this patch more difficult to review. While it is good to cleanup the code you touch, be mindful of the amount of noise it adds to a patch. If you're making a lot of style changes, it may be better to have two separate patches.

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
610

The earlier explanation doesn't really seem adequate. Why does this not cause a memory leak? It looks like we can still create GImpact shapes.

2582

Why do we also not use m_triangleIndexVertexArray here?

source/gameengine/Physics/Bullet/CcdPhysicsController.h
555

This interface seems to be getting (more) complicated. What is the difference between Replace and RecreateControllerShape? When should one be called and not the other? Could some of these be made private to make the interface clearer? Also, the "User internally" part of the comment doesn't make much sense. Is it saying what the function calls, or does it say that I need to use DeleteControllerShape, etc. when using this function? If it's the former, it really doesn't need to be in interface documentation, and the line should probably be removed.

This revision now requires changes to proceed.May 3 2015, 8:59 PM
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
610

For gimpact the mesh interface is the triangle vertex array, but this triangle vertex array is shared between gimpact shape and store in CcdShapeConstructionInfo, so free one time line 2661~2.

source/gameengine/Physics/Bullet/CcdPhysicsController.h
555

You need to call RcreateControllerShape when you want to 1) remove and free the current Bullet shape 2) create an new Bullet shape 3) set the new Bullet shape. while ReplaceCOntrollerShape only set the new Bullet shape.

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
610

Is this also not true for TRIANGLE_MESH_SHAPE_PROXYTYPE? If not, we really should have a comment here explaining why we specifically don't handle GIMPACT_SHAPE_PROXYTYPE.

source/gameengine/Physics/Bullet/CcdPhysicsController.h
555

Why does a "recreate" function need to be called to "free" data? Also, your comment really doesn't answer the bulk of the questions/concerns raised in my original comment.

Porteries Tristan (panzergame) edited edge metadata.

Set DeleteControllerShape and ReplaceControllerShape as private function and leave RecreateControllerShape as public, add comments, fix problems with softbody recreate during physics mesh reinstancing.

More inline comments. Also, have you tested the following cases with regular rigid bodies and soft bodies?

  • Dupligroups
  • LibLoading (and freeing)
  • Shared meshes
  • Replace mesh
  • Replace mesh on a shared mesh
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
615

Is this the same memory as m_triangleIndexVertexArray?

686

Do we no longer have to clear collisions? I know we're removing the softbody, but what about any objects currently involved in a collision with a softbody?

1751

I'm thinking this line could be moved to ReplaceControllerShape(). We could have the first argument be optional, and if it is NULL, we can create a btCollisionShape from the m_shapeInfo.

2582

Why does this branch not also use m_triangleIndexVertexArray?

I check with :

  • shared meshes (of course is the goal of this patch)
  • replace shared meshes & replace meshes (also the principal goal)

but not with :

  • libload
  • dupli group

even if i don't see why it can create a bug

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
615

yes, meshInterface is m_triangleIndexVertexArray.

686

see line 683 in CcdPhysicsEnvironement : RefreshCcdPhysicsController
this old code is wrong (we check all rigid bodies with same Bullet shape, but Bullet shape are unique) and do the same work in RefreshCcdPhysicsController.

1751

But the name will be not in harmony with the operation, replace not means create a new shape in certain case. and how we will do for arguments margin, gimpact ect ?

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
686

Okay.

1751

I was thinking of having this in ReplaceControllerShape().

if (newShape == NULL)
    m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft);

It seems to make sense to me to have ReplaceControllerShape(NULL) recreate the existing shape.

2582

This is still unanswered.

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
1751

m_cci is own by CcdPhysicsController not by CcdShapeContrustionInfo.

2582

in the case of softbody we have to use an unique vertex array to be deformed so we can use m_triangleIndexVertexArray which is reserved for sharing Bullet shape. We know that is a softbody when m_weldingThreshold1 is to 1.0f. it's also explicated in DeleteControllerShape.

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
1751

ReplaceControllerShape() is a member function of CcdPhysicsController, not CcdShapeConstructionInfo. Why would CcdShapeConstructionInfo need to access CcdPhysicsController::m_cci?

2597–2600

This branch isn't for soft bodies, but it still doesn't use m_triangleIndexVertexArray.

Porteries Tristan (panzergame) edited edge metadata.

Create new Bullet shape if "newShape" argument is NULL in ReplaceControllerShape.

Tested with libload, libfreea and dupli group.

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
2609

for btScaledBvhTriangleMeshShape we don't use m_triangleIndexVertexArray because we free the shape which contains the triangle vertex array here only during the recreating of m_unscaledShape.
The equivalent way of gimpact shape but with a proxy : the class btBvhTriangleMeshShape.

source/gameengine/Physics/Bullet/CcdPhysicsController.h
554

With the changes to ReplaceControllerShape(), we no longer need this member function. We'll need to make ReplaceControllerShape() public again, and maybe DeleteControllerShape().

Remove function RecreateControllerShape

Remove the binding usage of member variable m_unscaledShape and now m_triangleIndexVertexArray is used for BVH triangle shape and gimpact shape.
It clear a bit the raycast code and the Bullet shape creation (CreateBulletShape). But now during the Bullet shape free (DeleteBulletShape) we have to free the child of the Bullet shape : the old m_unscaleShape.

Mitchell Stokes (moguri) edited edge metadata.

Looks good to me, but I'd like someone more knowledgeable with Bullet to also take a look.

Angus Hollands (agoose77) edited edge metadata.

Besides grammar, looks good to me. However, this does require very careful testing, so I'd like to hear some reports of tests with LibLoad and duplis, or a windows build I can test on, if that's not possible (my build env is currently non functional).

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
603

English:
If we use Bullet scaled shape (btScaledBvhTriangleMeshShape), we have to free the child of the unscaled shape (btTriangleMeshShape) here.

Porteries Tristan (panzergame) edited edge metadata.

fix english in comments

This revision was automatically updated to reflect the committed changes.