Пример #1
0
        /// <summary>
        /// Gathers all the indices of the surfaces of a submesh
        /// </summary>
        /// <param name="subMesh"></param>
        /// <returns></returns>
        public static IEnumerable <int> GetAllIndices(this BXDAMesh.BXDASubMesh subMesh)
        {
            IEnumerable <int> indices = new List <int>();

            subMesh.surfaces.ForEach((s) => indices = indices.Concat(s.indicies));
            return(indices);
        }
Пример #2
0
    public static void GetCombinedMesh(List <BXDAMesh.BXDASubMesh> meshes, HandleMesh handleMesh)
    {
        BXDAMesh.BXDASubMesh combinedMesh = new BXDAMesh.BXDASubMesh();
        combinedMesh.verts    = new double[0];
        combinedMesh.norms    = new double[0];
        combinedMesh.surfaces = new List <BXDAMesh.BXDASurface>();

        foreach (BXDAMesh.BXDASubMesh mesh in meshes)
        {
            double[] oldVertices = combinedMesh.verts;
            double[] newVertices = new double[oldVertices.Length + mesh.verts.Length];
            oldVertices.CopyTo(newVertices, 0);
            mesh.verts.CopyTo(newVertices, oldVertices.Length);

            combinedMesh.verts = newVertices;

            double[] oldNorms = combinedMesh.verts;
            double[] newNorms = new double[oldNorms.Length + mesh.norms.Length];
            oldNorms.CopyTo(newNorms, 0);
            mesh.norms.CopyTo(newNorms, oldNorms.Length);

            combinedMesh.norms = newNorms;

            combinedMesh.surfaces.AddRange(mesh.surfaces);
        }

        List <BXDAMesh.BXDASubMesh> combinedMeshes = new List <BXDAMesh.BXDASubMesh>();

        combinedMeshes.Add(combinedMesh);

        ReadMeshSet(combinedMeshes, delegate(int id, BXDAMesh.BXDASubMesh subMesh, Mesh mesh)
        {
            handleMesh(id, subMesh, mesh);
        });
    }
    /// <summary>
    /// Used for creating a hull from the given BXDAMesh.BXDASubmesh.
    /// </summary>
    /// <param name="subMesh"></param>
    /// <param name="decompose"></param>
    /// <returns></returns>
    public static BXDAMesh.BXDASubMesh GetHull(BXDAMesh.BXDASubMesh subMesh)
    {
        List <int> indices = new List <int>();

        foreach (BXDAMesh.BXDASurface surface in subMesh.surfaces)
        {
            indices.AddRange(surface.indicies);
        }

        IVHACD decomposer = new IVHACD();

        ConvexLibraryWrapper.Parameters parameters = new ConvexLibraryWrapper.Parameters();

        parameters.m_depth     = 1;
        parameters.m_concavity = 1;

        if (!decomposer.Compute(Array.ConvertAll <double, float>(subMesh.verts, (d) => (float)d),
                                3, (uint)subMesh.verts.Length / 3, indices.ToArray(), 3, (uint)indices.Count / 3, parameters))
        {
            return(null);
        }

        ConvexLibraryWrapper.ConvexHull result = decomposer.GetConvexHull(0);

        BXDAMesh.BXDASubMesh resultMesh = ExportSubMesh(Array.ConvertAll <double, float>(result.m_points, (d) => (float)d), result.m_nPoints,
                                                        Array.ConvertAll <int, uint>(result.m_triangles, (i) => (uint)i), result.m_nTriangles);

        decomposer.Cancel();
        decomposer.Clean();
        decomposer.Release();

        return(resultMesh);
    }
Пример #4
0
        /// <summary>
        /// Gets all of the vertices referenced by the indices of all the surfaces in the mesh.
        /// </summary>
        /// <param name="mesh"></param>
        /// <returns></returns>
        public static Vector3[] GetindexedVertices(this BXDAMesh.BXDASubMesh mesh)
        {
            IEnumerable <int> indices = mesh.GetAllIndices();

            Vector3[] verts = mesh.GetVertexData();
            return((from int i in indices select verts[i]).ToArray());
        }
Пример #5
0
    /// <summary>
    /// Wraps the given raw mesh as a BXDA Submesh with a single surface.
    /// </summary>
    /// <param name="verts">The verticies. (3 elements per vertex)</param>
    /// <param name="vertCount">The vertex count.</param>
    /// <param name="inds">The index buffer.  (3 element per triangle, zero based)</param>
    /// <param name="trisCount">The triangle count</param>
    /// <returns>The resulting mesh</returns>
    private static BXDAMesh.BXDASubMesh ExportSubMesh(float[] verts, uint vertCount, uint[] inds, uint trisCount)
    {
        Simplify(ref verts, ref vertCount, ref inds, ref trisCount);
        BXDAMesh.BXDASubMesh sub = new BXDAMesh.BXDASubMesh();
        sub.norms = null;

        sub.verts = new double[verts.Length];

        for (uint i2 = 0; i2 < vertCount * 3; i2++)
        {
            sub.verts[i2] = verts[i2];
        }

        BXDAMesh.BXDASurface collisionSurface = new BXDAMesh.BXDASurface();

        collisionSurface.indicies = new int[inds.Length];
        for (uint i2 = 0; i2 < trisCount * 3; i2++)
        {
            collisionSurface.indicies[i2] = (int)inds[i2];
        }

        sub.surfaces = new List <BXDAMesh.BXDASurface>();
        sub.surfaces.Add(collisionSurface);

        return(sub);
    }
