/// <summary>
        ///   Add the collision data for an object.  This involves looking 
        ///   for a physics file that matches the mesh file's name, and 
        ///   loading the information from that file to build collision 
        ///   volumes.
        /// </summary>
        /// <param name="objNode">the object for which we are adding the collision data</param>
        private void AddCollisionObject(Entity modelEntity, SceneNode modelSceneNode,
                                        long oid, string physicsName)
        {
            // Create a set of collision shapes for the object
            List<CollisionShape> shapes = new List<CollisionShape>();
            PhysicsData pd = new PhysicsData();
            PhysicsSerializer ps = new PhysicsSerializer();

            try {
                Stream stream = ResourceManager.FindCommonResourceData(physicsName);
                ps.ImportPhysics(pd, stream);
                for (int i=0; i<modelEntity.SubEntityCount; i++) {
                    SubEntity subEntity = modelEntity.GetSubEntity(i);
                    if (subEntity.IsVisible) {
                        string submeshName = subEntity.SubMesh.Name;
                        List<CollisionShape> subEntityShapes = pd.GetCollisionShapes(submeshName);
                        foreach (CollisionShape subShape in subEntityShapes) {
                            // static objects will be transformed here, but movable objects
                            // are transformed on the fly
                            subShape.Transform(modelSceneNode.DerivedScale,
                                               modelSceneNode.DerivedOrientation,
                                               modelSceneNode.DerivedPosition);
                            shapes.Add(subShape);
                            log.InfoFormat("Added collision shape: {0} for {1}",
                                           subShape, submeshName);
                        }
                    }
                }
            } catch (Exception e) {
                // Unable to load physics data -- use a sphere or no collision data?
                log.WarnFormat("Unable to load physics data: {0}", e);
            }
            foreach (CollisionShape shape in shapes)
                collisionManager.AddCollisionShape(shape, oid);
        }
Exemplo n.º 2
0
        private static void TestPhysics( string srcDir, string dstDir, string name )
        {
            float OneMeter = 1000;
            PhysicsData pd = new PhysicsData();
            Vector3 center = new Vector3( 10 * OneMeter, 1 * OneMeter, 1 * OneMeter );
            Vector3[] obbAxes = new Vector3[ 3 ];
            obbAxes[ 0 ] = new Vector3( 1, 0, -1 );
            obbAxes[ 0 ].Normalize();
            obbAxes[ 1 ] = Vector3.UnitY;
            obbAxes[ 2 ] = new Vector3( 1, 0, 1 );
            obbAxes[ 2 ].Normalize();
            Vector3 obbExtents = new Vector3( 2.5f * OneMeter, 1 * OneMeter, 1 * OneMeter );
            CollisionOBB obb = new CollisionOBB( center, obbAxes, obbExtents );
            pd.AddCollisionShape( "submesh01", obb );
            CollisionAABB aabb = new CollisionAABB( center - obbExtents, center + obbExtents );
            pd.AddCollisionShape( "submesh01", aabb );
            CollisionSphere sphere = new CollisionSphere( center, 2 * OneMeter );
            pd.AddCollisionShape( "submesh01", sphere );
            Vector3 capExtents = new Vector3( -1 * OneMeter, 0, 0 );
            CollisionCapsule capsule = new CollisionCapsule( center + capExtents, center - capExtents, .5f * OneMeter );
            pd.AddCollisionShape( "submesh01", capsule );
            PhysicsSerializer ps = new PhysicsSerializer();
            ps.ExportPhysics( pd, name );

            pd = new PhysicsData();
            ps.ImportPhysics( pd, name );
            foreach( string objectId in pd.GetCollisionObjects() )
            {
                log.InfoFormat( "Collision shapes for: {0}", objectId );
                List<CollisionShape> collisionShapes = pd.GetCollisionShapes( objectId );
                foreach( CollisionShape shape in collisionShapes )
                    log.InfoFormat( "Shape: {0}", shape );
            }
        }
