public void ReadSphere(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData)
        {
            Vector3 scaleDelta = transform.Scale - Vector3.UnitScale;

            if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon)
            {
                log.Error("Scale is not currently supported for sphere shapes");
            }
            float radius = 0;

            foreach (XmlNode childNode in node.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "radius":
                    radius = float.Parse(childNode.InnerText);
                    break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
            Vector3 center = unitConversion * transform.Translation;

            radius *= unitConversion;

            CollisionShape collisionShape = new CollisionSphere(center, radius);

            physicsData.AddCollisionShape(objectId, collisionShape);
        }
        public void ExportPhysics(PhysicsData physicsData, Stream stream)
        {
            XmlDocument document = new XmlDocument();
            XmlNode     node     = Write(document, physicsData);

            document.AppendChild(node);
            document.Save(stream);
        }
        public void ExportPhysics(PhysicsData physicsData, string filename)
        {
            Stream outStream = new FileStream(filename, FileMode.Create);

            try {
                ExportPhysics(physicsData, outStream);
            } finally {
                outStream.Close();
            }
        }
        public void ImportPhysics(PhysicsData physicsData, string filename)
        {
            Stream inStream = new FileStream(filename, FileMode.Open);

            try {
                ImportPhysics(physicsData, inStream);
            } finally {
                inStream.Close();
            }
        }
        public void ReadCapsule(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData)
        {
            Quaternion rot          = MathHelpers.GetRotation(transform);
            Matrix4    tmpTransform = rot.Inverse().ToRotationMatrix() * transform;
            Vector3    scaleDelta   = tmpTransform.Scale - Vector3.UnitScale;

            if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon)
            {
                log.Error("Scale is not currently supported for capsule shapes");
            }
            float height = 0;

            float[] radius      = new float[2];
            Vector3 halfExtents = Vector3.Zero;

            foreach (XmlNode childNode in node.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "height":
                    height = float.Parse(childNode.InnerText);
                    break;

                case "radius": {
                    string[] values = childNode.InnerText.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                    Debug.Assert(values.Length == 2);
                    for (int i = 0; i < 2; ++i)
                    {
                        radius[i] = float.Parse(values[i]);
                    }
                }
                break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
            // We only support capsules where the two radii match
            if (radius[0] != radius[1])
            {
                log.Error("Different radii for capsules are not currently supported");
            }
            Vector3 center     = unitConversion * transform.Translation;
            Vector3 halfExtent = unitConversion * (.5f * height * (rot * Vector3.UnitY));

            radius[0] *= unitConversion;
            radius[1] *= unitConversion;

            CollisionShape collisionShape;

            collisionShape = new CollisionCapsule(center - halfExtent, center + halfExtent, radius[0]);
            physicsData.AddCollisionShape(objectId, collisionShape);
        }
        public XmlNode Write(XmlDocument document, PhysicsData physicsData)
        {
            XmlNode node = document.CreateElement("physics_model");

            foreach (string objectId in physicsData.GetCollisionObjects())
            {
                XmlNode childNode = WriteRigidBody(objectId, document, physicsData);
                node.AppendChild(childNode);
            }
            return(node);
        }
        public XmlNode WriteRigidBody(string objectId, XmlDocument document, PhysicsData physicsData)
        {
            XmlNode      node = document.CreateElement("rigid_body");
            XmlAttribute attr = document.CreateAttribute("sid");

            attr.Value = objectId;
            node.Attributes.Append(attr);

            XmlNode childNode = WriteRigidBody_TechniqueCommon(objectId, document, physicsData);

            node.AppendChild(childNode);

            return(node);
        }
        public void ReadBox(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData)
        {
            Quaternion rot          = MathHelpers.GetRotation(transform);
            Matrix4    tmpTransform = rot.Inverse().ToRotationMatrix() * transform;
            Vector3    scaleDelta   = tmpTransform.Scale - Vector3.UnitScale;

            if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon)
            {
                log.Error("Scale is not currently supported for box shapes");
            }
            Vector3 halfExtents = Vector3.Zero;

            foreach (XmlNode childNode in node.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "half_extents":
                    ReadVector(ref halfExtents, childNode);
                    break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
            Vector3 center = unitConversion * transform.Translation;

            halfExtents *= unitConversion;

            CollisionShape collisionShape;
            float          angle = 0;
            Vector3        axis  = Vector3.Zero;

            rot.ToAngleAxis(ref angle, ref axis);
            // I could build AABB shapes for boxes that are aligned, but then
            // I can't drop instances in the world with arbitrary rotations.
            // Instead, just always use an OBB.
            //if (angle < PhysicsSerializer.RotateEpsilon) {
            //    collisionShape = new CollisionAABB(center - halfExtents, center + halfExtents);
            //} else {
            // TODO: I'm not sure I understand the OBB constructor
            Vector3[] axes = new Vector3[3];
            axes[0]        = rot.XAxis;
            axes[1]        = rot.YAxis;
            axes[2]        = rot.ZAxis;
            collisionShape = new CollisionOBB(center, axes, halfExtents);
            physicsData.AddCollisionShape(objectId, collisionShape);
        }
        public void ReadRigidBody_TechniqueCommon(string objectId, XmlNode node, PhysicsData physicsData)
        {
            foreach (XmlNode childNode in node.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "shape":
                    ReadShape(objectId, childNode, physicsData);
                    break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
        }
        public void ReadPhysicsModel(XmlNode node, PhysicsData physicsData)
        {
            foreach (XmlNode childNode in node.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "rigid_body":
                    ReadRigidBody(childNode, physicsData);
                    break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
        }
        public void ReadRigidBody(XmlNode node, PhysicsData physicsData)
        {
            string objectId = node.Attributes["sid"].Value;

            foreach (XmlNode childNode in node.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "technique_common":
                    ReadRigidBody_TechniqueCommon(objectId, childNode, physicsData);
                    break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
        }
        public void ImportPhysics(PhysicsData physicsData, Stream stream)
        {
            XmlDocument document = new XmlDocument();

            document.Load(stream);
            foreach (XmlNode childNode in document.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "physics_model":
                    ReadPhysicsModel(childNode, physicsData);
                    break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
        }
        public void ReadShape(string objectId, XmlNode node, PhysicsData physicsData)
        {
            List <NamedTransform> transformChain = new List <NamedTransform>();

            foreach (XmlNode childNode in node.ChildNodes)
            {
                switch (childNode.Name)
                {
                case "rotate": {
                    float   angle = 0;
                    Vector3 axis  = Vector3.UnitY;
                    ReadRotate(ref angle, ref axis, childNode);
                    transformChain.Add(new NamedRotateTransform(null, angle, axis));
                }
                break;

                case "scale": {
                    Vector3 scale = Vector3.UnitScale;
                    ReadVector(ref scale, childNode);
                    transformChain.Add(new NamedScaleTransform(null, scale));
                }
                break;

                case "translate": {
                    Vector3 translation = Vector3.Zero;
                    ReadVector(ref translation, childNode);
                    transformChain.Add(new NamedTranslateTransform(null, translation));
                }
                break;

                case "box": {
                    Matrix4 transform = Matrix4.Identity;
                    foreach (NamedTransform t in transformChain)
                    {
                        transform = t.Transform * transform;
                        Debug.Assert(transform != Matrix4.Zero);
                    }
                    ReadBox(objectId, transform, childNode, physicsData);
                }
                break;

                case "sphere": {
                    Matrix4 transform = Matrix4.Identity;
                    foreach (NamedTransform t in transformChain)
                    {
                        transform = t.Transform * transform;
                        Debug.Assert(transform != Matrix4.Zero);
                    }
                    ReadSphere(objectId, transform, childNode, physicsData);
                }
                break;

                case "capsule": {
                    Matrix4 transform = Matrix4.Identity;
                    foreach (NamedTransform t in transformChain)
                    {
                        transform = t.Transform * transform;
                        Debug.Assert(transform != Matrix4.Zero);
                    }
                    ReadCapsule(objectId, transform, childNode, physicsData);
                }
                break;

                default:
                    DebugMessage(childNode);
                    break;
                }
            }
        }
Esempio n. 14
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 );
            }
        }
 public void ReadShape(string objectId, XmlNode node, PhysicsData physicsData)
 {
     List<NamedTransform> transformChain = new List<NamedTransform>();
     foreach (XmlNode childNode in node.ChildNodes) {
         switch (childNode.Name) {
             case "rotate": {
                     float angle = 0;
                     Vector3 axis = Vector3.UnitY;
                     ReadRotate(ref angle, ref axis, childNode);
                     transformChain.Add(new NamedRotateTransform(null, angle, axis));
                 }
                 break;
             case "scale": {
                     Vector3 scale = Vector3.UnitScale;
                     ReadVector(ref scale, childNode);
                     transformChain.Add(new NamedScaleTransform(null, scale));
                 }
                 break;
             case "translate": {
                     Vector3 translation = Vector3.Zero;
                     ReadVector(ref translation, childNode);
                     transformChain.Add(new NamedTranslateTransform(null, translation));
                 }
                 break;
             case "box": {
                     Matrix4 transform = Matrix4.Identity;
                     foreach (NamedTransform t in transformChain) {
                         transform = t.Transform * transform;
                         Debug.Assert(transform != Matrix4.Zero);
                     }
                     ReadBox(objectId, transform, childNode, physicsData);
                 }
                 break;
             case "sphere": {
                     Matrix4 transform = Matrix4.Identity;
                     foreach (NamedTransform t in transformChain) {
                         transform = t.Transform * transform;
                         Debug.Assert(transform != Matrix4.Zero);
                     }
                     ReadSphere(objectId, transform, childNode, physicsData);
                 }
                 break;
             case "capsule": {
                     Matrix4 transform = Matrix4.Identity;
                     foreach (NamedTransform t in transformChain) {
                         transform = t.Transform * transform;
                         Debug.Assert(transform != Matrix4.Zero);
                     }
                     ReadCapsule(objectId, transform, childNode, physicsData);
                 }
                 break;
             default:
                 DebugMessage(childNode);
                 break;
         }
     }
 }
 public void ReadRigidBody_TechniqueCommon(string objectId, XmlNode node, PhysicsData physicsData)
 {
     foreach (XmlNode childNode in node.ChildNodes) {
         switch (childNode.Name) {
             case "shape":
                 ReadShape(objectId, childNode, physicsData);
                 break;
             default:
                 DebugMessage(childNode);
                 break;
         }
     }
 }
        public void ReadBox(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData)
        {
            Quaternion rot = MathHelpers.GetRotation(transform);
            Matrix4 tmpTransform = rot.Inverse().ToRotationMatrix() * transform;
            Vector3 scaleDelta = tmpTransform.Scale - Vector3.UnitScale;
            if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon)
                log.Error("Scale is not currently supported for box shapes");
            Vector3 halfExtents = Vector3.Zero;
            foreach (XmlNode childNode in node.ChildNodes) {
                switch (childNode.Name) {
                    case "half_extents":
                        ReadVector(ref halfExtents, childNode);
                        break;
                    default:
                        DebugMessage(childNode);
                        break;
                }
            }
            Vector3 center = unitConversion * transform.Translation;
            halfExtents *= unitConversion;

            CollisionShape collisionShape;
            float angle = 0;
            Vector3 axis = Vector3.Zero;
            rot.ToAngleAxis(ref angle, ref axis);
            // I could build AABB shapes for boxes that are aligned, but then
            // I can't drop instances in the world with arbitrary rotations.
            // Instead, just always use an OBB.
            //if (angle < PhysicsSerializer.RotateEpsilon) {
            //    collisionShape = new CollisionAABB(center - halfExtents, center + halfExtents);
            //} else {
            // TODO: I'm not sure I understand the OBB constructor
            Vector3[] axes = new Vector3[3];
            axes[0] = rot.XAxis;
            axes[1] = rot.YAxis;
            axes[2] = rot.ZAxis;
            collisionShape = new CollisionOBB(center, axes, halfExtents);
            physicsData.AddCollisionShape(objectId, collisionShape);
        }
        public void ReadSphere(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData)
        {
            Vector3 scaleDelta = transform.Scale - Vector3.UnitScale;
            if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon)
                log.Error("Scale is not currently supported for sphere shapes");
            float radius = 0;
            foreach (XmlNode childNode in node.ChildNodes) {
                switch (childNode.Name) {
                    case "radius":
                        radius = float.Parse(childNode.InnerText);
                        break;
                    default:
                        DebugMessage(childNode);
                        break;
                }
            }
            Vector3 center = unitConversion * transform.Translation;
            radius *= unitConversion;

            CollisionShape collisionShape = new CollisionSphere(center, radius);
            physicsData.AddCollisionShape(objectId, collisionShape);
        }
 public void ReadRigidBody(XmlNode node, PhysicsData physicsData)
 {
     string objectId = node.Attributes["sid"].Value;
     foreach (XmlNode childNode in node.ChildNodes) {
         switch (childNode.Name) {
             case "technique_common":
                 ReadRigidBody_TechniqueCommon(objectId, childNode, physicsData);
                 break;
             default:
                 DebugMessage(childNode);
                 break;
         }
     }
 }
        public void ReadCapsule(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData)
        {
            Quaternion rot = MathHelpers.GetRotation(transform);
            Matrix4 tmpTransform = rot.Inverse().ToRotationMatrix() * transform;
            Vector3 scaleDelta = tmpTransform.Scale - Vector3.UnitScale;
            if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon)
                log.Error("Scale is not currently supported for capsule shapes");
            float height = 0;
            float[] radius = new float[2];
            Vector3 halfExtents = Vector3.Zero;
            foreach (XmlNode childNode in node.ChildNodes) {
                switch (childNode.Name) {
                    case "height":
                        height = float.Parse(childNode.InnerText);
                        break;
                    case "radius": {
                            string[] values = childNode.InnerText.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
                            Debug.Assert(values.Length == 2);
                            for (int i = 0; i < 2; ++i)
                                radius[i] = float.Parse(values[i]);
                        }
                        break;
                    default:
                        DebugMessage(childNode);
                        break;
                }
            }
            // We only support capsules where the two radii match
            if (radius[0] != radius[1])
                log.Error("Different radii for capsules are not currently supported");
            Vector3 center = unitConversion * transform.Translation;
            Vector3 halfExtent = unitConversion * (.5f * height * (rot * Vector3.UnitY));
            radius[0] *= unitConversion;
            radius[1] *= unitConversion;

            CollisionShape collisionShape;
            collisionShape = new CollisionCapsule(center - halfExtent, center + halfExtent, radius[0]);
            physicsData.AddCollisionShape(objectId, collisionShape);
        }
 public void ImportPhysics(PhysicsData physicsData, Stream stream)
 {
     XmlDocument document = new XmlDocument();
     document.Load(stream);
     foreach (XmlNode childNode in document.ChildNodes) {
         switch (childNode.Name) {
             case "physics_model":
                 ReadPhysicsModel(childNode, physicsData);
                 break;
             default:
                 DebugMessage(childNode);
                 break;
         }
     }
 }
 public void ExportPhysics(PhysicsData physicsData, Stream stream)
 {
     XmlDocument document = new XmlDocument();
     XmlNode node = Write(document, physicsData);
     document.AppendChild(node);
     document.Save(stream);
 }
 public void ExportPhysics(PhysicsData physicsData, string filename)
 {
     Stream outStream = new FileStream(filename, FileMode.Create);
     try {
         ExportPhysics(physicsData, outStream);
     } finally {
         outStream.Close();
     }
 }
        public XmlNode WriteRigidBody_TechniqueCommon(string objectId, XmlDocument document, PhysicsData physicsData)
        {
            XmlNode node = document.CreateElement("technique_common");

            List <CollisionShape> collisionShapes = physicsData.GetCollisionShapes(objectId);

            foreach (CollisionShape shape in collisionShapes)
            {
                XmlNode childNode = WriteShape(shape, document);
                node.AppendChild(childNode);
            }

            return(node);
        }
        public XmlNode WriteRigidBody_TechniqueCommon(string objectId, XmlDocument document, PhysicsData physicsData)
        {
            XmlNode node = document.CreateElement("technique_common");

            List<CollisionShape> collisionShapes = physicsData.GetCollisionShapes(objectId);
            foreach (CollisionShape shape in collisionShapes) {
                XmlNode childNode = WriteShape(shape, document);
                node.AppendChild(childNode);
            }

            return node;
        }
        public XmlNode WriteRigidBody(string objectId, XmlDocument document, PhysicsData physicsData)
        {
            XmlNode node = document.CreateElement("rigid_body");
            XmlAttribute attr = document.CreateAttribute("sid");
            attr.Value = objectId;
            node.Attributes.Append(attr);

            XmlNode childNode = WriteRigidBody_TechniqueCommon(objectId, document, physicsData);
            node.AppendChild(childNode);

            return node;
        }
 public XmlNode Write(XmlDocument document, PhysicsData physicsData)
 {
     XmlNode node = document.CreateElement("physics_model");
     foreach (string objectId in physicsData.GetCollisionObjects()) {
         XmlNode childNode = WriteRigidBody(objectId, document, physicsData);
         node.AppendChild(childNode);
     }
     return node;
 }
 public void ImportPhysics(PhysicsData physicsData, string filename)
 {
     Stream inStream = new FileStream(filename, FileMode.Open);
     try {
         ImportPhysics(physicsData, inStream);
     } finally {
         inStream.Close();
     }
 }
        /// <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);
        }
        /// <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);
            }
        }
 public void ReadPhysicsModel(XmlNode node, PhysicsData physicsData)
 {
     foreach (XmlNode childNode in node.ChildNodes) {
         switch (childNode.Name) {
             case "rigid_body":
                 ReadRigidBody(childNode, physicsData);
                 break;
             default:
                 DebugMessage(childNode);
                 break;
         }
     }
 }
        /// <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();
        }