Пример #6
0
            /// <summary>
            /// Adds the <see cref="outputVerts"/> and <see cref="outputMeshSurfaces"/> to the <see cref="outputMesh"/>.
            /// </summary>
            private void DumpOutputInternal()
            {
                if (outputVerts.count == 0 || outputMeshSurfaces.Count == 0)
                {
                    return;
                }

                // Copy the output surface's vertices and normals into the new sub-object
                BXDAMesh.BXDASubMesh subObject = new BXDAMesh.BXDASubMesh();
                subObject.verts = new double[outputVerts.count * 3];
                subObject.norms = new double[outputVerts.count * 3];
                Array.Copy(outputVerts.coordinates, 0, subObject.verts, 0, outputVerts.count * 3);
                Array.Copy(outputVerts.norms, 0, subObject.norms, 0, outputVerts.count * 3);

                // Copy the output surfaces into the new sub-object
                subObject.surfaces = new List <BXDAMesh.BXDASurface>(outputMeshSurfaces);

                // Add the sub-object to the output mesh
                lock (outputMesh)
                    outputMesh.meshes.Add(subObject);

                // Empty temporary storage
                outputVerts.count = 0;
                outputMeshSurfaces.Clear();
            }
Пример #7
0
    private void DumpMeshBuffer()
    {
        // Make sure all index copy threads have completed.
        if (waitingThreads.Count > 0)
        {
            //   Console.WriteLine("Got ahead of ourselves....");
            System.Threading.WaitHandle.WaitAll(waitingThreads.ToArray());
            waitingThreads.Clear();
        }

        if (postSurface.vertCount == 0 || postSurface.facetCount == 0)
        {
            return;
        }
        BXDAMesh.BXDASubMesh subObject = new BXDAMesh.BXDASubMesh();
        subObject.verts = new double[postSurface.vertCount * 3];
        subObject.norms = new double[postSurface.vertCount * 3];
        Array.Copy(postSurface.verts, 0, subObject.verts, 0, postSurface.vertCount * 3);
        Array.Copy(postSurface.norms, 0, subObject.norms, 0, postSurface.vertCount * 3);
        Console.WriteLine("Mesh segment " + outputMesh.meshes.Count + " has " + postSurface.vertCount + " verts and " + postSurface.facetCount + " facets");
        subObject.surfaces = new List <BXDAMesh.BXDASurface>(postSurfaces);
        outputMesh.meshes.Add(subObject);

        postSurface.vertCount  = 0;
        postSurface.facetCount = 0;
        postSurfaces           = new List <BXDAMesh.BXDASurface>();
    }
Пример #8
0
        /// <summary>
        /// Gets the center of a sub mesh that uses the given vertices
        /// </summary>
        /// <param name="subMesh"></param>
        /// <param name="vertices"></param>
        /// <returns></returns>
        public static Vector3 MeshCenter(BXDAMesh.BXDASubMesh subMesh)
        {
            IEnumerable <int> indices = subMesh.GetAllIndices();

            Vector3[] vertices = subMesh.GetVertexData();
            return((from int i in indices select vertices[i]).Aggregate(Vector3.Add) / indices.Count());
        }
Пример #9
0
        /// <summary>
        /// Returns a bullet mesh centered around the origin
        /// </summary>
        /// <param name="subMesh"></param>
        /// <param name="vertices"></param>
        /// <returns></returns>
        public static StridingMeshInterface CenteredBulletShapeFromSubMesh(BXDAMesh.BXDASubMesh subMesh)
        {
            IEnumerable <int> indices = subMesh.GetAllIndices();

            Vector3[] vertices = subMesh.GetVertexData();

            Vector3 center = MeshCenter(from int i in indices select vertices[i]);

            return(BulletShapeFromSubMesh(subMesh, -center));
        }
Пример #10
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();
        }
Пример #11
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);
        }
Пример #12
0
    public static void ReadMeshSet(List <BXDAMesh.BXDASubMesh> meshes, HandleMesh handleMesh, bool mirror = false)
    {
        for (int j = 0; j < meshes.Count; j++)
        {
            BXDAMesh.BXDASubMesh sub = meshes[j];
            //takes all of the required information from the API (the API information is within "sub" above)
            Vector3[] vertices = sub.verts == null ? null : ArrayUtilities.WrapArray <Vector3>(
                delegate(double x, double y, double z)
            {
                return(new Vector3((float)x * (mirror ? -0.01f : 0.01f), (float)y * 0.01f, (float)z * 0.01f));
            }, sub.verts);
            Vector3[] normals = sub.norms == null ? null : ArrayUtilities.WrapArray <Vector3>(
                delegate(double x, double y, double z)
            {
                return(new Vector3((float)x, (float)y, (float)z));
            }, sub.norms);

            Mesh unityMesh = new Mesh();
            unityMesh.vertices     = vertices;
            unityMesh.normals      = normals;
            unityMesh.uv           = new Vector2[vertices.Length];
            unityMesh.subMeshCount = sub.surfaces.Count;
            for (int i = 0; i < sub.surfaces.Count; i++)
            {
                int[] cpy = new int[sub.surfaces[i].indicies.Length];
                Array.Copy(sub.surfaces[i].indicies, cpy, cpy.Length);
                if (mirror)
                {
                    Array.Reverse(cpy);
                }
                unityMesh.SetTriangles(cpy, i);
            }
            if (normals != null)
            {
                unityMesh.RecalculateNormals();
            }

            handleMesh(j, sub, unityMesh);
        }
    }
