Page 1 of 1

Converting my project to use the v15.0 BETA. Some problems.

Posted: Fri Feb 18, 2011 2:39 pm
by Spankenstein
I've been upgrading all my projects from XNA 3.1 to XNA 4.0 today and I thought it would be good to update to the latest BETA too.

I've stumbled across a couple of problems and would be grateful for some advice.

1) entity.Tag is now 'string' instead of 'object', why is this? I can no longer store classes in the Tag property :(

2) How do I get the entities from 'INarrowPhasePair'?

I would like to assign material properties to a pair when they are created:

Code: Select all

private void Events_CreatingPair(EntityCollisionInformation info, CollisionEntry entry, INarrowPhasePair pair)

3) How do I find a list of entities that intersect with a shape?

Using:

Code: Select all

            IList<CollisionEntry> entities = Resources.GetCollisionEntryList();
            game.Space.BroadPhase.QueryAccelerator.GetEntries(sphereOfInfluence, entities);
gives me a list of collision entries but I would like a list of entities instead, if possible.

Thank you.

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Fri Feb 18, 2011 8:42 pm
by Norbo
entity.Tag is now 'string' instead of 'object', why is this? I can no longer store classes in the Tag property
There is no reason :) It's been changed back for the next nightly build, thanks for finding that.
How do I get the entities from 'INarrowPhasePair'?
The INarrowPhasePair is created between two CollisionEntries. The EntityCollisionInformation is a subclass of CollisionEntry has an Entity property. In the event parameters, it gives you the 'current' EntityCollisionInformation and a CollisionEntry representing what it hit. You can attempt to cast this to an EntityCollisionInformation. If it succeeds, then you can check its Entity property. If it fails, its not colliding with an entity. It may still be colliding with something that has a Material, though (like a StaticMesh).

This process could be made a little easier before v0.15.0's final release.
I would like to assign material properties to a pair when they are created:
In the current beta, the material properties are recalculated each frame, so setting them on pair creation isn't possible. This, too, may change before the final version goes up.

However, it is still possible to get a similar behavior. The new Material system lets you define relationships between Materials independently from their fallback material properties. Interaction properties for material pairs can be added to the MaterialManager.MaterialInteractions.
How do I find a list of entities that intersect with a shape?
Consulting the equivalent of v0.14.3's entity collision pairs list would probably be the quickest option. All CollisionInformations (which are subclasses of CollisionEntries) have a Pairs property. When it collides with another object, the pair is stored within that list. The list can be scanned and each entry of a pair casted to an EntityCollisionInformation. If it succeeds and it's not the 'current' entity, then it's a colliding entity. This is pretty much the same as v0.14.3 apart from the location of the list and the generalization of collision pairs requiring casting.


As you have already seen, v0.15.0 still has a lot of little issues scattered around in it. There will be many more, and a few large missing pieces too (though those are rapidly being taken care of). If you're willing to stick with it and use v0.15.0 in its early stage, good luck and I appreciate the extra testing :)

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 6:07 am
by Norbo
In the current beta, the material properties are recalculated each frame, so setting them on pair creation isn't possible. This, too, may change before the final version goes up.
It looks like this will actually be changing in the upcoming build. The constraint contained in a pair handler will be responsible for initializing the material properties when the pair is first created. Then, just like in v0.14.3, it can be changed by event handlers.

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 2:31 pm
by Spankenstein
The EntityCollisionInformation is a subclass of CollisionEntry has an Entity property
Am I right in thinking that the equivalent of ColliderA and ColliderB is as follows:

Code: Select all

        private void Events_CreatingPair(EntityCollisionInformation info, CollisionEntry entry, INarrowPhasePair pair)
        {
            this.Entity     // ColliderA
            info.Entity     // ColliderB
Can I set the material for the pair with the latest beta using:

Code: Select all

            info.Entity.Material.KineticFriction =
            info.Entity.Material.StaticFriction =
In this method?

EDIT:

I'm also having a little trouble with the new RayCasting method. Am I right in thinking that the standard cast will return the closest object hit automatically:

Code: Select all

                if (game.Space.RayCast(new Microsoft.Xna.Framework.Ray(cursorRay.Origin, cursorRay.Direction), 1000.0f, out result))
If so how do I obtain the Entity from the result. Currently, I can't cast the HitObject to an Entity?#

EDIT2:

Matrix3x3 makes life difficult with non extension Transform methods:

Code: Select all

Vector3.TransformNormal(localOffset, Entity.OrientationMatrix) 
Extension methods can be created but are a good deal slower.

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 8:00 pm
by Norbo
Am I right in thinking that the equivalent of ColliderA and ColliderB is as follows:
Yes, although you'd need to cast the CollisionEntry to an EntityCollisionInformation to get its entity, if it is in fact an EntityCollisionInformation. The reason for the abstraction is that it could be colliding with something that isn't an entity, like a StaticMesh, Terrain, InstacedMesh, etc.

However, even some things that are not Entities do have Materials (like StaticMesh, terrain, and InstancedMesh).
Can I set the material for the pair with the latest beta
That approach will change the entity material properties, and in turn re-blend the properties in any pairs associated with the entities. That is not a thread safe procedure, since the pair handling runs in parallel and there could be times when multiple pairs are associated with the same entity.

One better approach would be to use the Material system to define pairwise behaviors before collision pairs are created (using the MaterialManager as explained earlier).

Another approach is to do it the way you did it in v0.14.3. Each pair that cares about materials has a constraint, which contains the blended material properties. Getting at this information is a little tricky at the moment due to the abstractions, but it is theoretically doable. It might be worth waiting on improvements to usability before going this route.
Matrix3x3 makes life difficult with non extension Transform methods:
Here's three ways to deal with this without extension methods:
-The WorldTransform property returns an XNA matrix which can be used with the Vector3.TransformNormal method.
-Matrix3X3 has its own transform methods, though some may be lacking in non-ref parameter overloads at the moment.
-Matrix3X3 has a ToMatrix4X4 static method.

The "fastest" option is to use the Matrix3X3 transform methods, but I wouldn't worry too much about that level of performance optimization when doing game logic.

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 8:02 pm
by Norbo
Woops, missed a question:
Am I right in thinking that the standard cast will return the closest object hit automatically:
Yes.
If so how do I obtain the Entity from the result. Currently, I can't cast the HitObject to an Entity?
The raycast is tested against everything in the broadphase, which means all CollisionEntries in the broadphase. This abstraction allows StaticMeshes and other non-entity things to live in the broadphase. As a side effect, to know if you hit an entity, you'll need to try and convert the hit object to an EntityCollisionInformation.

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 9:35 pm
by Spankenstein
Thanks for the help in making the upgrade easier :)

