Ejemplo n.º 1
0
        private static void AddCgfToWorld(CgfLoader cgf, ref Matrix xform,
                                          Vector3 position, GeoSpace geoSpace)
        {
            s_tempVertices.Clear();

            // traverse nodes
            cgf.TraverseNodes((node, transform) =>
                              NodeHandler(cgf, node, position, transform), ref xform);

            // Add collected vertices as a new mesh.
            geoSpace.AddCollidableMeshToTree(s_tempVertices);
        }
Ejemplo n.º 2
0
        private void DrawCgfInWorld(CgfLoader cgf, ref Matrix xform, Vector3 position, CgfDrawStyle style,
                                    List <VertexPositionColor> vertices,
                                    List <VertexPositionColor> collisionVertices,
                                    List <VertexPositionColor> lineVertices)
        {
            // Collect collidable meshes
            int collisionStart = collisionVertices.Count;

            // traverse nodes
            cgf.TraverseNodes((node, transform)
                              => NodeHandler(cgf, node, position, transform, vertices, collisionVertices, lineVertices, style),
                              ref xform);

            // Add collected vertices as a new mesh.
            m_geoSpace.AddCollidableMeshToTree(collisionVertices, collisionStart, collisionVertices.Count - collisionStart);
        }
Ejemplo n.º 3
0
        // load terrain vertices for collision testing
        public void LoadIntoGeoSpace(GeoSpace geoSpace)
        {
            if (isEmpty)
            {
                return;
            }

            // Rules:
            // - subdivide X & Y to create smaller AABBs for geospace.
            // - remove steep slopes.

            const int subdivide = 8;

            var meshTriangleVertices = new List <Vector3>();

            for (int sectorY = 0; sectorY < width - 1; sectorY += subdivide)
            {
                for (int sectorX = 0; sectorX < width - 1; sectorX += subdivide)
                {
                    meshTriangleVertices.Clear();

                    // can reduce to 2 triangles only if all vertices are the same height and none are removed.
                    // TODO - use a real poly reduction algorithm instead of fixed size.
                    bool optimizationAllowed = true;

                    int endX = Math.Min(width - 1, sectorX + subdivide);
                    int endY = Math.Min(width - 1, sectorY + subdivide);
                    for (int y = sectorY; y < endY; y++)
                    {
                        for (int x = sectorX; x < endX; x++)
                        {
                            var p1 = VertexLookup(x, y);
                            var p2 = VertexLookup(x, y + 1);
                            var p3 = VertexLookup(x + 1, y);
                            var p4 = VertexLookup(x + 1, y + 1);

                            // TODO - replace with a correct slope test.
                            // TODO - test if any maps have unit size other than 2.
                            if (Math.Abs(p1.Z - p2.Z) >= 2 || Math.Abs(p1.Z - p3.Z) >= 2)
                            {
                                optimizationAllowed = false;
                                continue;
                            }

                            meshTriangleVertices.Add(p1);
                            meshTriangleVertices.Add(p3);
                            meshTriangleVertices.Add(p2);

                            meshTriangleVertices.Add(p2);
                            meshTriangleVertices.Add(p4);
                            meshTriangleVertices.Add(p3);
                        }
                    }

                    if (meshTriangleVertices.Count == 0)
                    {
                        continue;
                    }

                    if (optimizationAllowed)
                    {
                        // if all points have the same Z, replace with 2 triangles.
                        if (meshTriangleVertices.All(v => v.Z == meshTriangleVertices[0].Z))
                        {
                            // don't optimize if there is a mix of 3F and non-3F mats, as this would break cutouts.
                            // a mix would be rare, so for simplicity, just don't optimize when 3F is found.
                            bool anyMat3F = false;
                            for (int y = sectorY; y < endY; y++)
                            {
                                for (int x = sectorX; x < endX; x++)
                                {
                                    if (IsCutout(x, y))
                                    {
                                        anyMat3F = true;
                                        goto exitMatCheck;
                                    }
                                }
                            }
exitMatCheck:


                            if (!anyMat3F)
                            {
                                var p1 = VertexLookup(sectorX, sectorY);
                                var p2 = VertexLookup(sectorX, endY);
                                var p3 = VertexLookup(endX, sectorY);
                                var p4 = VertexLookup(endX, endY);

                                if (p1.Z != meshTriangleVertices[0].Z ||
                                    p2.Z != meshTriangleVertices[0].Z ||
                                    p3.Z != meshTriangleVertices[0].Z ||
                                    p4.Z != meshTriangleVertices[0].Z)
                                {
                                    throw new InvalidOperationException("Z mismatch");
                                }

                                meshTriangleVertices.Clear();

                                meshTriangleVertices.Add(p1);
                                meshTriangleVertices.Add(p3);
                                meshTriangleVertices.Add(p2);

                                meshTriangleVertices.Add(p2);
                                meshTriangleVertices.Add(p4);
                                meshTriangleVertices.Add(p3);
                            }
                        }
                    }

                    geoSpace.AddCollidableMeshToTree(meshTriangleVertices);
                }
            }
        }