コード例 #1
0
        private void CreateMesh(ParseTree parseTree, ParseTreeNode node, IReadOnlyList <Material> grammarMaterials)
        {
            var submeshes = new List <Tuple <Mesh, int> >();

            foreach (var pair in node.GetLeafNodes(parseTree).Select(n => n.Shape)
                     .GroupBy(p => p.MaterialID, p => p, (key, p) => new { Material = key, GeometricModel = p }))
            {
                var mesh = new Mesh();
                mesh.CombineMeshes(pair.GeometricModel.Select(model => new CombineInstance {
                    mesh      = MeshUtilities.MeshFromGeometricModel(model),
                    transform = MeshUtilities.MatrixFromArray(model.Transform)
                }).ToArray());
                submeshes.Add(Tuple.Create(mesh, pair.Material));
            }
            objectMesh = new Mesh();
            var finalCombine = new List <CombineInstance>();
            var materials    = new List <Material>();

            foreach (var m in submeshes)
            {
                finalCombine.Add(new CombineInstance {
                    mesh = m.Item1, transform = Matrix4x4.identity
                });
                materials.Add(grammarMaterials[m.Item2]);
            }
            objectMesh.CombineMeshes(finalCombine.ToArray(), false);
            MeshFilter.sharedMesh        = objectMesh;
            MeshRenderer.sharedMaterials = materials.ToArray();
            transform.localPosition      = new Vector3(0, 0, 0);
        }
コード例 #2
0
    public static bool IsEarTip(List <Vector3> vertices, List <PolyVertex> pvs, PolyVertex pv)
    {
        if (pv.wasRemoved || !pv.isConvex)
        {
            return(false);
        }

        var prev = pv.prevIndex;
        var curr = pv.currIndex;
        var next = pv.nextIndex;

        var prevVert = vertices[prev];
        var currVert = vertices[curr];
        var nextVert = vertices[next];

        var isEar = true;

        foreach (var p in pvs)
        {
            if (!p.wasRemoved && !p.isConvex && p.currIndex != prev && p.currIndex != curr && p.currIndex != next)
            {
                if (MeshUtilities.IsPointInTriangle(vertices[p.currIndex], prevVert, currVert, nextVert, true, true))
                {
                    isEar = false;
                    break;
                }
            }
        }

        return(isEar);
    }
コード例 #3
0
    public virtual void LoadBlock(MeshData d, WorldGeneration w)
    {
        Vector3 o = worldPosition;

        MeshUtilities.FaceUp(d, o);

        Block n = w.GetBlock(x, y, z + 1);

        if (n == null || !n.isSolid)
        {
            MeshUtilities.FaceNorth(d, o);
        }

        Block s = w.GetBlock(x, y, z - 1);

        if (s == null || !s.isSolid)
        {
            MeshUtilities.FaceSouth(d, o);
        }

        Block we = w.GetBlock(x - 1, y, z);

        if (we == null || !we.isSolid)
        {
            MeshUtilities.FaceWest(d, o);
        }

        Block e = w.GetBlock(x + 1, y, z);

        if (e == null || !e.isSolid)
        {
            MeshUtilities.FaceEast(d, o);
        }
    }
コード例 #4
0
    private void Start()
    {
        // Reorient the transforms if they are not on the diagonal
        // pointing towards the world origin.
        Vector3 min, max;

        min.x = Mathf.Min(minCorner.position.x, maxCorner.position.x);
        min.y = Mathf.Min(minCorner.position.y, maxCorner.position.y);
        min.z = Mathf.Min(minCorner.position.z, maxCorner.position.z);
        max.x = Mathf.Max(minCorner.position.x, maxCorner.position.x);
        max.y = Mathf.Max(minCorner.position.y, maxCorner.position.y);
        max.z = Mathf.Max(minCorner.position.z, maxCorner.position.z);
        minCorner.position = min;
        maxCorner.position = max;

        // Setup the mesh generation.
        int xCuts = Mathf.FloorToInt((max.x - min.x) / detailStep);
        int zCuts = Mathf.FloorToInt((max.z - min.z) / detailStep);

        surfaceMesh = MeshUtilities.GenerateGrid(xCuts, zCuts, detailStep);

        // Assign the generated mesh data and create the mesh components.
        MeshRenderer MR = gameObject.AddComponent <MeshRenderer>();
        MeshFilter   MF = gameObject.AddComponent <MeshFilter>();

        MR.material = fluidMaterial;
        MF.mesh     = surfaceMesh;
        // Make this liquid accessible to other scene objects.
        SceneLiquids.Add(this);
    }
コード例 #5
0
        /// <summary>
        ///   Instantiates new GameObject at the pivot of node specified by id.
        /// </summary>
        /// <param name="nodeId">The node Id from current parse tree.</param>
        /// <returns>Instantiated GameObject.</returns>
        public GameObject AttachGameObjectToNode(uint nodeId)
        {
            var node      = ParseTree[nodeId];
            var newObject = new GameObject();

            newObject.transform.SetParent(transform);
            newObject.transform.position = MeshUtilities.MatrixFromArray(node.Shape.Transform).ExtractPosition();
            return(newObject);
        }
コード例 #6
0
 /// <summary>
 ///   Updates highlights of selected parse tree nodes visible in scene view.
 /// </summary>
 public void UpdateNodeHighlights()
 {
     MeshHighlights = treeViewState.selectedIDs.Where(id => ParseTree[(uint)id].Rule != "ROOT")
                      .Select(id => {
         var node   = ParseTree[(uint)id];
         var matrix = MeshUtilities.MatrixFromArray(node.Shape.Transform);
         return(new MeshGizmoData {
             Position = matrix.ExtractPosition(), Rotation = matrix.ExtractRotation(), Scale = matrix.ExtractScale() + new Vector3(0.05f, 0.05f, 0.05f), Model = node.Shape
         });
     })
                      .ToList();
 }
