private float?ProcessTriangle(int triangleIndex)
        {
            System.Diagnostics.Debug.Assert((int)m_flags != 0);

            MyTriangle_Vertexes     triangle;
            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];

            m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2);

            Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

            //We dont want backside intersections
            if (((int)(m_flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) &&
                Vector3.Dot(m_line.Direction, calculatedTriangleNormal) > 0)
            {
                return(null);
            }

            Line  lineF    = (Line)m_line;
            float?distance = MyUtils.GetLineTriangleIntersection(ref lineF, ref triangle);

            //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
            if ((distance != null) && ((m_result == null) || (distance.Value < m_result.Value.Distance)))
            {
                //  We need to remember original triangleVertexes coordinates (not transformed by world matrix)
                m_result = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                return(distance.Value);
            }
            return(null);
        }
        private float?ProcessTriangle(int triangleIndex)
        {
            System.Diagnostics.Debug.Assert((int)m_flags != 0);

            MyTriangle_Vertexes     triangle;
            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];

            m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2);

            Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

            //We dont want backside intersections
            if (((int)(m_flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) &&
                Vector3.Dot(m_line.Direction, calculatedTriangleNormal) > 0)
            {
                return(null);
            }

            Line  lineF    = (Line)m_line;
            float?distance = MyUtils.GetLineTriangleIntersection(ref lineF, ref triangle);

            if (distance.HasValue)
            {
                var result = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                m_result.Add(result);
            }

            return(distance);
        }
        IPhysicsMesh CreatePhysicsMesh(MyModel model)
        {
            IPhysicsMesh physicsMesh = new MyPhysicsMesh();

            physicsMesh.SetAABB(model.BoundingBox.Min, model.BoundingBox.Max);


            for (int v = 0; v < model.GetVerticesCount(); v++)
            {
                Vector3 vertex = model.GetVertex(v);
                Vector3 normal = model.GetVertexNormal(v);
                Vector3 tangent = model.GetVertexTangent(v);
                if (model.TexCoords == null)
                    model.LoadTexCoordData();
                Vector2 texCoord = model.TexCoords[v].ToVector2();

                physicsMesh.AddVertex(vertex, normal, tangent, texCoord);
            }

            for (int i = 0; i < model.Indices16.Length; i++)
            {
                physicsMesh.AddIndex(model.Indices16[i]);
            }

            for (int i = 0; i < model.GetMeshList().Count; i++)
            {
                var mesh = model.GetMeshList()[i];
                physicsMesh.AddSectionData(mesh.IndexStart, mesh.TriCount, mesh.Material.Name);
            }

            return physicsMesh;
        }
        //  Return true if object intersects specified sphere.
        //  This method doesn't return exact point of intersection or any additional data.
        //  We don't look for closest intersection - so we stop on first intersection found.
        //  IMPORTANT: Sphere must be in model space, so don't transform it!
        public bool GetIntersectionWithSphere(MyModel model, ref BoundingSphereD sphere)
        {
            //  Check if sphere intersects bounding box of this node
            if (m_boundingBox.Intersects(ref sphere) == false)
            {
                return false;         
            }

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();

            //  Triangles that are directly in this node
            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                if (triangleBoundingBox.Intersects(ref sphere))
                {
                    //  See that we swaped vertex indices!!
                    MyTriangle_Vertexes triangle;
                    MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                    triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                    triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                    triangle.Vertex2 = model.GetVertex(triangleIndices.I1);

                    PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                    if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                    {
                        //  If we found intersection we can stop and dont need to look further
                        return true;
                    }                    
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    if (m_childs[i].GetIntersectionWithSphere(model, ref sphere))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        public void GetTrianglesIntersectingSphere(MyModel model, ref BoundingSphereD sphere, Vector3? referenceNormalVector, float? maxAngle, List<MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            //  Check if sphere intersects bounding box of this node
            //if (m_boundingBox.Contains(sphere) == ContainmentType.Disjoint) return;
            if (m_boundingBox.Intersects(ref sphere) == false) return;

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();

            //  Triangles that are directly in this node
            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                if (retTriangles.Count == maxNeighbourTriangles) return;

                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                if (triangleBoundingBox.Intersects(ref sphere))
                {
                    //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertexes triangle;
                        MyTriangle_Normals triangleNormals;
                        //MyTriangle_Normals triangleTangents;

                        MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                        triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                        triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                        triangle.Vertex2 = model.GetVertex(triangleIndices.I1);
                        triangleNormals.Normal0 = model.GetVertexNormal(triangleIndices.I0);
                        triangleNormals.Normal1 = model.GetVertexNormal(triangleIndices.I2);
                        triangleNormals.Normal2 = model.GetVertexNormal(triangleIndices.I1);
                        /*
                        triangleTangents.Normal0 = model.GetVertexTangent(triangleIndices.I0);
                        triangleTangents.Normal1 = model.GetVertexTangent(triangleIndices.I2);
                        triangleTangents.Normal2 = model.GetVertexTangent(triangleIndices.I1);
                        */
                        PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                        if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                        {
                            Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                            if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                            {
                                MyTriangle_Vertex_Normals retTriangle;
                                retTriangle.Vertices = triangle;
                                retTriangle.Normals = triangleNormals;
                          //      retTriangle.Tangents = triangleTangents;

                                retTriangles.Add(retTriangle);
                            }
                        }
                    }
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    //m_childs[value].GetTrianglesIntersectingSphere(physObject, ref sphere, referenceNormalVector, maxAngle, ignoreTriangleWithIndex, retTriangles, maxNeighbourTriangles);
                    m_childs[i].GetTrianglesIntersectingSphere(model, ref sphere, referenceNormalVector, maxAngle, retTriangles, maxNeighbourTriangles);
                }
            }
        }
        //  Finds intersection between line and model, using octree for speedup the lookup.
        //  Another speedup is, that first we check triangles that are directly in the node and then start
        //  checking node's childs. But only if child node instersection is less than last know min distance.
        MyIntersectionResultLineTriangle? GetIntersectionWithLineRecursive(MyModel model, ref LineD line, double? minDistanceUntilNow)
        {
            //  Check if line intersects bounding box of this node and if distance to bounding box is less then last know min distance
            Line lineF = (Line)line;
            double? distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref lineF, ref m_boundingBox);
            if ((distanceToBoundingBox.HasValue == false) || ((minDistanceUntilNow != null) && (minDistanceUntilNow < distanceToBoundingBox.Value))) return null;

            //  Triangles that are directly in this node
            MyIntersectionResultLineTriangle? foundIntersection = null;

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();
            BoundingBox lineBB = BoundingBox.CreateInvalid();
            lineBB = lineBB.Include(line.From);
            lineBB = lineBB.Include(line.To);

            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                if (triangleBoundingBox.Intersects(ref lineBB))
                {
                    //  See that we swaped vertex indices!!
                    MyTriangle_Vertexes triangle;
                    MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                    triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                    triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                    triangle.Vertex2 = model.GetVertex(triangleIndices.I1);

                    double? distance = MyUtils.GetLineTriangleIntersection(ref lineF, ref triangle);

                    //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
                    if ((distance != null) && ((foundIntersection == null) || (distance.Value < foundIntersection.Value.Distance)))
                    {
                        Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                        //  We need to remember original triangleVertexes coordinates (not transformed by world matrix)
                        foundIntersection = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                    }
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    MyIntersectionResultLineTriangle? childIntersection = m_childs[i].GetIntersectionWithLineRecursive(model, ref line,
                        (foundIntersection == null) ? (double?)null : foundIntersection.Value.Distance);

                    //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
                    foundIntersection = MyIntersectionResultLineTriangle.GetCloserIntersection(ref foundIntersection, ref childIntersection);
                }
            }

            return foundIntersection;
        }
        private static void ExtractModelDataForObj(
            MyModel model,
            Matrix matrix,
            List<Vector3> vertices,
            List<TriangleWithMaterial> triangles,
            List<Vector2> uvs,
            ref Vector2 offsetUV,
            Dictionary<string, MyExportModel.Material> materials,
            ref int currVerticesCount,
            Vector3 colorMaskHSV)
        {
            if (false == model.HasUV)
            {
                model.LoadUV = true;
                model.UnloadData();
                model.LoadData();
            }

            MyExportModel renderModel = new MyExportModel(model);

            int modelVerticesCount = renderModel.GetVerticesCount();

            List<HalfVector2> modelUVs = GetUVsForModel(renderModel, modelVerticesCount);
            Debug.Assert(modelUVs.Count == modelVerticesCount, "wrong UVs for model");
            if (modelUVs.Count != modelVerticesCount)
            {
                return;
            }

            //we need new material for every HSV and texture combination, therefore we need to create new materials for each model
            List<MyExportModel.Material> newModelMaterials = CreateMaterialsForModel(materials, colorMaskHSV, renderModel);

            for (int i = 0; i < modelVerticesCount; ++i)
            {
                vertices.Add(Vector3.Transform(model.GetVertex(i), matrix));
                Vector2 localUV = modelUVs[i].ToVector2()/model.PatternScale + offsetUV;
                uvs.Add(new Vector2(localUV.X, -localUV.Y));
            }

            for (int i = 0; i < renderModel.GetTrianglesCount(); ++i)
            {
                int matID = -1;
                for (int j = 0; j < newModelMaterials.Count; ++j)
                {
                    if (i <= newModelMaterials[j].LastTri)
                    {
                        matID = j;
                        break;
                    }
                }
                Debug.Assert(matID != -1, "Triangle with no material");

                var t = renderModel.GetTriangle(i);
                string materialName = "EmptyMaterial";
                if (matID != -1)
                {
                    materialName = newModelMaterials[matID].Name;
                }
                triangles.Add(new TriangleWithMaterial()
                {
                    triangle = new MyTriangleVertexIndices(t.I0 + 1 + currVerticesCount, t.I1 + 1 + currVerticesCount, t.I2 + 1 + currVerticesCount),
                    material = materialName,
                });
            }
            currVerticesCount += modelVerticesCount;
        }