Exemplo n.º 3
0
        /// <summary>
        ///   Add the collision data for an object.  This involves looking 
        ///   for a physics file that matches the mesh file's name, and 
        ///   loading the information from that file to build collision 
        ///   volumes.
        /// </summary>
        /// <param name="objNode">the object for which we are adding the collision data</param>
        public void AddCollisionObject(ObjectNode objNode)
        {
            if (worldManager.CollisionHelper == null)
                return;
            if (!objNode.UseCollisionObject)
                return;
            // Create a set of collision shapes for the object
            List<CollisionShape> shapes = new List<CollisionShape>();
            string meshName = objNode.Entity.Mesh.Name;
            PhysicsData pd = new PhysicsData();
            PhysicsSerializer ps = new PhysicsSerializer();
            bool static_object = true;
            if ((objNode.ObjectType == ObjectNodeType.Npc) ||
                (objNode.ObjectType == ObjectNodeType.User)) {
                static_object = false;
            }

            if (meshName.EndsWith(".mesh")) {
                string physicsName = meshName.Substring(0, meshName.Length - 5) + ".physics";
                try {
                    Stream stream = ResourceManager.FindCommonResourceData(physicsName);
                    ps.ImportPhysics(pd, stream);
                    foreach (SubEntity subEntity in objNode.Entity.SubEntities) {
                        if (subEntity.IsVisible) {
                            string submeshName = subEntity.SubMesh.Name;
                            List<CollisionShape> subEntityShapes = pd.GetCollisionShapes(submeshName);
                            foreach (CollisionShape subShape in subEntityShapes) {
                                // static objects will be transformed here, but movable objects
                                // are transformed on the fly
                                if (static_object)
                                    subShape.Transform(objNode.SceneNode.DerivedScale,
                                                       objNode.SceneNode.DerivedOrientation,
                                                       objNode.SceneNode.DerivedPosition);
                                shapes.Add(subShape);
                                log.DebugFormat("Added collision shape for oid {0}, subShape {1}, subMesh {2}",
                                                objNode.Oid, subShape, submeshName);
                            }
                        }
                    }
                    // Now populate the region volumes
                    foreach (KeyValuePair<string, List<CollisionShape>> entry in pd.CollisionShapes) {
                        string regionName = RegionVolumes.ExtractRegionName(entry.Key);
                        if (regionName != "") {
                            // We must record this region - - must be
                            // a static object
                            Debug.Assert(static_object);
                            List<CollisionShape> subShapes = new List<CollisionShape>();
                            foreach (CollisionShape subShape in entry.Value) {
                                subShape.Transform(objNode.SceneNode.DerivedScale,
                                                   objNode.SceneNode.DerivedOrientation,
                                                   objNode.SceneNode.DerivedPosition);
                                subShapes.Add(subShape);
                            }
                            RegionVolumes.Instance.AddRegionShapes(objNode.Oid, regionName, subShapes);
                        }
                    }
                } catch (Exception) {
                    // Unable to load physics data -- use a sphere or no collision data?
                    log.InfoFormat("Unable to load physics data: {0}", physicsName);
                    //// For now, I'm going to put in spheres.  Later I should do something real.
                    //CollisionShape shape = new CollisionSphere(Vector3.Zero, Client.OneMeter);
                    //if (static_object)
                    //    // static objects will be transformed here, but movable objects
                    //    // are transformed on the fly
                    //    shape.Transform(objNode.SceneNode.DerivedScale,
                    //                    objNode.SceneNode.DerivedOrientation,
                    //                    objNode.SceneNode.DerivedPosition);
                    //shapes.Add(shape);
                }
            }

            if (static_object) {
                foreach (CollisionShape shape in shapes)
                    worldManager.CollisionHelper.AddCollisionShape(shape, objNode.Oid);
                objNode.CollisionShapes = shapes;
            } else {
                MovingObject mo = new MovingObject(worldManager.CollisionHelper);
                foreach (CollisionShape shape in shapes)
                    worldManager.CollisionHelper.AddPartToMovingObject(mo, shape);
                objNode.Collider = mo;
                objNode.Collider.Transform(objNode.SceneNode.DerivedScale,
                                           objNode.SceneNode.DerivedOrientation,
                                           objNode.SceneNode.DerivedPosition);
            }
        }
        /// <summary>
        ///   Return the untransformed collision shapes associated
        ///   with a mesh.  If they are already encached, return them,
        ///   else look for a physics file that matches the mesh
        ///   file's name, and  load the information from that file to
        ///   build the collision shapes.
        /// </summary>
        public List<CollisionShape> FindMeshCollisionShapes(string meshName, Entity entity)
        {
            if (collisionManager == null)
            {
                Axiom.Core.LogManager.Instance.Write("DisplayObject.collisionManager is null!");
                return null;
            }
            List<CollisionShape> shapes;
            if (!WorldEditor.Instance.MeshCollisionShapes.TryGetValue(meshName, out shapes))
            {
                string physicsName = Path.GetFileNameWithoutExtension(meshName) + ".physics";
                // Create a set of collision shapes for the object
                shapes = new List<CollisionShape>();
                PhysicsData pd = new PhysicsData();
                PhysicsSerializer ps = new PhysicsSerializer();

                try
                {
                    Stream stream = ResourceManager.FindCommonResourceData(physicsName);
                    ps.ImportPhysics(pd, stream);
                    for (int i = 0; i < entity.SubEntityCount; i++)
                    {
                        SubEntity subEntity = entity.GetSubEntity(i);
                        if (subEntity.IsVisible)
                        {
                            string submeshName = subEntity.SubMesh.Name;
                            List<CollisionShape> subEntityShapes = pd.GetCollisionShapes(submeshName);
                            foreach (CollisionShape subShape in subEntityShapes)
                            {
                                // Clone the shape, and add to the list of
                                // untransformed shapes
                                shapes.Add(subShape);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    // Unable to load physics data -- use a sphere or no collision data?
                    Axiom.Core.LogManager.Instance.Write("Unable to load physics data: " + e);
                    shapes = new List<CollisionShape>();
                }
                WorldEditor.Instance.MeshCollisionShapes[meshName] = shapes;
            }
            List<CollisionShape> newShapes = new List<CollisionShape>();
            foreach (CollisionShape shape in shapes)
                newShapes.Add(shape.Clone());
            return newShapes;
        }
        public static void ExtractCollisionShapes( Mesh mesh, string path )
        {
            PhysicsData physicsData = null;
            List<string> deleteEm = new List<string>();
            int count = mesh.SubMeshCount;

            for( int i = 0; i < count; i++ )
            {
                SubMesh subMesh = mesh.GetSubMesh( i );
                CollisionShape shape = null;
                string targetName = null;
                bool cv = String.Compare( subMesh.Name.Substring( 0, 5 ), "mvcv_", false ) == 0;
                bool rg = String.Compare( subMesh.Name.Substring( 0, 5 ), "mvrg_", false ) == 0;
                int firstIndex = 0;
                if( cv )
                    firstIndex = 5;
                else if( rg )
                {
                    string rest = subMesh.Name.Substring( 5 );
                    firstIndex = rest.IndexOf( "_" ) + 1 + 5;
                }
                if( cv || rg )
                {
                    // It's probably a collision volume - - check the
                    // shape type to make sure
                    if( String.Compare( subMesh.Name.Substring( firstIndex, 4 ), "obb_", false ) == 0 )
                    {
                        shape = ExtractBox( subMesh );
                    }
                    else if( String.Compare( subMesh.Name.Substring( firstIndex, 5 ), "aabb_", false ) == 0 )
                    {
                        shape = ExtractBox( subMesh );
                    }
                    else if( String.Compare( subMesh.Name.Substring( firstIndex, 7 ), "sphere_", false ) == 0 )
                    {
                        shape = ExtractSphere( subMesh );
                    }
                    else if( String.Compare( subMesh.Name.Substring( firstIndex, 8 ), "capsule_", false ) == 0 )
                    {
                        shape = ExtractCapsule( subMesh );
                    }
                    if( shape != null )
                        targetName = GetTargetSubmesh( mesh, subMesh.Name );
                }
                if( shape != null )
                {
                    deleteEm.Add( subMesh.Name );
                    if( physicsData == null )
                        physicsData = new PhysicsData();
                    physicsData.AddCollisionShape( targetName, shape );
                }
            }
            for( int i = 0; i < deleteEm.Count; i++ )
            {
                mesh.RemoveSubMesh( deleteEm[ i ] );
            }
            if( physicsData != null )
            {
                PhysicsSerializer serializer = new PhysicsSerializer();
                serializer.ExportPhysics( physicsData, path + ".physics" );
            }

            if( DoLog )
                CloseLog();
        }