コード例 #7
0
    /// <summary>
    /// Generates the mesh with low-poly rendering.
    /// </summary>
    public static Mesh SetupFlatMesh(Mesh p_mesh)
    {
        int l_triangleCount = p_mesh.triangles.Length / 3;

        var l_vertices  = new List <Vector3>(p_mesh.vertexCount);
        var l_triangles = new List <int>(l_triangleCount * 3);
        var l_normals   = new List <Vector3>(p_mesh.vertexCount);

        int l_vertexCount = 0;

        for (int i = 0; i < l_triangleCount; i++)
        {
            // Get the three vertices of triangle
            int l_triangleIndex = i * 3;
            int l_vertexIndexA  = p_mesh.triangles[l_triangleIndex];
            int l_vertexIndexB  = p_mesh.triangles[l_triangleIndex + 1];
            int l_vertexIndexC  = p_mesh.triangles[l_triangleIndex + 2];

            Vector3 l_vertexPositionA = p_mesh.vertices[l_vertexIndexA];
            Vector3 l_vertexPositionB = p_mesh.vertices[l_vertexIndexB];
            Vector3 l_vertexPositionC = p_mesh.vertices[l_vertexIndexC];

            //Vertices
            l_vertices.Add(l_vertexPositionA);
            l_vertices.Add(l_vertexPositionB);
            l_vertices.Add(l_vertexPositionC);

            //Triangles
            l_triangles.Add(l_vertexCount++);
            l_triangles.Add(l_vertexCount++);
            l_triangles.Add(l_vertexCount++);

            // Compute a vector perpendicular to the face.
            // NORMAL
            Vector3 l_normal = MeshUtilities.GetNormalFace(l_vertexPositionA, l_vertexPositionB, l_vertexPositionC);
            l_normals.Add(l_normal);
            l_normals.Add(l_normal);
            l_normals.Add(l_normal);
        }
        var l_completeMesh = new Mesh();

        l_completeMesh.vertices  = l_vertices.ToArray();
        l_completeMesh.triangles = l_triangles.ToArray();
        l_completeMesh.normals   = l_normals.ToArray();

        l_completeMesh = MeshUtilities.PerfectUVMesh(l_completeMesh, 1, 1);

        l_completeMesh.RecalculateBounds();
        //save this mesh for next generation
        l_completeMesh.name = "CompleteMesh";
        return(l_completeMesh);
    }
コード例 #8
0
        private void CreateMesh(ParseTree parseTree, IReadOnlyDictionary <int, MaterialModel> materialsDictionary)
        {
            DeleteOldMeshes();

            ParseTreeData.ParseTree = parseTree;
            materials = materialsDictionary.Select(m => MeshUtilities.MaterialFromModel(m.Value)).ToArray();

            var nodes = ParseTree.GetMeshNodes();

            foreach (var node in nodes)
            {
                ParseTreeScript.Construct(transform, ParseTree, node, materials);
            }
        }
コード例 #9
0
    private void ShuffleEdgesAndTurnIntoPolygon()
    {
        var totalEdgeCount  = _edges.Count + _holeEdges.Count;
        var shuffledIndices = new List <int>(capacity: totalEdgeCount);

        for (int i = 0; i < totalEdgeCount; ++i)
        {
            shuffledIndices.Add(i);
        }
        for (int i = 0; i < shuffledIndices.Count - 1; ++i)
        {
            var left  = Random.Range(0, i + 1);
            var right = Random.Range(i + 1, shuffledIndices.Count);

            var tmp = shuffledIndices[left];
            shuffledIndices[left]  = shuffledIndices[right];
            shuffledIndices[right] = tmp;
        }

        var shuffledEdges = new List <Edge>(capacity: totalEdgeCount);

        foreach (var index in shuffledIndices)
        {
            if (index < _edges.Count)
            {
                shuffledEdges.Add(_edges[index]);
            }
            else
            {
                shuffledEdges.Add(_holeEdges[index - _edges.Count]);
            }
        }

        var polys = MeshUtilities.ConnectEdges(shuffledEdges);

        _polyA   = polys[0];
        _aIsHole = false;

        if (polys.Count > 1)
        {
            _polyB = polys[1];

            _aIsHole = MeshUtilities.IsSecondHoleInFirst(_polyB, _polyA);
            _bIsHole = MeshUtilities.IsSecondHoleInFirst(_polyA, _polyB);
        }
    }
コード例 #10
0
        internal MDSubMeshVifBatch(ref int index, ushort nodeIndex, bool isLast, List <VIFPacket> packets)
        {
            SetHeader(ref index, nodeIndex, packets);

            for (int i = 0; i < 31; i++)
            {
                if (BitHelper.IsBitSet(_flags, i))
                {
                    switch (i)
                    {
                    case 21:     // Triangle indices
                        SetTriangleIndices(ref index, packets);
                        break;

                    case 22:     // Vertex Positions
                        SetVertexPositionsAndWeights(ref index, packets);
                        break;

                    case 23:     // Vertex Normals
                        SetVertexNormals(ref index, packets);
                        break;

                    case 24:     // Texture Coordinates
                        if (isLast)
                        {
                            SetTextureCoordinates(ref index, packets);
                        }
                        break;

                    case 25:     // Vertex Colors
                        if (isLast)
                        {
                            SetVertexColors(ref index, packets);
                        }
                        break;
                    }
                }
            }

            // Some meshes don't store normals, so generate average normals in case we want to export it.
            if (_normals == null)
            {
                _normals = MeshUtilities.CalculateAverageNormals(_triangleIndices, _positions);
            }
        }