Пример #13
0
 /// <summary>
 /// Returns a bullet mesh shape given a BXDA sub mesh and a list of vectors to index from
 /// </summary>
 /// <param name="subMesh"></param>
 /// <param name="vertices"></param>
 /// <returns></returns>
 public static StridingMeshInterface BulletShapeFromSubMesh(BXDAMesh.BXDASubMesh subMesh)
 {
     return(new TriangleIndexVertexArray(subMesh.GetAllIndices().ToArray(), subMesh.GetVertexData()));
 }
Пример #14
0
        /// <summary>
        /// Executes the actual exporting.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exporter_DoWork(object sender, DoWorkEventArgs e)
        {
            string directory = FIELD_FOLDER + fieldNameTextBox.Text;

            // Create directory if it does not exist
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
            // Warn user of overwrite if it does exist
            else if (MessageBox.Show("A field with this name already exists. Continue?", "Overwrite Existing Field", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
            {
                e.Cancel = true;
                return;
            }

            FieldDefinition fieldDefinition = FieldDefinition.Factory(Guid.NewGuid(), Program.ASSEMBLY_DOCUMENT.DisplayName);

            foreach (PropertySet ps in Program.MAINWINDOW.GetPropertySetsTabControl().TranslateToPropertySets())
            {
                fieldDefinition.AddPropertySet(ps);
            }

            SurfaceExporter surfaceExporter   = new SurfaceExporter();
            List <string>   exportedMeshes    = new List <string>();
            List <string>   exportedColliders = new List <string>();
            StringBuilder   pathBuilder       = new StringBuilder();

            int numOccurrences      = Program.ASSEMBLY_DOCUMENT.ComponentDefinition.Occurrences.AllLeafOccurrences.Count;
            int progressPercent     = 0;
            int currentOccurrenceID = 0;

            foreach (ComponentOccurrence currentOccurrence in Program.ASSEMBLY_DOCUMENT.ComponentDefinition.Occurrences.AllLeafOccurrences)
            {
                if (exporter.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                progressPercent = (int)Math.Floor((currentOccurrenceID / (double)numOccurrences) * 100.0);
                exporter.ReportProgress(progressPercent, "Exporting... " + progressPercent + "%");

                if (currentOccurrence.Visible &&
                    currentOccurrence.ReferencedDocumentDescriptor != null &&
                    currentOccurrence.ReferencedDocumentDescriptor.ReferencedDocumentType == DocumentTypeEnum.kPartDocumentObject &&
                    currentOccurrence.SurfaceBodies.Count > 0)
                {
                    FieldNode outputNode = new FieldNode(currentOccurrence.Name);

                    outputNode.Position = Utilities.ToBXDVector(currentOccurrence.Transformation.Translation);
                    outputNode.Rotation = Utilities.QuaternionFromMatrix(currentOccurrence.Transformation);

                    if (!exportedMeshes.Contains(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName))
                    {
                        surfaceExporter.Reset();
                        surfaceExporter.Export(((PartDocument)currentOccurrence.ReferencedDocumentDescriptor.ReferencedDocument).ComponentDefinition, false, true);

                        BXDAMesh.BXDASubMesh outputMesh = surfaceExporter.GetOutput().meshes.First();

                        exportedMeshes.Add(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);
                        fieldDefinition.AddSubMesh(outputMesh);
                    }

                    outputNode.SubMeshID = exportedMeshes.IndexOf(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);

                    ComponentPropertiesTabPage componentProperties = Program.MAINWINDOW.GetPropertySetsTabControl().GetParentTabPage(currentOccurrence.Name);

                    if (componentProperties != null)
                    {
                        outputNode.PropertySetID = componentProperties.Name;

                        PropertySet propertySet = fieldDefinition.GetPropertySets()[outputNode.PropertySetID];

                        if (propertySet.Collider.CollisionType == PropertySet.PropertySetCollider.PropertySetCollisionType.MESH &&
                            ((PropertySet.MeshCollider)propertySet.Collider).Convex)
                        {
                            if (!exportedColliders.Contains(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName))
                            {
                                exportedColliders.Add(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);
                                var test = fieldDefinition.GetSubMesh(outputNode.SubMeshID);
                                fieldDefinition.AddCollisionMesh(ConvexHullCalculator.GetHull(fieldDefinition.GetSubMesh(outputNode.SubMeshID)));
                            }
                            outputNode.CollisionMeshID = exportedColliders.IndexOf(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);
                        }
                    }

                    pathBuilder.Clear();

                    foreach (ComponentOccurrence co in currentOccurrence.OccurrencePath)
                    {
                        pathBuilder.Append(co.Name + "/");
                    }

                    pathBuilder.Length--;

                    fieldDefinition.NodeGroup[pathBuilder.ToString()] = outputNode;
                }

                currentOccurrenceID++;
            }

            exporter.ReportProgress(100, "Export Successful!");

            fieldDefinition.GetMeshOutput().WriteToFile(directory + "\\mesh.bxda");

            // Field data such as spawnpoints and gamepieces
            ExportFieldData(directory);

            // Property sets
            BXDFProperties.WriteProperties(directory + "\\definition.bxdf", fieldDefinition);

            // Open the export directory when done
            if (openFolderCheckBox.Checked)
            {
                Process.Start("explorer.exe", "/select, " + directory);
            }
        }
Пример #15
0
    public bool CreateMesh(string filePath)
    {
        BXDAMesh mesh = new BXDAMesh();

        mesh.ReadFromFile(filePath, null);

        if (!mesh.GUID.Equals(GUID))
        {
            return(false);
        }

        List <FieldNode> remainingNodes = new List <FieldNode>(NodeGroup.EnumerateAllLeafFieldNodes());

        List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > submeshes = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >();
        List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > colliders = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >();

        // Create all submesh objects
        auxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu)
        {
            submeshes.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu));
        });

        // Create all collider objects
        auxFunctions.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu)
        {
            colliders.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu));
        });

        foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes())
        {
            GameObject subObject = new GameObject(node.NodeID);
            //subObject.transform.parent = unityObject.transform;

            if (node.SubMeshID != -1)
            {
                KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = submeshes[node.SubMeshID];

                BXDAMesh.BXDASubMesh sub = currentSubMesh.Key;
                Mesh meshu = currentSubMesh.Value;

                subObject.AddComponent <MeshFilter>().mesh = meshu;
                subObject.AddComponent <MeshRenderer>();
                Material[] matls = new Material[meshu.subMeshCount];

                for (int i = 0; i < matls.Length; i++)
                {
                    matls[i] = sub.surfaces[i].AsMaterial();
                }

                subObject.GetComponent <MeshRenderer>().materials = matls;
            }

            if (GetPropertySets().ContainsKey(node.PropertySetID))
            {
                PropertySet currentPropertySet             = GetPropertySets()[node.PropertySetID];
                PropertySet.PropertySetCollider psCollider = currentPropertySet.Collider;
                Collider unityCollider = null;

                Debug.Log(psCollider == null);

                switch (psCollider.CollisionType)
                {
                case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX:
                    PropertySet.BoxCollider psBoxCollider    = (PropertySet.BoxCollider)psCollider;
                    BoxCollider             unityBoxCollider = subObject.AddComponent <BoxCollider>();

                    //unityBoxCollider.size.Scale(new Vector3(psBoxCollider.Scale.x, psBoxCollider.Scale.y, psBoxCollider.Scale.z));
                    unityBoxCollider.size = new Vector3(
                        unityBoxCollider.size.x * psBoxCollider.Scale.x,
                        unityBoxCollider.size.y * psBoxCollider.Scale.y,
                        unityBoxCollider.size.z * psBoxCollider.Scale.z);

                    unityCollider = unityBoxCollider;
                    break;

                case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE:
                    PropertySet.SphereCollider psSphereCollider    = (PropertySet.SphereCollider)psCollider;
                    SphereCollider             unitySphereCollider = subObject.AddComponent <SphereCollider>();

                    unitySphereCollider.radius *= psSphereCollider.Scale;

                    unityCollider = unitySphereCollider;
                    break;

                case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH:
                    if (node.CollisionMeshID != -1)
                    {
                        KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = colliders[node.CollisionMeshID];

                        BXDAMesh.BXDASubMesh sub = currentSubMesh.Key;
                        Mesh meshu = currentSubMesh.Value;

                        MeshCollider unityMeshCollider = subObject.AddComponent <MeshCollider>();
                        unityMeshCollider.sharedMesh = meshu;
                        unityMeshCollider.convex     = true;

                        unityCollider = unityMeshCollider;
                    }
                    break;
                }

                if (unityCollider != null)
                {
                    unityCollider.material.dynamicFriction = unityCollider.material.staticFriction = currentPropertySet.Friction / 100f;
                    unityCollider.material.frictionCombine = PhysicMaterialCombine.Minimum;

                    Rigidbody rb = unityCollider.gameObject.AddComponent <Rigidbody>();

                    if (currentPropertySet.Mass > 0)
                    {
                        rb.mass = (float)currentPropertySet.Mass * Init.PHYSICS_MASS_MULTIPLIER;
                    }
                    else
                    {
                        rb.constraints = RigidbodyConstraints.FreezeAll;
                        rb.isKinematic = true;
                    }
                }
            }

            // Invert the x-axis to compensate for Unity's inverted coordinate system.
            subObject.transform.localScale = new Vector3(-1f, 1f, 1f);

            // Set the position of the object (scaled by 1/100 to match Unity's scaling correctly).
            subObject.transform.position = new Vector3(-node.Position.x * 0.01f, node.Position.y * 0.01f, node.Position.z * 0.01f);

            // Set the rotation of the object (the x and w properties are inverted to once again compensate for Unity's differences).
            subObject.transform.rotation = new Quaternion(-node.Rotation.X, node.Rotation.Y, node.Rotation.Z, -node.Rotation.W);
        }

        #region Free mesh
        foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders })
        {
            foreach (BXDAMesh.BXDASubMesh sub in list)
            {
                sub.verts = null;
                sub.norms = null;
                foreach (BXDAMesh.BXDASurface surf in sub.surfaces)
                {
                    surf.indicies = null;
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                list[i] = null;
            }
        }
        mesh = null;
        GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
        #endregion

        return(true);
    }