Do triangle normals have to calculated for each triangle now as I can no longer access the 'LocalNormal' property?

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 9:56 pm
by Norbo
Do triangle normals have to calculated for each triangle now as I can no longer access the 'LocalNormal' property?
Yes. The TriangleShape class (which is a property of the CollisionInformation of a Triangle entity) has some helper methods, like GetNormal and GetLocalNormal. Of course, you can also just do the cross product yourself.

This might be a good time to explain some of the new architecture, since you may find yourself digging through some confusing hierarchies.

The Triangle, Box, Sphere and other Entity subclasses you see in the engine are simply convenience classes put in so that existing codebases wouldn't explode. They are not actually necessary to create an entity. The abstract superclass Entity contains all the dynamic data necessary for simulation; its two immediate children can be used to create Entities without using the prefab types.

The non-abstract subclass Entity<T> : Entity where T : EntityCollisionInformation is the superclass of the prefab types, and can also be constructed directly with EntityCollisionInformations to define its collision behavior. Once constructed, the entity's collision information cannot be changed.

There's another still-unfinished class, MorphableEntity : Entity. This version does not have a generic type; the CollisionInformation property is always of type EntityCollisionInformation. However, the property can be set, allowing an entity to switch its collision information completely after construction.

CollisionInformations are the proxy of the entity in the collision system. As you saw, they are subclasses of CollisionEntry, which live in the BroadPhase. The pairs created from the BroadPhase are handled by the NarrowPhase. The NarrowPhase does different things depending on what type of CollisionEntries compose a given pair.

CollisionInformations have CollisionShapes (but not all CollisionEntries have CollisionShapes). CollisionShapes contain local information only, so you will have to pass in whatever world space information in order to get world space results (like the RigidTransform of the entity to GetNormal). This local-only nature allows them to be shared amongst as many other CollisionInformations as needed. This can help reduce memory usage and startup times quite a bit when used properly.

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 10:48 pm
by Spankenstein
Brilliant, that's got rid of loads more errors. :D

I'm still not understanding your explanation of obtaining a list of entities that intersect with a shape:

Code: Select all

            IList<CollisionEntry> entries = Resources.GetCollisionEntryList();
            game.Space.BroadPhase.QueryAccelerator.GetEntries(sphereOfInfluence, entries);
            int numEntities = entries.Count;
All CollisionInformations (which are subclasses of CollisionEntries) have a Pairs property.
So I have to cast each CollisionEntry to a CollisionInformation class?

Code: Select all

CollisionInformation info = entries[i] as CollisionInformation;
When it collides with another object, the pair is stored within that list. The list can be scanned and each entry of a pair casted to an EntityCollisionInformation. If it succeeds and it's not the 'current' entity, then it's a colliding entity.
I then have to scan each and every pair to see if it is not the original shape inserted and that it can be cast to an Entity class? :!:

EDIT:

Are entities automatically added to the Space now?

I get the following error when trying to add an entity:

Code: Select all

game.Space.Add(entity);
The event creator is managed by a different dispatcher; it cannot be added.

Re: Converting my project to use the v15.0 BETA. Some probl

Posted: Sat Feb 19, 2011 11:26 pm
by Norbo
I'm still not understanding your explanation of obtaining a list of entities that intersect with a shape:
If you only want to know a list of entities intersecting another entity, you don't need to query the broadphase. The CollisionInformation associated with an Entity keeps track of a list of relevant CollisionInformationPairHandlers. If you knew the specific types of the PairHandlers, they have properties for each involved collision information. If you do not know the types, you can use the BroadPhaseOverlap property on the PairHandler. In Beta 17, it's implemented explicitly through the INarrowPhasePair interface, so you'll have to cast to get to it (this is changing in Beta 18 to make it easier).

The BroadPhaseOverlap contains the CollisionEntries which were overlapped. You can try to cast those down to EntityCollisionInformations to see if they were, in fact, entity proxies. If they are, you can use their Entity property.


A separate approach is to query the broadphase, as you have started to do. Then, attempt to cast each CollisionEntry to EntityCollisionInformation. If it is an EntityCollisionInformation, use the Entity property.
I then have to scan each and every pair to see if it is not the original shape inserted and that it can be cast to an Entity class?
No; in the first approach you are only checking an entity's CollisionInformation's pairs list. The things an entity can collide with are not just entities, hence the conversion and testing. But you don't have to check pairs that aren't in the entity's pairs list. The above non-broadphase-query approach is conceptually identical to the old CollisionPairs approach, where you could scan the entity's CollisionPairs list and determine which entities were colliding. It's just that the pairs can contain things which aren't entities sometimes.
Are entities automatically added to the Space now?

I get the following error when trying to add an entity:
No, they are not added automatically. That could be a bug; I'll look into it.