コード例 #11
0
        protected override Mesh DoProcessing(MeshSqueezerData data)
        {
            Vector3 center = MeshUtilities.GetCenter(data.mesh.Clone().vertices, data.CenterType);
            Mesh    mesh   = data.mesh.Clone();

            Vector3[]  v = (Vector3[])mesh.vertices.Clone();
            Quaternion r = data.Rotation;
            float      f = data.Force;

            for (int i = 0; i < v.Length; i++)
            {
                Vector3 tempPoint = r * (v[i] - center);
                v[i] = (Quaternion.Inverse(r) * new Vector3(tempPoint.x, tempPoint.y * f, tempPoint.z)) + center;
            }

            mesh.vertices = v;
            return(mesh);
        }
コード例 #12
0
    GameObject CreateRing(float radius)
    {
        float innerRadius = .01f;
        int   nbRadSeg    = 80;
        int   nbSides     = 20;

        GameObject result = new GameObject();

        MeshUtilities.AddTorusMeshFilter(result, radius, innerRadius, nbRadSeg, nbSides);

        MeshRenderer renderer = result.AddComponent <MeshRenderer>();

        renderer.enabled = false; // start off hidden

        renderer.material = ringMaterial;

        return(result);
    }
コード例 #13
0
        public Mesh(BXDAMesh.BXDASubMesh mesh, Vector3 position)
        {
            Vector3[] vertData  = MeshUtilities.DataToVector(mesh.verts);
            Vector3[] normsData = MeshUtilities.DataToVector(mesh.norms);
            vertexData = mesh.verts;

            //Translate objects
            for (int i = 0; i < vertexData.Length;)
            {
                vertexData[i++] += position.X;
                vertexData[i++] += position.Y;
                vertexData[i++] += position.Z;
            }

            for (int i = 0; i < vertData.Length; i++)
            {
                vertData[i] *= 0.001f;
            }

            vertices = new List <Vertex>();
            //for(int i = 0; i < vertData.Length; i++)
            //{
            //    Vertex toAdd = new Vertex()
            //    {
            //        position = vertData[i],
            //        normal = normsData[i],
            //        texCoord = new Vector2(0, 0)
            //    };
            //    vertices.Add(toAdd);
            //}
            vertices = vertData.Zip(normsData, (v, n) => new Vertex {
                position = v, normal = n, texCoord = new Vector2(0, 0)
            }).ToList();

            indices = new List <int>();
            mesh.surfaces.ForEach((s) => indices = new List <int>(indices.Concat(s.indicies)));

            IEnumerable <double> temp = vertexData.Zip(indices, (v, i) => vertexData[i]);

            //vertexData = temp.ToArray();

            textures = new List <Texture>();
            setupMesh();
        }
コード例 #14
0
        /// <summary>
        /// Turns a BXDA mesh into a CompoundShape centered around the origin
        /// </summary>
        /// <param name="mesh"></param>
        /// <returns></returns>
        private static CompoundShape GetShape(BXDAMesh mesh)
        {
            CompoundShape shape = new CompoundShape();

            Vector3[] meshVertices = mesh.AllColliderVertices().ToArray();

            for (int i = 0; i < mesh.colliders.Count; i++)
            {
                BXDAMesh.BXDASubMesh  sub      = mesh.colliders[i];
                Vector3[]             vertices = sub.GetVertexData();
                StridingMeshInterface sMesh    = MeshUtilities.CenteredBulletShapeFromSubMesh(sub);

                //Add the shape at a location relative to the compound shape such that the compound shape is centered at (0, 0) but child shapes are properly placed
                shape.AddChildShape(Matrix4.CreateTranslation(MeshUtilities.MeshCenterRelative(sub, mesh)), new ConvexTriangleMeshShape(sMesh));
                Console.WriteLine("Successfully created and added sub shape");
            }

            return(shape);
        }
コード例 #15
0
    /// <summary>
    /// Generates the mesh with smooth rendering.
    /// </summary>
    public static Mesh SetupSmoothMesh(Mesh p_mesh)
    {
        Mesh l_completeMesh = p_mesh;

        int l_vertexCount   = l_completeMesh.vertices.Length;
        int l_triangleCount = l_completeMesh.triangles.Length / 3;

        var l_normals = new Vector3[l_vertexCount];

        Vector3 l_zero = Vector3.zero;

        for (int i = 0; i < l_triangleCount; i++)
        {
            // Get the three vertices of triangle
            int l_triangleIndex = i * 3;
            int l_vertexIndexA  = l_completeMesh.triangles[l_triangleIndex];
            int l_vertexIndexB  = l_completeMesh.triangles[l_triangleIndex + 1];
            int l_vertexIndexC  = l_completeMesh.triangles[l_triangleIndex + 2];

            Vector3 l_vertexPositionA = l_completeMesh.vertices[l_vertexIndexA];
            Vector3 l_vertexPositionB = l_completeMesh.vertices[l_vertexIndexB];
            Vector3 l_vertexPositionC = l_completeMesh.vertices[l_vertexIndexC];

            // Compute a vector perpendicular to the face.
            ////NORMAL
            Vector3 l_normal = MeshUtilities.GetNormalFace(l_vertexPositionA, l_vertexPositionB, l_vertexPositionC);
            if (l_normal.y >= l_zero.y)
            {
                l_normals[l_vertexIndexA] += l_normal;
                l_normals[l_vertexIndexB] += l_normal;
                l_normals[l_vertexIndexC] += l_normal;
            }
        }
        l_completeMesh.normals = l_normals;

        //l_completeMesh = MeshUtilities.PerfectUVMesh(l_completeMesh, 1, 1);

        l_completeMesh.RecalculateBounds();
        //save this mesh for next generation
        l_completeMesh.name = "CompleteMesh";

        return(l_completeMesh);
    }