Пример #16
0
        /// <summary>
        /// Executes the actual exporting.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exporter_DoWork(object sender, DoWorkEventArgs e)
        {
            FieldDefinition fieldDefinition = FieldDefinition.Factory(Guid.NewGuid(), Program.ASSEMBLY_DOCUMENT.DisplayName);

            foreach (PropertySet ps in Program.MAINWINDOW.GetPropertySetsTabControl().TranslateToPropertySets())
            {
                fieldDefinition.AddPropertySet(ps);
            }

            SurfaceExporter surfaceExporter   = new SurfaceExporter();
            List <string>   exportedMeshes    = new List <string>();
            List <string>   exportedColliders = new List <string>();
            StringBuilder   pathBuilder       = new StringBuilder();

            int numOccurrences      = Program.ASSEMBLY_DOCUMENT.ComponentDefinition.Occurrences.AllLeafOccurrences.Count;
            int progressPercent     = 0;
            int currentOccurrenceID = 0;

            foreach (ComponentOccurrence currentOccurrence in Program.ASSEMBLY_DOCUMENT.ComponentDefinition.Occurrences.AllLeafOccurrences)
            {
                if (exporter.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                progressPercent = (int)Math.Floor((currentOccurrenceID / (double)numOccurrences) * 100.0);
                exporter.ReportProgress(progressPercent, "Exporting... " + progressPercent + "%");

                if (currentOccurrence.Visible &&
                    currentOccurrence.ReferencedDocumentDescriptor != null &&
                    currentOccurrence.ReferencedDocumentDescriptor.ReferencedDocumentType == DocumentTypeEnum.kPartDocumentObject &&
                    currentOccurrence.SurfaceBodies.Count > 0)
                {
                    FieldNode outputNode = new FieldNode(currentOccurrence.Name);

                    outputNode.Position = Utilities.ToBXDVector(currentOccurrence.Transformation.Translation);
                    outputNode.Rotation = Utilities.QuaternionFromMatrix(currentOccurrence.Transformation);

                    if (!exportedMeshes.Contains(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName))
                    {
                        surfaceExporter.Reset();
                        surfaceExporter.Export(((PartDocument)currentOccurrence.ReferencedDocumentDescriptor.ReferencedDocument).ComponentDefinition, false, true);

                        BXDAMesh.BXDASubMesh outputMesh = surfaceExporter.GetOutput().meshes.First();

                        exportedMeshes.Add(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);
                        fieldDefinition.AddSubMesh(outputMesh);
                    }

                    outputNode.SubMeshID = exportedMeshes.IndexOf(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);

                    ComponentPropertiesTabPage componentProperties = Program.MAINWINDOW.GetPropertySetsTabControl().GetParentTabPage(currentOccurrence.Name);

                    if (componentProperties != null)
                    {
                        outputNode.PropertySetID = componentProperties.Name;

                        PropertySet propertySet = fieldDefinition.GetPropertySets()[outputNode.PropertySetID];

                        if (propertySet.Collider.CollisionType == PropertySet.PropertySetCollider.PropertySetCollisionType.MESH &&
                            ((PropertySet.MeshCollider)propertySet.Collider).Convex)
                        {
                            if (!exportedColliders.Contains(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName))
                            {
                                exportedColliders.Add(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);
                                fieldDefinition.AddCollisionMesh(ConvexHullCalculator.GetHull(fieldDefinition.GetSubMesh(outputNode.SubMeshID)));
                            }

                            outputNode.CollisionMeshID = exportedColliders.IndexOf(currentOccurrence.ReferencedDocumentDescriptor.FullDocumentName);
                        }
                    }

                    pathBuilder.Clear();

                    foreach (ComponentOccurrence co in currentOccurrence.OccurrencePath)
                    {
                        pathBuilder.Append(co.Name + "/");
                    }

                    pathBuilder.Length--;

                    fieldDefinition.NodeGroup[pathBuilder.ToString()] = outputNode;
                }

                currentOccurrenceID++;
            }

            exporter.ReportProgress(100, "Export Successful!");

            fieldDefinition.GetMeshOutput().WriteToFile(filePathTextBox.Text + "\\mesh.bxda");

            BXDFProperties.WriteProperties(filePathTextBox.Text + "\\definition.bxdf", fieldDefinition);

            // Use the commented code below for debugging.

            /** /
             * string result;
             * FieldDefinition readDefinition = BXDFProperties.ReadProperties(filePathTextBox.Text + "\\definition.bxdf", out result);
             * MessageBox.Show(result);
             * /**/
        }
Пример #17
0
    public bool CreateMesh(string filePath)
    {
        BXDAMesh mesh = new BXDAMesh();

        mesh.ReadFromFile(filePath, null);

        if (!mesh.GUID.Equals(GUID))
        {
            return(false);
        }

        List <FieldNode> remainingNodes = new List <FieldNode>(NodeGroup.EnumerateAllLeafFieldNodes());

        List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > submeshes = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >();
        List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > colliders = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >();

        // Create all submesh objects
        AuxFunctions.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu)
        {
            submeshes.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu));
        });

        // Create all collider objects
        AuxFunctions.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu)
        {
            colliders.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu));
        });

        foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes())
        {
            GameObject subObject = new GameObject(node.NodeID);
            subObject.transform.parent = unityObject.transform;

            GameObject meshObject = new GameObject(node.NodeID + "-mesh");

            if (node.SubMeshID != -1)
            {
                KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = submeshes[node.SubMeshID];

                BXDAMesh.BXDASubMesh sub = currentSubMesh.Key;
                Mesh meshu = currentSubMesh.Value;

                meshObject.AddComponent <MeshFilter>().mesh = meshu;
                meshObject.AddComponent <MeshRenderer>();
                Material[] matls = new Material[meshu.subMeshCount];

                for (int i = 0; i < matls.Length; i++)
                {
                    matls[i] = sub.surfaces[i].AsMaterial();
                }

                meshObject.GetComponent <MeshRenderer>().materials = matls;
            }

            // Invert the x-axis to compensate for Unity's inverted coordinate system.
            meshObject.transform.localScale = new Vector3(-1f, 1f, 1f);

            // Set the rotation of the object (the x and w properties are inverted to once again compensate for Unity's differences).
            meshObject.transform.localRotation = new Quaternion(-node.Rotation.X, node.Rotation.Y, node.Rotation.Z, -node.Rotation.W);

            // Set the position of the object (scaled by 1/100 to match Unity's scaling correctly).
            meshObject.transform.position = new Vector3(-node.Position.x * 0.01f, node.Position.y * 0.01f, node.Position.z * 0.01f);

            if (GetPropertySets().ContainsKey(node.PropertySetID))
            {
                PropertySet currentPropertySet             = GetPropertySets()[node.PropertySetID];
                PropertySet.PropertySetCollider psCollider = currentPropertySet.Collider;

                switch (psCollider.CollisionType)
                {
                case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX:
                    PropertySet.BoxCollider psBoxCollider    = (PropertySet.BoxCollider)psCollider;
                    BoxCollider             dummyBoxCollider = meshObject.AddComponent <BoxCollider>();

                    subObject.transform.localRotation = meshObject.transform.localRotation;
                    subObject.transform.position      = meshObject.transform.TransformPoint(dummyBoxCollider.center);

                    BBoxShape boxShape = subObject.AddComponent <BBoxShape>();
                    boxShape.Extents = new Vector3(
                        dummyBoxCollider.size.x * 0.5f * psBoxCollider.Scale.x,
                        dummyBoxCollider.size.y * 0.5f * psBoxCollider.Scale.y,
                        dummyBoxCollider.size.z * 0.5f * psBoxCollider.Scale.z);

                    //meshObject.AddComponent<MouseListener>();
                    UnityEngine.Object.Destroy(dummyBoxCollider);

                    break;

                case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE:
                    PropertySet.SphereCollider psSphereCollider    = (PropertySet.SphereCollider)psCollider;
                    SphereCollider             dummySphereCollider = meshObject.AddComponent <SphereCollider>();

                    subObject.transform.position = meshObject.transform.TransformPoint(dummySphereCollider.center);

                    BSphereShape sphereShape = subObject.AddComponent <BSphereShape>();
                    sphereShape.Radius = dummySphereCollider.radius * psSphereCollider.Scale;

                    //meshObject.AddComponent<MouseListener>();
                    UnityEngine.Object.Destroy(dummySphereCollider);

                    break;

                case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH:
                    PropertySet.MeshCollider psMeshCollider = (PropertySet.MeshCollider)psCollider;

                    if (psMeshCollider.Convex || currentPropertySet.Mass != 0)
                    {
                        MeshCollider dummyMeshCollider = subObject.AddComponent <MeshCollider>();
                        dummyMeshCollider.sharedMesh = meshObject.GetComponent <MeshFilter>().mesh;

                        subObject.transform.position = meshObject.transform.TransformPoint(dummyMeshCollider.bounds.center);
                        subObject.transform.rotation = meshObject.transform.rotation;

                        BConvexHullShape hullshape = subObject.AddComponent <BConvexHullShape>();
                        hullshape.HullMesh = AuxFunctions.GenerateCollisionMesh(meshObject.GetComponent <MeshFilter>().mesh, dummyMeshCollider.sharedMesh.bounds.center);
                        hullshape.GetCollisionShape().Margin = 0f;

                        //subObject.AddComponent<MouseListener>();
                        UnityEngine.Object.Destroy(dummyMeshCollider);
                    }
                    else
                    {
                        subObject.transform.position = meshObject.transform.position;
                        subObject.transform.rotation = meshObject.transform.rotation;

                        BBvhTriangleMeshShape meshShape = subObject.AddComponent <BBvhTriangleMeshShape>();
                        meshShape.HullMesh = meshObject.GetComponent <MeshFilter>().mesh.GetScaledCopy(-1f, 1f, 1f);
                        meshShape.GetCollisionShape().Margin = 0f;
                    }

                    // TODO: Find a way to implement embedded margins. See https://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=2358
                    break;
                }

                BRigidBody rb = subObject.AddComponent <BRigidBody>();
                rb.friction = currentPropertySet.Friction * FRICTION_SCALE;
                rb.mass     = currentPropertySet.Mass;

                if (currentPropertySet.Mass == 0)
                {
                    rb.collisionFlags = BulletSharp.CollisionFlags.StaticObject;
                }
                else
                {
                    subObject.AddComponent <Tracker>();
                }

                meshObject.transform.parent = subObject.transform;
            }
            else
            {
                meshObject.transform.parent = unityObject.transform;
            }
        }

        #region Free mesh
        foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders })
        {
            foreach (BXDAMesh.BXDASubMesh sub in list)
            {
                sub.verts = null;
                sub.norms = null;
                foreach (BXDAMesh.BXDASurface surf in sub.surfaces)
                {
                    surf.indicies = null;
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                list[i] = null;
            }
        }
        mesh = null;
        GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
        #endregion

        return(true);
    }
