Пример #1
0
        /// <summary>
        /// Shows the local rotation axes. This method should be properly be moved to the ModelGeo class
        /// </summary>
        /// <param name="m"></param>
        public static void ShowLocalRotAxes(ModelGeo m)
        {
            Vector3 dim = m.Dimensions();
            float sc = 1.1f * Math.Min(Math.Min(dim.X, dim.Y), dim.Z);

            Vector3 p = m.mMatWorld.Translation;
            AddCircle(p, sc, m.mMatWorldNoScale.Right, Color.Red);
            AddCircle(p, sc, m.mMatWorldNoScale.Up, Color.Lime);
            AddCircle(p, sc, m.mMatWorldNoScale.Backward, Color.Blue);
        }
Пример #2
0
        /// <summary>
        /// Draw the model as a wireframe. Currently not functional.
        /// </summary>
        /// <param name="m"></param>
        /// <param name="c"></param>
        static void drawWireFrame(ModelGeo m, Color c)
        {
            ModelMeshPart mp;

            foreach (ModelMesh mesh in m.mModel.Meshes)
            {
                // Prepare to receive the vertices of the model
                v = new VertexPositionColor[mesh.MeshParts[0].NumVertices];
                // Request the vertices
                mesh.MeshParts[0].VertexBuffer.GetData<VertexPositionColor>(v);

                // Get the points and indices used for the lines
                indices = new short[mesh.MeshParts[0].IndexBuffer.IndexCount / 2];
                mesh.MeshParts[0].IndexBuffer.GetData<short>(indices);

                // Place the points and indices in their respective buffer buffer
                VB = new VertexBuffer(thegame.GraphicsDevice, typeof(VertexPositionColor), v.Length, BufferUsage.WriteOnly);
                VB.SetData<VertexPositionColor>(v);
                IB = new IndexBuffer(thegame.GraphicsDevice, typeof(short), indices.Length, BufferUsage.WriteOnly);
                IB.SetData<short>(indices);

                //BEshader.GraphicsDevice.VertexDeclaration = VD;
                BEshader.GraphicsDevice.Indices = IB;
                BEshader.World = m.mMatBones[mesh.ParentBone.Index] * m.mMatWorld;
                BEshader.CurrentTechnique.Passes[0].Apply();

                //BEshader.GraphicsDevice.Vertices[0].SetSource(VB, 0, v.Length * VertexPositionColor.SizeInBytes );

                for (int i = 0; i < mesh.MeshParts.Count; i++)
                {
                    mp = mesh.MeshParts[i];

                    //BEshader.Begin();
                    foreach (EffectPass pass in BEshader.CurrentTechnique.Passes)
                    {
                        //pass.Begin();
                        //BEshader.GraphicsDevice.RenderState.PointSize = 5.0f;
                        BEshader.GraphicsDevice.SetVertexBuffer(VB, mp.VertexOffset);
                        //BEshader.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, mp.BaseVertex, mp.StreamOffset, mp.NumVertices, mp.StartIndex, mp.PrimitiveCount);
                        BEshader.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, mp.StartIndex, mp.VertexOffset, mp.NumVertices, mp.StartIndex, mp.PrimitiveCount);
                        //pass.End();
                    }

                    //BEshader.End();
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Visualizes the BoundingSpheres of a ModelGeo. This method should be properly be moved to the ModelGeo class
        /// </summary>
        /// <param name="m"></param>
        /// <param name="c"></param>
        public static void ShowBoundingSpheres(ModelGeo m, Color c)
        {
            BoundingSphere bs;
            for (int i = 0; i < m.BoundingSpheres.Count; i++)
            {
                bs = m.GetBoundingSphere(i);

                AddSphere(Matrix.CreateScale(bs.Radius) * Matrix.CreateTranslation(bs.Center), c, false);
            }
        }
Пример #4
0
        /// <summary>
        /// Shows the local axes of a model. This method should be properly be moved to the ModelGeo class
        /// </summary>
        /// <param name="m"></param>
        /// <param name="persistent"></param>
        public static void ShowLocalAxes(ModelGeo m)
        {
            Vector3 dim = m.Dimensions();
            float sc = 1.1f * Math.Max(Math.Max(dim.X, dim.Y), dim.Z);

            Vector3 p = m.mMatWorld.Translation;
            AddLine(p, p + sc * m.mMatWorldNoScale.Right, Color.Red, false);
            AddLine(p, p + sc * m.mMatWorldNoScale.Up, Color.Lime, false);
            AddLine(p, p + sc * m.mMatWorldNoScale.Backward, Color.Blue, false);
        }
Пример #5
0
        public static void ShowAABB(ModelGeo m, Color c)
        {
            BoundingBox boundingBox = new BoundingBox();
            Vector3[] vertexs;
            Matrix M;
            ModelMesh mesh;

            //foreach (ModelMesh mesh in m.mModel.Meshes)
            for (int i = 0; i < m.mModel.Meshes.Count; i++)
            {
                mesh = m.mModel.Meshes[i];

                // This is the right matrix to localize the bounding sphere,
                // But it will also squash it accoding the whatever uneven scaling is in the mMatWorld
                M = m.mMatBones[mesh.ParentBone.Index] * m.mMatWorld;

                // Prepare to receive the vertices of the model
                m.GetMeshpartVerticesCOPY(i, 0, out vertexs);
                Vector3.Transform(vertexs, ref M, vertexs);

                // We create a new boundingbox for these vertices and merge with what we have so far
                boundingBox = BoundingBox.CreateFromPoints(vertexs);

                // Now we need only to add the box to the draw list
                LineStrips.Add(new LineStripData(boundingBox.GetCorners(), UnitBoxIndices, c, Matrix.Identity, false));
            }
        }
Пример #6
0
 /// <summary>
 /// Visualizes the BoundingBox of a ModelGeo. This method should be properly be moved to the ModelGeo class
 /// </summary>
 /// <param name="m"></param>
 /// <param name="c"></param>
 public static void ShowBoundingBox(ModelGeo m, Color c)
 {
     LineStrips.Add(new LineStripData(m.BoundingBoxUnscaled.GetCorners(), UnitBoxIndices, c, m.mMatWorld, false));
 }
Пример #7
0
        /// <summary>
        /// Returns true/false based on whether the segment defined by a and b intersects
        /// the model m's bounding spheres.
        /// meshInd report the specific mesh being intersected
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        public static bool IntersectSegmentBSphere(Vector3 a, Vector3 b, ModelGeo m, out int meshInd)
        {
            //BoundingSphere bs;
            float t = 0;
            Vector3 q = Vector3.Zero;
            meshInd = -1;

            Vector3 norm = Vector3.Normalize(b - a);
            for (int i = 0; i < m.BoundingSpheres.Count; i++)
            {
                if (IntersectRaySphere(a, norm, m.GetBoundingSphere(i), ref t, ref q) && t <= (a - b).Length())
                {
                    meshInd = i;
                    CollisionData.NewEvent(i, -1, norm, -norm);
                    //return true;
                }
            }
            //*/

            return CollisionData.Event; // false;
        }
Пример #8
0
        /// <summary>
        /// Returns true/false based on whether the segment defined by a and b intersects
        /// the model m's meshes. meshInd report the specific mesh being intersected
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        public static bool IntersectSegmentMesh(Vector3 a, Vector3 b, ModelGeo m, out int meshInd)
        {
            meshInd = -1;
            int polyIndex = -1;
            int meshPartIndex = -1;

            //return CollisionSegmentMesh(m.mModel, m.mMatWorld, a, b, out meshInd, out meshPartIndex, out polyIndex);
            return CollisionSegmentMesh(-1, m, a, b, out meshInd, out meshPartIndex, out polyIndex);
        }
Пример #9
0
        /// <summary>
        /// Collision between bounding spheres for c1 and c2
        /// Andre Berthiaume, 2008
        /// </summary>
        /// <param name="c1"></param>
        /// <param name="c2"></param>
        /// <returns>True if a collision is detected, false otherwise.</returns>
        private static bool CollisionSphereSphere(ModelGeo c1, ModelGeo c2)
        {
            BoundingSphere c1BoundingSphere, c2BoundingSphere;

            for (int i = 0; i < c1.BoundingSpheres.Count; i++)
            {
                // Check whether the bounding spheres intersect.
                c1BoundingSphere = c1.GetBoundingSphere(i);

                //Monitor.AddMessage("c1: " + c1BoundingSphere.Center);

                for (int j = 0; j < c2.BoundingSpheres.Count; j++)
                {
                    c2BoundingSphere = c2.GetBoundingSphere(j);

                    //Monitor.AddMessage("c2: " + c2BoundingSphere.Center);

                    if (c1BoundingSphere.Intersects(c2BoundingSphere))
                    {
                        //Console.WriteLine("Sphere Sphere col");

                        n1 = c2BoundingSphere.Center - c1BoundingSphere.Center;
                        n2 = -n1;

                        CollisionData.NewEvent(i, j, n1, n2);

                        //return true;
                    }

                    // Comparison Counter (pedagogical value only)
                    mComparisonCounter++;
                }
            }

            return CollisionData.Event;
        }
Пример #10
0
        /// <summary>
        /// Returns wether a models's bounding spheres (of meshes) collides with a terrain
        /// </summary>
        /// <param name="c1"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        private static bool CollisionSphereTerrain(ModelGeo c1, Terrain t)
        {
            BoundingSphere c1BoundingSphere;

            //for (int i = 0; i < c1.mModel.Meshes.Count; i++)
            for (int i = 0; i < c1.BoundingSpheres.Count; i++)
            {
                //c1BoundingSphere = c1.mModel.Meshes[i].BoundingSphere;
                //c1BoundingSphere.Center = Vector3.Transform(c1BoundingSphere.Center, c1.mModel.Bones[i].Transform * c1.mMatWorld);
                //c1BoundingSphere.Radius *= c1.mMaxScale;

                c1BoundingSphere = c1.GetBoundingSphere(i);

                if (c1BoundingSphere.Center.Y - t.GetHeight(c1BoundingSphere.Center) <= c1BoundingSphere.Radius)
                {
                    n2 = t.GetNormal(c1BoundingSphere.Center);
                    n1 = -n2;

                    CollisionData.NewEvent(i, -1, n1, n2);

                    //return true;
                }
            }

            //Console.WriteLine(c2.mModel.Meshes[0].MeshParts[0]. );
            //return false;
            return CollisionData.Event;
        }
Пример #11
0
        /// <summary>
        /// Segment-Mesh collision test, used by the mesh-mesh collision test
        /// Andre Berhtiaume, 2008 
        /// </summary>
        /// <param name="m1"></param>
        /// <param name="segstart"></param>
        /// <param name="segend"></param>
        /// <param name="meshIndex"></param>
        /// <param name="meshPartIndex"></param>
        /// <param name="polyIndex"></param>
        /// <returns></returns>
        private static bool CollisionSegmentMesh(int m1ind, ModelGeo m1, Vector3 segstart, Vector3 segend, out int meshIndex, out int meshPartIndex, out int polyIndex)
        {
            meshIndex = -1;
            polyIndex = -1;
            meshPartIndex = -1;
            float u = 0, v = 0, w = 0, t = 0;
            Vector3 a, b, c;

            Ray meshSpaceRay = new Ray();

            for (int i = 0; i < m1.mModel.Meshes.Count; i++)
            {
                ModelMesh mesh = m1.mModel.Meshes[i];

                Matrix mat = m1.MeshMat(i); //m1.mMatBones[mesh.ParentBone.Index] * m1.mMatWorld;
                Matrix inverseSceneTransform = Matrix.Invert(mat);

                Vector3 rayPosition = Vector3.Transform(segstart, inverseSceneTransform);
                Vector3 rayDirection = Vector3.TransformNormal(Vector3.Normalize(segend - segstart), inverseSceneTransform);
                Vector3 locsegstart = rayPosition;
                Vector3 locsegend = Vector3.Transform(segend, inverseSceneTransform);

                meshSpaceRay.Position = rayPosition;
                meshSpaceRay.Direction = rayDirection;

                //if (mesh.BoundingSphere.Intersects(meshSpaceRay).HasValue == false)
                //{
                //    continue;
                //}

                List<CollisionUtility.collidingPart> collidingParts = new List<CollisionUtility.collidingPart>();

                if (!CollisionUtility.Contains(m1.mModel))
                {
                    CollisionUtility.ModelBoundingInfo.Add(CollisionUtility.CalcBoundingBoxes(m1.mModel));
                }
                else
                {
                    foreach (CollisionUtility.ModelBoundingBoxBuffer mbb in CollisionUtility.modelBoundingInfo)
                    {
                        //Monitor.AddMessage("count " + mbb.MeshList.Count);
                        if (i < mbb.MeshList.Count) // this is a patch: must understand why it's needed
                        {
                            for (int j = 0; j < mbb.MeshList[i].BoundingBoxes.Count; j++)
                            {
                                float? f = meshSpaceRay.Intersects(mbb.MeshList[i].BoundingBoxes[j]);
                                //Monitor.AddMessage("test" + f.HasValue);
                                if (f.HasValue)
                                {
                                    CollisionUtility.collidingPart cp;
                                    cp.MeshIndex = i;
                                    cp.MeshPartIndex = j;
                                    cp.Distance = f.Value;
                                    collidingParts.Add(cp);
                                }
                            }
                        }
                    }
                    //Monitor.AddMessage( "CP count = " + collidingParts.Count);
                    collidingParts.Sort();
                }

                //Monitor.AddMessage("Col part: " + collidingParts.Count);
                if (collidingParts.Count == 0)
                {
                    continue;
                }

                //*
                for (int j = 0; j < collidingParts.Count; j++)
                {
                    CollisionUtility.collidingPart prt = collidingParts[j];

                    ModelMeshPart part = mesh.MeshParts[prt.MeshPartIndex];
                    //*/

                    /*
                    for (int j = 0; j < mesh.MeshParts.Count; j++)
                    {
                        ModelMeshPart part = mesh.MeshParts[j];
                    //*/
                    for (int x = 0; x < part.PrimitiveCount; x++)
                    {
                        a = m1.GetVertex(i, prt.MeshPartIndex, x * 3 + 0);
                        b = m1.GetVertex(i, prt.MeshPartIndex, x * 3 + 1);
                        c = m1.GetVertex(i, prt.MeshPartIndex, x * 3 + 2);

                        if (IntersectSegmentTriangle(locsegstart, locsegend, b, a, c, ref u, ref v, ref w, ref t))
                        {
                            meshIndex = i;
                            meshPartIndex = prt.MeshPartIndex;
                            polyIndex = x;

                            a = Vector3.Transform(a, mat);
                            b = Vector3.Transform(b, mat);
                            c = Vector3.Transform(c, mat);

                            n2 = Vector3.Cross(a - b, c - b);

                            //n2 = Vector3.Transform(n2, transforms[mesh.ParentBone.Index] * sceneTransform);

                            //Console.WriteLine("Test case:");
                            //Monitor.AddMessage( "Event: i1 " + m1ind + "  i2: " + i + "  n1: " + n1 + "  n2: " + n2 );

                            CollisionData.NewEvent(m1ind, i, n1, n2);

                            //Visualize.AddVector( new Vector3(0,2,0), 5* n2, Color.Red);

                            //Monitor.AddMessage("SegmentMesh loop: i1: " + CollisionData.Index1 + "  i2: " + CollisionData.Index2 + "  n1: " + CollisionData.Normal1 + "  n2: " + CollisionData.Normal2);
                        }

                        // Comparison Counter (pedagogical value only)
                        mComparisonCounter++;
                    }
                }
            }

            //return meshIndex != -1 && polyIndex != -1 && meshPartIndex != -1;

            //return true;// Data.ColEvent();

            /*
            if (CollisionData.Event)
                Monitor.AddMessage("SegmentMesh: i1: " + CollisionData.Index1 + "  i2: " + CollisionData.Index2
                                    + "  n1: " + CollisionData.Normal1 + "  n2: " + CollisionData.Normal2);
            //*/

            return CollisionData.Event;
        }
Пример #12
0
        /// <summary>
        /// Returns wether a models's meshes collides with a terrain
        /// </summary>
        /// <param name="m1"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        private static bool CollisionMeshTerrain(ModelGeo m1, Terrain t)
        {
            int meshIndex = -1;
            int polyIndex = -1;
            int meshPartIndex = -1;

            for (int i = 0; i < m1.mModel.Meshes.Count; i++)
            {
                ModelMesh mesh = m1.mModel.Meshes[i];

                for (int j = 0; j < mesh.MeshParts.Count; j++)
                {
                    ModelMeshPart part = mesh.MeshParts[j];

                    for (int x = 0; x < part.PrimitiveCount; x++)
                    {
                        Matrix mat = m1.mMatBones[mesh.ParentBone.Index] * m1.mMatWorld;
                        Vector3 a = Vector3.Transform(m1.GetVertex(i, j, x * 3 + 0), mat);
                        Vector3 b = Vector3.Transform(m1.GetVertex(i, j, x * 3 + 1), mat);
                        Vector3 c = Vector3.Transform(m1.GetVertex(i, j, x * 3 + 2), mat);

                        if (a.Y < t.GetHeight(a) || b.Y < t.GetHeight(b) || c.Y < t.GetHeight(c))
                        {

                            meshIndex = i;
                            meshPartIndex = j;
                            polyIndex = x;

                            n1 = Vector3.Cross((a - b), (c - b));
                            n2 = t.GetNormal(a);

                            CollisionData.NewEvent(i, -1, n1, n2);

                            //return true;
                        }
                    }
                }
            }

            //Console.WriteLine(fClosestPoly);
            //return meshIndex != -1 && polyIndex != -1 && meshPartIndex != -1;
            return CollisionData.Event;
        }
Пример #13
0
        /// <summary>
        /// Mesh-Mesh collision test
        /// Andre Berhtiaume, 2008
        /// </summary>
        /// <param name="m1"></param>
        /// <param name="m2"></param>
        /// <returns>True if a collision is detected, false otherwise.</returns>
        private static bool CollisionMeshMesh(ModelGeo m1, ModelGeo m2)
        {
            int meshIndex = -1;
            int polyIndex = -1;
            int meshPartIndex = -1;

            //Matrix[] transforms = new Matrix[m1.mModel.Bones.Count];
            //m1.mModel.CopyAbsoluteBoneTransformsTo(transforms);

            for (int i = 0; i < m1.mModel.Meshes.Count; i++)
            {
                ModelMesh mesh = m1.mModel.Meshes[i];

                Matrix inverseSceneTransform = Matrix.Invert(m1.mMatBones[mesh.ParentBone.Index] * m1.mMatWorld);

                for (int j = 0; j < mesh.MeshParts.Count; j++)
                {
                    ModelMeshPart part = mesh.MeshParts[j];

                    for (int x = 0; x < part.PrimitiveCount; x++)
                    {
                        Matrix mat = m1.mMatBones[mesh.ParentBone.Index] * m1.mMatWorld;
                        Vector3 a = Vector3.Transform(m1.GetVertex(i, j, x * 3 + 0), mat);
                        Vector3 b = Vector3.Transform(m1.GetVertex(i, j, x * 3 + 1), mat);
                        Vector3 c = Vector3.Transform(m1.GetVertex(i, j, x * 3 + 2), mat);

                        n1 = Vector3.Cross((a - b), (c - b));

                        CollisionSegmentMesh(i, m2, a, b, out meshIndex, out meshPartIndex, out polyIndex);
                        CollisionSegmentMesh(i, m2, b, c, out meshIndex, out meshPartIndex, out polyIndex);
                        CollisionSegmentMesh(i, m2, c, a, out meshIndex, out meshPartIndex, out polyIndex);

                        /*
                        if (CollisionSegmentMesh(m2.mModel, m2.mMatWorld, a, b, out meshIndex, out meshPartIndex, out polyIndex)
                            ||
                            CollisionSegmentMesh(m2.mModel, m2.mMatWorld, b, c, out meshIndex, out meshPartIndex, out polyIndex)
                            ||
                            CollisionSegmentMesh(m2.mModel, m2.mMatWorld, c, a, out meshIndex, out meshPartIndex, out polyIndex))
                        {

                            meshIndex = i;
                            meshPartIndex = j;
                            polyIndex = x;

                            //return true;
                        }
                        //*/
                    }
                }
            }

            //return meshIndex != -1 && polyIndex != -1 && meshPartIndex != -1;
            return CollisionData.Event;
        }
Пример #14
0
        /// <summary>
        /// Bounding sphere-Mesh collision test
        /// Andre Berhtiaume, 2008
        /// </summary>
        /// <param name="m1"></param>
        /// <param name="m2"></param>
        /// <returns>True if a collision is detected, false otherwise.</returns>
        private static bool CollisionMeshBoundingSphere(ModelGeo m1, ModelGeo m2)
        {
            for (int i = 0; i < m2.BoundingSpheres.Count; i++)
            {
                if (CollisionMeshBoundingSphere(m1, i, m2.GetBoundingSphere(i)))
                {
                    return true;
                }
            }

            return false;
        }
Пример #15
0
        /// <summary>
        /// Bounding sphere-Mesh collision test
        /// Andre Berhtiaume, 2008
        /// </summary>
        /// <param name="m1"></param>
        /// <param name="s"></param>
        /// <returns>True if a collision is detected, false otherwise.</returns>
        private static bool CollisionMeshBoundingSphere(ModelGeo m1, int m2ind, BoundingSphere s)
        {
            float t = -1;
            Vector3 q = Vector3.Zero;
            BoundingSphere bs;

            for (int i = 0; i < m1.mModel.Meshes.Count; i++)
            {
                ModelMesh mesh = m1.mModel.Meshes[i];

                Matrix inverseSceneTransform = Matrix.Invert(m1.mMatBones[mesh.ParentBone.Index] * m1.mMatWorld);

                bs = s;
                bs.Center = Vector3.Transform(s.Center, inverseSceneTransform);
                bs.Radius *= 1 / m1.mMinScale;

                //Monitor.AddMessage("center " + bs.Center + "   radius: " + bs.Radius);

                for (int j = 0; j < mesh.MeshParts.Count; j++)
                {
                    ModelMeshPart part = mesh.MeshParts[j];

                    for (int x = 0; x < part.PrimitiveCount; x++)
                    {
                        // Comparison Counter (pedagogical value only
                        mComparisonCounter++;

                        Vector3 a = m1.GetVertex(i, j, x * 3 + 0);
                        Vector3 b = m1.GetVertex(i, j, x * 3 + 1);
                        Vector3 c = m1.GetVertex(i, j, x * 3 + 2);

                        n1 = Vector3.Transform(Vector3.Cross((a - b), (c - b)), m1.mMatWorldRot);

                        if (IntersectRaySphere(a, Vector3.Normalize(b - a), bs, ref t, ref q)
                            && t <= (a - b).Length() //*******************
                            )
                        {
                            //Console.WriteLine("ab t = " + t + "   impact " + q + "from " + a + " and " + b);

                            n2 = Vector3.Transform(q - bs.Center, m1.mMatWorldRot);
                            CollisionData.NewEvent(i, m2ind, n1, n2);
                            //return true;
                        }

                        if (IntersectRaySphere(b, Vector3.Normalize(c - b), bs, ref t, ref q)
                            && t <= (b - c).Length()
                            )
                        {
                            //Console.WriteLine("bc t = " + t + "   impact " + q + "from " + b + " and " + c);
                            n2 = Vector3.Transform(q - bs.Center, m1.mMatWorldRot);
                            CollisionData.NewEvent(i, m2ind, n1, n2);
                            //return true;
                        }

                        if (IntersectRaySphere(c, Vector3.Normalize(a - c), bs, ref t, ref q)
                            && t <= (c - a).Length()
                            )
                        {
                            //Console.WriteLine("ca t = " + t + "   impact " + q + "from " + c + " and " + a);
                            n2 = Vector3.Transform(q - bs.Center, m1.mMatWorldRot);
                            CollisionData.NewEvent(i, m2ind, n1, n2);
                            //return true;
                        }
                        //Monitor.AddMessage("t = " + t);

                    }
                }
            }

            return CollisionData.Event; //false;
        }