コード例 #16
0
ファイル: SoftwareRenderer.cs プロジェクト: chargen/AGI-X0
        void recalcFrustum()
        {
            // TODO< transform view frustom mesh by rotation of the camera >

            // we transform a mesh which describes the view frustum in global space
            // and then we calculate the normal and distance of the normal of the planes
            MeshWithExplicitFaces frustumMesh = new MeshWithExplicitFaces();

            { // create a VerticesWithAttributes with just positions
                MutableMeshAttribute positionMeshAttribute = MutableMeshAttribute.makeDouble4ByLength(5);
                var positionAccessor = positionMeshAttribute.getDouble4Accessor();
                positionAccessor[0] = new double[] { -1, -1, 1, 1 };
                positionAccessor[1] = new double[] { 1, -1, 1, 1 };
                positionAccessor[2] = new double[] { 1, 1, 1, 1 };
                positionAccessor[3] = new double[] { -1, 1, 1, 1 };
                positionAccessor[4] = new double[] { 0, 0, 0, 1 };

                VerticesWithAttributes verticesWithAttributes = new VerticesWithAttributes(new AbstractMeshAttribute[] { positionMeshAttribute }, 0);
                frustumMesh.verticesWithAttributes = verticesWithAttributes;
            }

            frustumMesh.faces = new MeshWithExplicitFaces.Face[] {
                new MeshWithExplicitFaces.Face(new uint[] { 4, 0, 1 }), // top side
                new MeshWithExplicitFaces.Face(new uint[] { 4, 1, 2 }), // right side
                new MeshWithExplicitFaces.Face(new uint[] { 4, 2, 3 }), // bottom side
                new MeshWithExplicitFaces.Face(new uint[] { 4, 3, 0 }), // left side
            };

            // TODO< use globally transformed vertices >
            // result is 4 component
            SpatialVectorDouble[] planesWith4Component = MeshUtilities.calcAllPlanes(frustumMesh.faces, frustumMesh.getVertexPositionsAsVector3Array());



            // we only have 4 planes because we dont limit the maximal z
            frustum.planes    = new FrustumPlane[4];
            frustum.planes[0] = FrustumPlane.makeFrom4Component(planesWith4Component[0]);
            frustum.planes[1] = FrustumPlane.makeFrom4Component(planesWith4Component[1]);
            frustum.planes[2] = FrustumPlane.makeFrom4Component(planesWith4Component[2]);
            frustum.planes[3] = FrustumPlane.makeFrom4Component(planesWith4Component[3]);
        }
コード例 #17
0
    private void Start()
    {
        // Reorient the transforms if they are not on the diagonal
        // pointing towards the world origin.
        Vector3 min, max;

        min.x = Mathf.Min(minCorner.position.x, maxCorner.position.x);
        min.y = Mathf.Min(minCorner.position.y, maxCorner.position.y);
        min.z = Mathf.Min(minCorner.position.z, maxCorner.position.z);
        max.x = Mathf.Max(minCorner.position.x, maxCorner.position.x);
        max.y = Mathf.Max(minCorner.position.y, maxCorner.position.y);
        max.z = Mathf.Max(minCorner.position.z, maxCorner.position.z);
        minCorner.position = min;
        maxCorner.position = max;

        // Setup the mesh generation.
        int  xCuts       = Mathf.FloorToInt((max.x - min.x) / detailStep);
        int  zCuts       = Mathf.FloorToInt((max.z - min.z) / detailStep);
        Mesh surfaceMesh = MeshUtilities.GenerateGrid(xCuts, zCuts, detailStep);

        // Add noise to generate the mounds.
        Vector3[] verts = surfaceMesh.vertices;
        for (int i = 0; i < verts.Length; i++)
        {
            // Use perlin noise relative to location.
            verts[i].y = visualTurbulenceMagnitude * Mathf.PerlinNoise(
                verts[i].x * visualTurbulenceStep,
                verts[i].z * visualTurbulenceStep
                );
        }
        surfaceMesh.vertices = verts;

        // Assign the generated mesh data and create the mesh components.
        MeshRenderer MR = gameObject.AddComponent <MeshRenderer>();
        MeshFilter   MF = gameObject.AddComponent <MeshFilter>();

        MR.material = moundMaterial;
        MF.mesh     = surfaceMesh;
    }
コード例 #18
0
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.C) && (Input.GetKey(KeyCode.RightShift) || Input.GetKey(KeyCode.LeftShift)))
        {
            _verticesSetupCount = 0;
            _isTestPointSetup   = false;
        }

        if (Input.GetMouseButtonDown(0))
        {
            if (_verticesSetupCount < 3)
            {
                _testTriangle[_verticesSetupCount++] = GetMousePoint();
            }
        }

        if (Input.GetMouseButton(0) && _verticesSetupCount == 3)
        {
            _testPoint        = GetMousePoint();
            _isTestPointSetup = true;
            _isPointInside    = MeshUtilities.IsPointInTriangle(_testPoint, _testTriangle[0], _testTriangle[1], _testTriangle[2], true, true);
        }
    }
コード例 #19
0
    private void MakeTheCut()
    {
        _hasStartedMarkingTheCut = false;

        var gameObjectsToSlice = CollectSliceables();

        foreach (var go in gameObjectsToSlice)
        {
            var mMaterial = go.GetComponent <MeshRenderer>().sharedMaterial;

            var couldSlice = MeshUtilities.SliceMultiTriangleMesh(go, _cutStartPoint, _cutEndPoint, mMaterial, makePiecesDrop, false);
            if (couldSlice)
            {
                Destroy(go);
            }
            else
            {
                Debug.Log("Couldn't slice");
            }

            _shouldDrawCutNormal = true;
        }
    }
