Exemple #1
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);
            }
        }
        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();
            }
        }