Пример #18
0
 public VBOMesh(BXDAMesh.BXDASubMesh subMesh)
 {
     this.subMesh = subMesh;
 }
Пример #19
0
 /// <summary>
 /// Used for adding a submesh and creating a sub mesh ID for the given node.
 /// </summary>
 /// <param name="subMesh"></param>
 /// <param name="node"></param>
 public void AddSubMesh(BXDAMesh.BXDASubMesh subMesh)
 {
     mesh.meshes.Add(subMesh);
 }
Пример #20
0
 /// <summary>
 /// Returns a bullet mesh shape offset relative to its starting position
 /// </summary>
 /// <param name="subMesh"></param>
 /// <param name="vertices"></param>
 /// <param name="offset"></param>
 /// <returns></returns>
 public static StridingMeshInterface BulletShapeFromSubMesh(BXDAMesh.BXDASubMesh subMesh, Vector3 offset)
 {
     Vector3[] vertices = subMesh.GetVertexData();
     return(new TriangleIndexVertexArray(subMesh.GetAllIndices().ToArray(), (from Vector3 v in vertices select v + offset).ToArray()));
 }
Пример #21
0
 /// <summary>
 /// Used for adding a collision mesh and creating a collision mesh ID for the given node.
 /// </summary>
 /// <param name="collisionMesh"></param>
 /// <param name="node"></param>
 public void AddCollisionMesh(BXDAMesh.BXDASubMesh collisionMesh)
 {
     mesh.colliders.Add(collisionMesh);
 }