コード例 #20
0
        /// <summary>
        /// Creates a Rigid Body from a .bxda file
        /// </summary>
        /// <param name="FilePath"></param>
        public void CreateRigidBody(string FilePath)
        {
            CollisionShape     shape;
            WheelDriverMeta    wheel = null;
            DefaultMotionState motion;
            BXDAMesh           mesh = new BXDAMesh();

            mesh.ReadFromFile(FilePath);
            Vector3    loc;
            Quaternion rot = Quaternion.Identity;

            //Is it a wheel?
            if ((wheel = GetSkeletalJoint()?.cDriver?.GetInfo <WheelDriverMeta>()) != null && true)
            {
                //Align the cylinders
                Vector3 min, max;
                GetShape(mesh).GetAabb(Matrix4.Identity, out min, out max);
                Vector3 extents = max - min;

                //Find the thinnest dimension, that is probably wheat the cylinder should be aligned to
                if (extents.X < extents.Y) //X or Z
                {
                    if (extents.X < extents.Z)
                    {
                        shape = new CylinderShapeX(wheel.width, wheel.radius, wheel.radius); //X
                    }
                    else
                    {
                        shape = new CylinderShapeZ(wheel.radius, wheel.radius, wheel.width); //Z
                    }
                }
                else //Y or Z
                {
                    if (extents.Y < extents.Z)
                    {
                        shape = new CylinderShape(wheel.radius, wheel.width, wheel.radius); //Y
                    }
                    else
                    {
                        shape = new CylinderShapeZ(wheel.radius, wheel.radius, wheel.width); //Z
                    }
                }

                loc = MeshUtilities.MeshCenter(mesh);
            }
            //Rigid Body Construction
            else
            {
                shape = GetShape(mesh);
                loc   = MeshUtilities.MeshCenter(mesh);
            }

            if (debug)
            {
                Console.WriteLine("Rotation is " + rot);
            }

            motion = new DefaultMotionState(Matrix4.CreateTranslation(loc + new Vector3(0, 100, 0)));
            RigidBodyConstructionInfo info = new RigidBodyConstructionInfo(mesh.physics.mass, motion, shape, shape.CalculateLocalInertia(mesh.physics.mass));

            //Temp?
            info.Friction        = 100;
            info.RollingFriction = 100;
            //info.AngularDamping = 0f;
            //info.LinearDamping = 0.5f;

            BulletObject = new RigidBody(info);
        }
コード例 #21
0
        /// <summary>
        /// Updates Data structures made for Game Objects visibility.
        /// </summary>
        /// <param name="planes"></param>
        /// <param name="allGeoInfos"></param>
        /// <param name="useBounds"></param>
        private List <GeometryDataModels.GeoInfo> UpdateGeometryInfoVisibilities(Plane[] planes,
                                                                                 List <GeometryDataModels.GeoInfo> allGeoInfos, bool useBounds)
        {
            int geoCount    = allGeoInfos.Count;
            int index2      = 0;
            var newGeoInfos = new List <GeometryDataModels.GeoInfo>(allGeoInfos.Count);

            newGeoInfos.AddRange(allGeoInfos);
            this.seenTransforms = new List <Transform>();
            UpdateSeenGeometryObjects();

            // Updates object collection containing geometry and data related to seen object. Usage is to internally update seen geometry objects by checking objects renderer bounds
            // against eyes/cameras frustum
            void UpdateSeenGeometryObjects()
            {
                Transform geoInfoTransform = null;

                for (var i = 0; i < geoCount; i++)
                {
                    var geoInfo = allGeoInfos[i];
                    geoInfoTransform = geoInfo.transform;
                    if (!geoInfoTransform)
                    {
                        continue;
                    }

                    if (useBounds)
                    {
                        AddVisibleRenderer(geoInfo, ref index2);
                    }
                    else if (MeshUtilities.IsInsideFrustum(geoInfoTransform.position, planes))
                    {
                        AddVisibleObject(geoInfo, ref index2);
                    }
                }

                allGeoInfos = newGeoInfos;
                newGeoInfos = null;
            }

            return(newSeenGeometriesList.Take(index2).ToList());

            // Local functions
            void AddVisibleRenderer(GeometryDataModels.GeoInfo geInfo, ref int index)
            {
                if (!geInfo.renderer)
                {
                    newGeoInfos.Remove(geInfo);
                    return;
                }

                if (GeometryUtility.TestPlanesAABB(GeoVision.Planes, geInfo.renderer.bounds))
                {
                    if (GeometryVisionUtilities.TransformIsEffect(geInfo.transform.name))
                    {
                        return;
                    }
                    this.seenTransforms.Add(geInfo.transform);
                    this.newSeenGeometriesList[index] = geInfo;
                    index += 1;
                }
            }

            void AddVisibleObject(GeometryDataModels.GeoInfo geInfo, ref int index)
            {
                if (GeometryVisionUtilities.TransformIsEffect(geInfo.transform.name))
                {
                    return;
                }
                this.seenTransforms.Add(geInfo.transform);
                this.newSeenGeometriesList[index] = geInfo;
                index += 1;
            }
        }