Beispiel #8
0
        HkShape CreateShape(MyModel model, HkShapeType shapeType)
        {
            switch(shapeType)
            {
                case HkShapeType.Box:
                    Vector3 halfExtents = (model.BoundingBox.Max - model.BoundingBox.Min) / 2;
                    return new HkBoxShape(Vector3.Max(halfExtents - 0.1f, new Vector3(0.05f)), 0.02f);
                    break;

                case HkShapeType.Sphere:
                    return new HkSphereShape(model.BoundingSphere.Radius);
                    break;

                case HkShapeType.ConvexVertices:
                    m_tmpVerts.Clear();
                    for (int i = 0; i < model.GetVerticesCount(); i++)
                    {
                        m_tmpVerts.Add(model.GetVertex(i));
                    }

                    return new HkConvexVerticesShape(m_tmpVerts.GetInternalArray(), m_tmpVerts.Count, true, 0.1f);
                    break;
            }
            throw new InvalidOperationException("This shape is not supported");
        }
Beispiel #9
0
        public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            var            aabb    = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphere;

            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());

            m_overlappedTriangles.Clear();
            if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles))
            {
                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles)
                    {
                        return;
                    }

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (triangleBoundingBox.Intersects(ref sphere))
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;
                            MyTriangle_Normals  triangleNormals;
                            //MyTriangle_Normals triangleTangents;

                            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                            m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2);

                            /*
                             * triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                             * triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                             * triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);
                             */

                            triangleNormals.Normal0 = m_model.GetVertexNormal(triangleIndices.I0);
                            triangleNormals.Normal1 = m_model.GetVertexNormal(triangleIndices.I2);
                            triangleNormals.Normal2 = m_model.GetVertexNormal(triangleIndices.I1);

                            PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                            if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                            {
                                Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                                if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                    ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                                {
                                    MyTriangle_Vertex_Normals retTriangle;
                                    retTriangle.Vertices = triangle;
                                    retTriangle.Normals  = triangleNormals;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }
            }
        }