stilldesign / PhysX.Net

A .NET wrapper for NVIDIA PhysX 4.1.2 written using C++/CLI.
MIT License
206 stars 54 forks source link

I Found Scene.Actors can't be release! #27

Closed wavebbs closed 7 years ago

wavebbs commented 7 years ago

When I call "((RigidStatic)(colliderProxy.Actor)).Dispose();" the ptr of this actor also exist in “Scene.Actors”! When I call "Scene.RemoveActor(colliderProxy.Actor); " the ptr of this actor also exist in “Scene.Actors”! When I call "Scene.RemoveActor(colliderProxy.Actor); ((RigidStatic)(colliderProxy.Actor)).Dispose(); " the ptr of this actor also exist in “Scene.Actors”!

So I don't know How can I do about it? It works OK ? We use this Engine for a Space MMO Game On server side. please help me! thank you :)

wavebbs commented 7 years ago
    public void ActorCollectionOfScene()
        {
            using (var physics = CreatePhysicsAndScene())
            {
                var material = physics.Physics.CreateMaterial(0.2f, 0.3f, 0.1f);
                Assert.AreEqual(0, physics.Scene.Actors.Count());
                var rigidActor1 = physics.Scene.Physics.CreateRigidDynamic();
                Assert.AreEqual(1, physics.Scene.Actors.Count());
                        var rigidActor2 = physics.Scene.Physics.CreateRigidDynamic();
                Assert.AreEqual(2, physics.Scene.Actors.Count());

                        ///remove actor and scene///
                        rigidActor1.Dispose();
                        rigidActor2.Dispose();
                        physics.Scene.Dispose();
                        Assert.AreEqual(2, physics.Scene.Actors.Count());
                        physics.Physics.Dispose();
                        GC.Collect();

                        Assert.AreEqual(2, physics.Scene.Actors.Count());
                        var p = physics.Physics;
                        physics.Dispose();
                        var actorKey = new ObjectTableOwnershipType(p, typeof(PhysX.Actor));
                        IEnumerable<PhysX.Actor> Actors = ObjectTable.GetObjectsOfOwnerAndType<PhysX.Actor>(p);
                        Assert.AreEqual(2, Actors.Count());

                 }

                    Assert.AreEqual(1, ObjectTable.OwnerTypeLookup.Count);
                    Assert.AreEqual(1, ObjectTable.Ownership.Count);
            }

Here is test code , final the ObjectTable not null,and the Scene.Actor.Count still equal 2. I don‘’t know either the actor have already released or not !!

Thank you very much!!!!

stilldesign commented 7 years ago

Thanks for the test, it is indeed a bug.

I believe the issue is in Actor.cpp; The object in question is a RigidActor^, however the object is recorded (added to ObjectTable's dictionary) as Actor^:

ObjectTable::Add<Actor^>((intptr_t)actor, this, owner);

When the RigidActor is disposed, it tries to find it in the dictionary by its type, which now don't match. Passing the type to ObjectTable.Add isn't needed, and the cause of the problem, getting the concrete type of the passed argument should solve this.

wavebbs commented 7 years ago

OK!Maybe I FIxed it. maybe you need change "Type^ type = T::typeid;" to Type TO "type = object->GetType();" on ObjectTable.cpp line 59, otherwise when release actor the type "RigidActor" not found type "Actor".

wavebbs commented 7 years ago

waa , we found it at same time . hoo:)