コード例 #22
0
        private void CreateMesh(string filePath)
        {
            Bodies       = new List <RigidBody>();
            VisualMeshes = new List <Mesh>();

            BXDAMesh mesh = new BXDAMesh();

            mesh.ReadFromFile(filePath);

            foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes())
            {
                if (!GetPropertySets().ContainsKey(node.PropertySetID))
                {
                    return;
                }

                PropertySet    current  = GetPropertySets()[node.PropertySetID];
                CollisionShape subShape = null;
                switch (current.Collider.CollisionType)
                {
                case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX:
                {
                    //Create a box shape
                    //This is a mess, though I was told that this is how it works
                    Vector3[]             vertices = MeshUtilities.DataToVector(mesh.meshes[node.SubMeshID].verts);
                    StridingMeshInterface temp = MeshUtilities.BulletShapeFromSubMesh(mesh.meshes[node.SubMeshID]);
                    Vector3 min, max;
                    temp.CalculateAabbBruteForce(out min, out max);

                    PropertySet.BoxCollider colliderInfo = (PropertySet.BoxCollider)current.Collider;
                    subShape = new BoxShape((max - min) * colliderInfo.Scale.Convert() * 0.5f);
                    if (debug)
                    {
                        Console.WriteLine("Created Box");
                    }
                    break;
                }

                case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE:
                {
                    //Create a sphere shape
                    PropertySet.SphereCollider colliderInfo = (PropertySet.SphereCollider)current.Collider;
                    subShape = new SphereShape(colliderInfo.Scale);
                    if (debug)
                    {
                        Console.WriteLine("Created Sphere");
                    }
                    break;
                }

                case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH:
                {
                    //Create a mesh shape
                    if (node.CollisionMeshID == -1)
                    {
                        break;
                    }

                    PropertySet.MeshCollider colliderInfo = (PropertySet.MeshCollider)current.Collider;

                    Vector3[] vertices = MeshUtilities.DataToVector(mesh.colliders[node.CollisionMeshID].verts);

                    if (colliderInfo.Convex)
                    {
                        subShape = new ConvexHullShape(vertices);
                        if (debug)
                        {
                            Console.WriteLine("Created Convex Mesh");
                        }
                    }
                    else
                    {
                        StridingMeshInterface sMesh = MeshUtilities.BulletShapeFromSubMesh(mesh.colliders[node.CollisionMeshID]);
                        subShape = new ConvexTriangleMeshShape(sMesh, true);         //still not really concave
                        if (debug)
                        {
                            Console.WriteLine("Created Concave Mesh");
                        }
                    }
                    break;
                }
                }

                if (null == subShape)
                {
                    return;
                }

                //set sub shape local position/rotation and add it to the compound shape
                Vector3    Translation = node.Position.Convert();
                Quaternion rotation    = node.Rotation.Convert();

                DefaultMotionState motion = new DefaultMotionState(Matrix4.CreateFromQuaternion(rotation) * Matrix4.CreateTranslation(Translation));
                motion.CenterOfMassOffset = Matrix4.CreateTranslation(mesh.physics.centerOfMass.Convert());

                RigidBodyConstructionInfo info = new RigidBodyConstructionInfo(current.Mass, motion, subShape, subShape.CalculateLocalInertia(current.Mass));
                info.Friction = current.Friction;
                Bodies.Add(new RigidBody(info));

                VisualMeshes.Add(new Mesh(mesh.meshes[node.SubMeshID], Translation));
                if (debug)
                {
                    Console.WriteLine("Created " + node.PropertySetID);
                }
            }
        }