Пример #22
0
        public bool CreateMesh(string filePath, bool multiplayer = false, bool host = false)
        {
            BXDAMesh mesh = new BXDAMesh();

            mesh.ReadFromFile(filePath, null);

            if (!mesh.GUID.Equals(GUID))
            {
                return(false);
            }

            List <FieldNode> remainingNodes = new List <FieldNode>(NodeGroup.EnumerateAllLeafFieldNodes());

            List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > submeshes = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >();
            List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> > colliders = new List <KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> >();

            // Create all submesh objects
            Auxiliary.ReadMeshSet(mesh.meshes, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu)
            {
                submeshes.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu));
            });

            // Create all collider objects
            Auxiliary.ReadMeshSet(mesh.colliders, delegate(int id, BXDAMesh.BXDASubMesh sub, Mesh meshu)
            {
                colliders.Add(new KeyValuePair <BXDAMesh.BXDASubMesh, Mesh>(sub, meshu));
            });

            //Dictionary<string, NetworkElement> networkElements = new Dictionary<string, NetworkElement>();

            //foreach (NetworkElement ne in Resources.FindObjectsOfTypeAll<NetworkElement>())
            //    networkElements[ne.NodeID] = ne;

            foreach (FieldNode node in NodeGroup.EnumerateAllLeafFieldNodes())
            {
                PropertySet?propertySet = null;

                if (GetPropertySets().ContainsKey(node.PropertySetID))
                {
                    propertySet = GetPropertySets()[node.PropertySetID];
                }

                GameObject subObject;

                //if (multiplayer && propertySet.HasValue && propertySet.Value.Mass != 0)
                //{
                //    if (host)
                //    {
                //        subObject = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("prefabs/NetworkElement"), unityObject.transform);
                //        subObject.GetComponent<NetworkElement>().NodeID = node.NodeID;
                //        subObject.name = node.NodeID;
                //        NetworkServer.Spawn(subObject);
                //    }
                //    else
                //    {
                //        subObject = networkElements[node.NodeID].gameObject;
                //        subObject.name = node.NodeID;
                //    }
                //}
                //else
                //{
                //    subObject = new GameObject(node.NodeID);
                //}

                subObject = new GameObject(node.NodeID);
                subObject.transform.parent = unityObject.transform;

                GameObject meshObject = new GameObject(node.NodeID + "-mesh");

                if (node.SubMeshID != -1)
                {
                    KeyValuePair <BXDAMesh.BXDASubMesh, Mesh> currentSubMesh = submeshes[node.SubMeshID];

                    BXDAMesh.BXDASubMesh sub = currentSubMesh.Key;
                    Mesh meshu = currentSubMesh.Value;

                    meshObject.AddComponent <MeshFilter>().mesh = meshu;


                    meshObject.AddComponent <MeshRenderer>();
                    Material[] matls = new Material[meshu.subMeshCount];

                    for (int i = 0; i < matls.Length; i++)
                    {
                        matls[i] = sub.surfaces[i].AsMaterial();
                    }

                    meshObject.GetComponent <MeshRenderer>().materials = matls;
                }

                // Invert the x-axis to compensate for Unity's inverted coordinate system.
                meshObject.transform.localScale = new Vector3(-1f, 1f, 1f);

                // Set the rotation of the object (the x and w properties are inverted to once again compensate for Unity's differences).
                meshObject.transform.localRotation = new Quaternion(-node.Rotation.X, node.Rotation.Y, node.Rotation.Z, -node.Rotation.W);

                // Set the position of the object (scaled by 1/100 to match Unity's scaling correctly).
                meshObject.transform.position = new Vector3(-node.Position.x * 0.01f, node.Position.y * 0.01f, node.Position.z * 0.01f);

                if (GetPropertySets().ContainsKey(node.PropertySetID))
                {
                    PropertySet currentPropertySet             = GetPropertySets()[node.PropertySetID];
                    PropertySet.PropertySetCollider psCollider = currentPropertySet.Collider;

                    switch (psCollider.CollisionType)
                    {
                    case PropertySet.PropertySetCollider.PropertySetCollisionType.BOX:
                        PropertySet.BoxCollider psBoxCollider    = (PropertySet.BoxCollider)psCollider;
                        BoxCollider             dummyBoxCollider = meshObject.AddComponent <BoxCollider>();

                        subObject.transform.localRotation = meshObject.transform.localRotation;
                        subObject.transform.position      = meshObject.transform.TransformPoint(dummyBoxCollider.center);

                        BBoxShape boxShape = subObject.AddComponent <BBoxShape>();
                        boxShape.Extents = new Vector3(
                            dummyBoxCollider.size.x * 0.5f * psBoxCollider.Scale.x,
                            dummyBoxCollider.size.y * 0.5f * psBoxCollider.Scale.y,
                            dummyBoxCollider.size.z * 0.5f * psBoxCollider.Scale.z);

                        //meshObject.AddComponent<MouseListener>();
                        UnityEngine.Object.Destroy(dummyBoxCollider);

                        break;

                    case PropertySet.PropertySetCollider.PropertySetCollisionType.SPHERE:
                        PropertySet.SphereCollider psSphereCollider    = (PropertySet.SphereCollider)psCollider;
                        SphereCollider             dummySphereCollider = meshObject.AddComponent <SphereCollider>();

                        subObject.transform.position = meshObject.transform.TransformPoint(dummySphereCollider.center);

                        BSphereShape sphereShape = subObject.AddComponent <BSphereShape>();
                        sphereShape.Radius = dummySphereCollider.radius * psSphereCollider.Scale;

                        //meshObject.AddComponent<MouseListener>();
                        UnityEngine.Object.Destroy(dummySphereCollider);

                        break;

                    case PropertySet.PropertySetCollider.PropertySetCollisionType.MESH:
                        PropertySet.MeshCollider psMeshCollider = (PropertySet.MeshCollider)psCollider;

                        if (psMeshCollider.Convex || currentPropertySet.Mass != 0)
                        {
                            MeshCollider dummyMeshCollider = subObject.AddComponent <MeshCollider>();
                            dummyMeshCollider.sharedMesh = meshObject.GetComponent <MeshFilter>().mesh;

                            subObject.transform.position = meshObject.transform.TransformPoint(dummyMeshCollider.bounds.center);
                            subObject.transform.rotation = meshObject.transform.rotation;

                            BConvexHullShape hullshape = subObject.AddComponent <BConvexHullShape>();
                            hullshape.HullMesh = Auxiliary.GenerateCollisionMesh(meshObject.GetComponent <MeshFilter>().mesh, dummyMeshCollider.sharedMesh.bounds.center, 0f /*CollisionMargin*/);
                            hullshape.GetCollisionShape().Margin = CollisionMargin;

                            //subObject.AddComponent<MouseListener>();
                            UnityEngine.Object.Destroy(dummyMeshCollider);
                        }
                        else
                        {
                            subObject.transform.position = meshObject.transform.position;
                            subObject.transform.rotation = meshObject.transform.rotation;

                            BBvhTriangleMeshShape meshShape = subObject.AddComponent <BBvhTriangleMeshShape>();
                            meshShape.HullMesh = meshObject.GetComponent <MeshFilter>().mesh.GetScaledCopy(-1f, 1f, 1f);
                            meshShape.GetCollisionShape().Margin = CollisionMargin;
                        }
                        break;
                    }

                    BRigidBody rb = subObject.AddComponent <BRigidBody>();
                    rb.friction        = currentPropertySet.Friction * FrictionScale;
                    rb.rollingFriction = currentPropertySet.Friction * RollingFrictionScale;
                    rb.mass            = currentPropertySet.Mass;

                    if (currentPropertySet.Mass == 0)
                    {
                        rb.collisionFlags = BulletSharp.CollisionFlags.StaticObject;
                    }
                    else
                    {
                        subObject.AddComponent <Tracker>();
                        subObject.name = currentPropertySet.PropertySetID; //sets game elements to the same name as the property set - used to identify proper colliders
                    }

                    meshObject.transform.parent = subObject.transform;
                }
                else
                {
                    meshObject.transform.parent = unityObject.transform;
                }
            }

            //if (!host)
            //    foreach (NetworkElement ne in networkElements.Values)
            //        ne.gameObject.AddComponent<NetworkMesh>();

            #region Free mesh
            foreach (var list in new List <BXDAMesh.BXDASubMesh>[] { mesh.meshes, mesh.colliders })
            {
                foreach (BXDAMesh.BXDASubMesh sub in list)
                {
                    sub.verts = null;
                    sub.norms = null;
                    foreach (BXDAMesh.BXDASurface surf in sub.surfaces)
                    {
                        surf.indicies = null;
                    }
                }
                for (int i = 0; i < list.Count; i++)
                {
                    list[i] = null;
                }
            }
            mesh = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            #endregion

            return(true);
        }
Пример #23
0
 /// <summary>
 /// Gets the center of a sub mesh relative to the entire BXDA mesh
 /// </summary>
 /// <param name="subMesh"></param>
 /// <param name="vertices"></param>
 /// <returns></returns>
 public static Vector3 MeshCenterRelative(BXDAMesh.BXDASubMesh subMesh, BXDAMesh mesh)
 {
     return(MeshCenter(subMesh) - MeshCenter(mesh.AllColliderVertices()));
 }
Пример #24
0
 /// <summary>
 /// Gets all of the unordered vertex data from the submesh
 /// </summary>
 /// <param name="mesh"></param>
 /// <returns></returns>
 public static Vector3[] GetVertexData(this BXDAMesh.BXDASubMesh mesh)
 {
     return(MeshUtilities.DataToVector(mesh.verts));
 }