コード例 #23
0
ファイル: RWClumpNode.cs プロジェクト: zarroboogs/Amicitia
        public static Assimp.Scene ToAssimpScene(RwClumpNode clumpNode)
        {
            // Scene
            var aiScene = new Assimp.Scene();

            // RootNode
            var rootFrame  = clumpNode.FrameList[0];
            var aiRootNode = new Assimp.Node("RootNode", null);

            aiRootNode.Transform = new Assimp.Matrix4x4(rootFrame.Transform.M11, rootFrame.Transform.M21, rootFrame.Transform.M31, rootFrame.Transform.M41,
                                                        rootFrame.Transform.M12, rootFrame.Transform.M22, rootFrame.Transform.M32, rootFrame.Transform.M42,
                                                        rootFrame.Transform.M13, rootFrame.Transform.M23, rootFrame.Transform.M33, rootFrame.Transform.M43,
                                                        rootFrame.Transform.M14, rootFrame.Transform.M24, rootFrame.Transform.M34, rootFrame.Transform.M44);

            aiScene.RootNode = aiRootNode;

            for (int i = 1; i < clumpNode.FrameList.Count; i++)
            {
                var frame     = clumpNode.FrameList[i];
                var frameName = "_" + frame.HAnimFrameExtensionNode.NameId;

                Assimp.Node aiParentNode = null;
                if (frame.Parent != null)
                {
                    string parentName = "RootNode";
                    if (frame.Parent.HasHAnimExtension)
                    {
                        parentName = "_" + frame.Parent.HAnimFrameExtensionNode.NameId;
                    }

                    aiParentNode = aiRootNode.FindNode(parentName);
                }

                var aiNode = new Assimp.Node(frameName, aiParentNode);
                aiNode.Transform = new Assimp.Matrix4x4(frame.Transform.M11, frame.Transform.M21, frame.Transform.M31, frame.Transform.M41,
                                                        frame.Transform.M12, frame.Transform.M22, frame.Transform.M32, frame.Transform.M42,
                                                        frame.Transform.M13, frame.Transform.M23, frame.Transform.M33, frame.Transform.M43,
                                                        frame.Transform.M14, frame.Transform.M24, frame.Transform.M34, frame.Transform.M44);
                aiParentNode.Children.Add(aiNode);
            }

            // Meshes, Materials
            for (int atomicIndex = 0; atomicIndex < clumpNode.Atomics.Count; atomicIndex++)
            {
                var atomic   = clumpNode.Atomics[atomicIndex];
                var geometry = clumpNode.GeometryList[atomic.GeometryIndex];
                var frame    = clumpNode.FrameList[atomic.FrameIndex];

                var aiNodeName          = $"Atomic{atomicIndex}";
                var aiNode              = new Assimp.Node(aiNodeName, aiScene.RootNode);
                var frameWorldTransform = frame.WorldTransform;
                aiNode.Transform = new Assimp.Matrix4x4(frameWorldTransform.M11, frameWorldTransform.M21, frameWorldTransform.M31, frameWorldTransform.M41,
                                                        frameWorldTransform.M12, frameWorldTransform.M22, frameWorldTransform.M32, frameWorldTransform.M42,
                                                        frameWorldTransform.M13, frameWorldTransform.M23, frameWorldTransform.M33, frameWorldTransform.M43,
                                                        frameWorldTransform.M14, frameWorldTransform.M24, frameWorldTransform.M34, frameWorldTransform.M44);
                aiScene.RootNode.Children.Add(aiNode);

                bool hasVertexWeights = geometry.SkinNode != null;

                for (int meshIndex = 0; meshIndex < geometry.MeshListNode.MaterialMeshes.Length; meshIndex++)
                {
                    var mesh   = geometry.MeshListNode.MaterialMeshes[meshIndex];
                    var aiMesh = new Assimp.Mesh($"Atomic{atomicIndex}_Geometry{atomic.GeometryIndex}_Mesh{meshIndex}", Assimp.PrimitiveType.Triangle);

                    // get triangle list indices
                    int[] indices;

                    if (geometry.MeshListNode.PrimitiveType == RwPrimitiveType.TriangleList)
                    {
                        indices = mesh.Indices;
                    }
                    else
                    {
                        indices = MeshUtilities.ToTriangleList(mesh.Indices, false);
                    }

                    // Faces
                    for (int i = 0; i < indices.Length; i += 3)
                    {
                        var faceIndices = new[] { i, i + 1, i + 2 };
                        var aiFace      = new Assimp.Face(faceIndices);
                        aiMesh.Faces.Add(aiFace);
                    }

                    // TextureCoordinateChannels, VertexColorChannels, Vertices, MaterialIndex, Normals
                    for (int triIdx = 0; triIdx < indices.Length; triIdx += 3)
                    {
                        for (int triVertIdx = 0; triVertIdx < 3; triVertIdx++)
                        {
                            int vertexIndex = indices[triIdx + triVertIdx];

                            // TextureCoordinateChannels
                            if (geometry.HasTextureCoordinates)
                            {
                                for (int channelIdx = 0; channelIdx < geometry.TextureCoordinateChannelCount; channelIdx++)
                                {
                                    var textureCoordinate   = geometry.TextureCoordinateChannels[channelIdx][vertexIndex];
                                    var aiTextureCoordinate = new Assimp.Vector3D(textureCoordinate.X, textureCoordinate.Y, 0f);
                                    aiMesh.TextureCoordinateChannels[channelIdx].Add(aiTextureCoordinate);
                                }
                            }

                            // VertexColorChannels
                            if (geometry.HasColors)
                            {
                                var color   = geometry.Colors[vertexIndex];
                                var aiColor = new Assimp.Color4D(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
                                aiMesh.VertexColorChannels[0].Add(aiColor);
                            }

                            // Vertices
                            if (geometry.HasVertices)
                            {
                                var vertex   = geometry.Vertices[vertexIndex];
                                var aiVertex = new Assimp.Vector3D(vertex.X, vertex.Y, vertex.Z);
                                aiMesh.Vertices.Add(aiVertex);
                            }

                            // Normals
                            if (geometry.HasNormals)
                            {
                                var normal   = geometry.Normals[vertexIndex];
                                var aiNormal = new Assimp.Vector3D(normal.X, normal.Y, normal.Z);
                                aiMesh.Normals.Add(aiNormal);
                            }
                        }
                    }

                    // Bones
                    if (hasVertexWeights)
                    {
                        var skinNode  = geometry.SkinNode;
                        var aiBoneMap = new Dictionary <int, Assimp.Bone>();

                        for (int i = 0; i < indices.Length; i++)
                        {
                            var vertexIndex     = indices[i];
                            int realVertexIndex = i;

                            for (int j = 0; j < 4; j++)
                            {
                                var boneIndex  = skinNode.VertexBoneIndices[vertexIndex][j];
                                var boneWeight = skinNode.VertexBoneWeights[vertexIndex][j];

                                if (boneWeight == 0.0f)
                                {
                                    continue;
                                }

                                if (!aiBoneMap.Keys.Contains(boneIndex))
                                {
                                    var aiBone    = new Assimp.Bone();
                                    var boneFrame = clumpNode.FrameList.GetFrameByHierarchyIndex(boneIndex);

                                    aiBone.Name = boneFrame.HasHAnimExtension ? "_" + boneFrame.HAnimFrameExtensionNode.NameId : "RootNode";
                                    aiBone.VertexWeights.Add(new Assimp.VertexWeight(realVertexIndex, boneWeight));

                                    Matrix4x4.Invert(frame.WorldTransform, out Matrix4x4 invertedFrameWorldTransform);
                                    Matrix4x4.Invert(boneFrame.WorldTransform * invertedFrameWorldTransform, out Matrix4x4 offsetMatrix);
                                    aiBone.OffsetMatrix = new Assimp.Matrix4x4(offsetMatrix.M11, offsetMatrix.M21, offsetMatrix.M31, offsetMatrix.M41,
                                                                               offsetMatrix.M12, offsetMatrix.M22, offsetMatrix.M32, offsetMatrix.M42,
                                                                               offsetMatrix.M13, offsetMatrix.M23, offsetMatrix.M33, offsetMatrix.M43,
                                                                               offsetMatrix.M14, offsetMatrix.M24, offsetMatrix.M34, offsetMatrix.M44);
                                    aiBoneMap[boneIndex] = aiBone;
                                }

                                if (!aiBoneMap[boneIndex].VertexWeights.Any(x => x.VertexID == realVertexIndex))
                                {
                                    aiBoneMap[boneIndex].VertexWeights.Add(new Assimp.VertexWeight(realVertexIndex, boneWeight));
                                }
                            }
                        }

                        aiMesh.Bones.AddRange(aiBoneMap.Values);
                    }
                    else
                    {
                        var aiBone = new Assimp.Bone();

                        // Name
                        aiBone.Name = frame.HasHAnimExtension ? "_" + frame.HAnimFrameExtensionNode.NameId : "RootNode";

                        // VertexWeights
                        for (int i = 0; i < aiMesh.Vertices.Count; i++)
                        {
                            var aiVertexWeight = new Assimp.VertexWeight(i, 1f);
                            aiBone.VertexWeights.Add(aiVertexWeight);
                        }

                        // OffsetMatrix

                        /*
                         * Matrix4x4.Invert( frame.WorldTransform, out Matrix4x4 offsetMatrix );
                         * aiBone.OffsetMatrix = new Assimp.Matrix4x4( offsetMatrix.M11, offsetMatrix.M21, offsetMatrix.M31, offsetMatrix.M41,
                         *                                          offsetMatrix.M12, offsetMatrix.M22, offsetMatrix.M32, offsetMatrix.M42,
                         *                                          offsetMatrix.M13, offsetMatrix.M23, offsetMatrix.M33, offsetMatrix.M43,
                         *                                          offsetMatrix.M14, offsetMatrix.M24, offsetMatrix.M34, offsetMatrix.M44 );
                         */
                        aiBone.OffsetMatrix = Assimp.Matrix4x4.Identity;

                        aiMesh.Bones.Add(aiBone);
                    }

                    var material   = geometry.Materials[mesh.MaterialIndex];
                    var aiMaterial = new Assimp.Material();

                    if (material.IsTextured)
                    {
                        // TextureDiffuse
                        var texture = material.TextureReferenceNode;
                        aiMaterial.TextureDiffuse = new Assimp.TextureSlot(
                            texture.Name + ".png", Assimp.TextureType.Diffuse, 0, Assimp.TextureMapping.FromUV, 0, 0, Assimp.TextureOperation.Add, Assimp.TextureWrapMode.Wrap, Assimp.TextureWrapMode.Wrap, 0);
                    }

                    // Name
                    aiMaterial.Name = material.Name ?? $"Geometry{atomic.GeometryIndex}_Material{mesh.MaterialIndex}";
                    if (material.IsTextured && material.Name == null)
                    {
                        aiMaterial.Name = material.TextureReferenceNode.Name;
                    }

                    aiMaterial.ShadingMode = Assimp.ShadingMode.Phong;

                    // Add mesh to meshes
                    aiScene.Meshes.Add(aiMesh);

                    // Add material to materials
                    aiScene.Materials.Add(aiMaterial);

                    // MaterialIndex
                    aiMesh.MaterialIndex = aiScene.Materials.Count - 1;

                    // Add mesh index to node
                    aiNode.MeshIndices.Add(aiScene.Meshes.Count - 1);
                }
            }

            return(aiScene);
        }
コード例 #24
0
        RayHitDescriptor?traceRayInternal(SpatialVectorDouble rayOrigin, SpatialVectorDouble rayDirection, out bool hit, double maxT = double.MaxValue)
        {
            CollisionDescriptor collisionDescriptor = new CollisionDescriptor();

            foreach (PhysicsComponentAndCollidersPair iPhysicsComponentAndColliders in physicsAndMeshPairs)
            {
                if (ConvexHullRayIntersection.checkRayCollision(rayOrigin, rayDirection, iPhysicsComponentAndColliders.physicsComponent.boundingVolume.convexHull))
                {
                    // iterate over all ColliderComponents and check for collision
                    foreach (ColliderComponent iCollider in iPhysicsComponentAndColliders.colliders)
                    {
                        if (iCollider.isConvex)
                        {
                            SpatialVectorDouble[] convexHullPlanes = MeshUtilities.calcAllPlanes(iCollider.faces, iCollider.transformedVertices);

                            SpatialVectorDouble?hitNormal;
                            double hitTResult;
                            int?   hitFaceNumber;

                            bool isHit = ConvexHullRayIntersection.calcRayCollision(rayOrigin, rayDirection, convexHullPlanes, out hitNormal, out hitTResult, out hitFaceNumber);
                            if (!isHit)
                            {
                                continue;
                            }

                            if (hitTResult < 0.0)
                            {
                                continue;
                            }

                            if (hitTResult > maxT)
                            {
                                continue;
                            }

                            if (collisionDescriptor.rayDistance < hitTResult)
                            {
                                continue;
                            }



                            // store collision information
                            collisionDescriptor.rayDistance = hitTResult;
                            collisionDescriptor.faceIndex   = (uint)hitFaceNumber.Value;
                            collisionDescriptor.faceNormal  = hitNormal.Value;
                            collisionDescriptor.physicsComponentAndCollider = new PhysicsComponentAndCollidersPair(iPhysicsComponentAndColliders.physicsComponent, iCollider);
                            collisionDescriptor.hit = true;
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
            }

            hit = collisionDescriptor.hit;
            if (hit)
            {
                // translate hit informations
                RayHitDescriptor hitDescriptor = new RayHitDescriptor();
                hitDescriptor.hitNormal = collisionDescriptor.faceNormal;
                hitDescriptor.hitPhysicsComponentAndCollider = collisionDescriptor.physicsComponentAndCollider;
                hitDescriptor.hitPosition = rayOrigin + rayDirection.scale(collisionDescriptor.rayDistance);
                return(hitDescriptor);
            }
            else
            {
                return(null);
            }
        }
コード例 #25
0
 public virtual void DoUpdate()
 {
     enabled = false;
     MeshUtilities.MakeTessellatable(moveDistance, subdivideCount, maxPairsToMove);
 }