コード例 #1
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);
    }
コード例 #2
0
ファイル: BXDExtensions.cs プロジェクト: ezhangle/synthesis
        public static Material AsMaterial(this BXDAMesh.BXDASurface surf, bool emissive = false)
        {
            uint  val   = surf.hasColor ? surf.color : 0xFFFFFFFF;
            Color color = new Color32((byte)(val & 0xFF), (byte)((val >> 8) & 0xFF), (byte)((val >> 16) & 0xFF), (byte)((val >> 24) & 0xFF));

            if (surf.transparency != 0)
            {
                color.a = surf.transparency;
            }
            else if (surf.translucency != 0)
            {
                color.a = surf.translucency;
            }
            if (color.a == 0)   // No perfectly transparent things plz.
            {
                color.a = 1;
            }
            Material result = new Material(Shader.Find(emissive ? "Standard" : (color.a != 1 ? "Transparent/" : "") + (surf.specular > 0 ? "Specular" : "Diffuse")));

            result.SetColor("_Color", color);
            if (surf.specular > 0)
            {
                result.SetFloat("_Shininess", surf.specular);
                result.SetColor("_SpecColor", color);
            }

            if (emissive)
            {
                result.EnableKeyword("_EMISSION");
                result.SetColor("_EmissionColor", Color.black);
            }

            return(result);
        }
コード例 #3
0
    public static Material AsMaterial(this BXDAMesh.BXDASurface surf)
    {
        uint  val   = surf.hasColor ? surf.color : 0xFFFFFFFF;
        Color color = new Color32((byte)(val & 0xFF), (byte)((val >> 8) & 0xFF), (byte)((val >> 16) & 0xFF), (byte)((val >> 24) & 0xFF));

        if (surf.transparency != 0)
        {
            color.a = surf.transparency;
        }
        else if (surf.translucency != 0)
        {
            color.a = surf.translucency;
        }
        if (color.a == 0)   // No perfectly transparent things plz.
        {
            color.a = 1;
        }
        Material result = new Material((Shader)Shader.Find((color.a != 1 ? "Transparent/" : "") + (surf.specular > 0 ? "Specular" : "Diffuse")));

        result.SetColor("_Color", color);
        if (surf.specular > 0)
        {
            result.SetFloat("_Shininess", surf.specular);
            result.SetColor("_SpecColor", color);
        }
        return(result);
    }
コード例 #4
0
            /// <summary>
            /// Adds a surface to the output mesh. Not saved as a sub-surface until <see cref="DumpOutput"/> is called.
            /// </summary>
            /// <param name="bufferSurface">Surface to add to mesh.</param>
            /// <param name="asset">Asset for surface.</param>
            public void AddSurface(ref PartialSurface bufferSurface, AssetProperties asset)
            {
                // Create new surface
                BXDAMesh.BXDASurface newMeshSurface = new BXDAMesh.BXDASurface();

                // Apply Asset Properties
                if (asset == null)
                {
                    return;
                }

                newMeshSurface.hasColor     = true;
                newMeshSurface.color        = asset.color;
                newMeshSurface.transparency = (float)asset.transparency;
                newMeshSurface.translucency = (float)asset.translucency;
                newMeshSurface.specular     = (float)asset.specular;

                // Prevent too many vertices
                if (bufferSurface.verts.count > MAX_VERTS_OR_FACETS)
                {
                    throw new TooManyVerticesException();
                }

                int indexOffset;

                lock (outputVerts)
                {
                    // Prevent too many vertices
                    if (outputVerts.count + bufferSurface.verts.count > MAX_VERTS_OR_FACETS)
                    {
                        DumpOutputInternal();
                    }

                    // Copy buffer vertices into output
                    Array.Copy(bufferSurface.verts.coordinates, 0, outputVerts.coordinates, outputVerts.count * 3, bufferSurface.verts.count * 3);
                    Array.Copy(bufferSurface.verts.norms, 0, outputVerts.norms, outputVerts.count * 3, bufferSurface.verts.count * 3);

                    // Store length of output verts for later
                    indexOffset        = outputVerts.count - 1;
                    outputVerts.count += bufferSurface.verts.count;
                }

                // Copy buffer surface into output, incrementing indices relative to where verts where stitched into the vert array
                newMeshSurface.indicies = new int[bufferSurface.facets.count * 3];
                for (int i = 0; i < bufferSurface.facets.count * 3; i++)
                {
                    newMeshSurface.indicies[i] = bufferSurface.facets.indices[i] + indexOffset; // Why does Inventor start from 1?!
                }
                // Add the new surface to the output
                lock (outputMeshSurfaces)
                    outputMeshSurfaces.Add(newMeshSurface);

                // Empty buffer
                bufferSurface.verts.count  = 0;
                bufferSurface.facets.count = 0;
            }
コード例 #5
0
        private void reloadSubMesh(BXDAEditorNode subMeshNode)
        {
            foreach (BXDAEditorNode surfaceNode in subMeshNode.LastNode.Nodes)
            {
                BXDAMesh.BXDASurface surface      = (BXDAMesh.BXDASurface)surfaceNode.data[0];
                BXDAEditorNode       materialNode = (BXDAEditorNode)surfaceNode.Nodes[0];

                surface.hasColor     = (bool)((BXDAEditorNode)materialNode.Nodes[0]).data[1];
                surface.color        = (uint)((BXDAEditorNode)materialNode.Nodes[0]).data[0];
                surface.transparency = (float)((BXDAEditorNode)materialNode.Nodes[1]).data[0];
                surface.translucency = (float)((BXDAEditorNode)materialNode.Nodes[2]).data[0];
                surface.specular     = (float)((BXDAEditorNode)materialNode.Nodes[3]).data[0];
            }
        }
コード例 #6
0
    /// <summary>
    /// Copies mesh information for the given surface body into the mesh storage structure.
    /// </summary>
    /// <param name="surf">The surface body to export</param>
    /// <param name="bestResolution">Use the best possible resolution</param>
    /// <param name="separateFaces">Separate the surface body into one mesh per face</param>
    private void AddFacets(SurfaceBody surf, bool bestResolution = false, bool separateFaces = false)
    {
        BXDAMesh.BXDASurface nextSurface = new BXDAMesh.BXDASurface();

        surf.GetExistingFacetTolerances(out tmpToleranceCount, out tolerances);

        int bestIndex = -1;

        for (int i = 0; i < tmpToleranceCount; i++)
        {
            if (bestIndex < 0 || ((tolerances[i] < tolerances[bestIndex]) == bestResolution))
            {
                bestIndex = i;
            }
        }

        #region SHOULD_SEPARATE_FACES
        AssetProperties sharedValue = null;
        string          sharedDisp  = null;
        if (separateFaces)  // Only separate if they are actually different colors
        {
            separateFaces = false;
            foreach (Face f in surf.Faces)
            {
                try
                {
                    Asset ast = f.Appearance;
                    if (sharedValue == null)
                    {
                        sharedValue = new AssetProperties(ast);
                        sharedDisp  = ast.DisplayName;
                    }
                    else if (!ast.DisplayName.Equals(sharedDisp))
                    {
                        separateFaces = true;
                        break;
                    }
                }
                catch
                {
                }
            }
        }
        #endregion

#if USE_TEXTURES
        surf.GetExistingFacetsAndTextureMap(tolerances[bestIndex], out tmpSurface.vertCount, out tmpSurface.facetCount, out tmpSurface.verts, out tmpSurface.norms, out tmpSurface.indicies, out tmpSurface.textureCoords);
        if (tmpSurface.vertCount == 0)
        {
            surf.CalculateFacetsAndTextureMap(tolerances[bestIndex], out tmpSurface.vertCount, out tmpSurface.facetCount, out tmpSurface.verts, out tmpSurface.norms, out tmpSurface.indicies, out tmpSurface.textureCoords);
        }
#else
        surf.GetExistingFacets(tolerances[bestIndex], out tmpSurface.vertCount, out tmpSurface.facetCount, out tmpSurface.verts, out tmpSurface.norms, out tmpSurface.indicies);
        if (tmpSurface.vertCount == 0)
        {
            surf.CalculateFacets(tolerances[bestIndex], out tmpSurface.vertCount, out tmpSurface.facetCount, out tmpSurface.verts, out tmpSurface.norms, out tmpSurface.indicies);
        }
#endif
        if (separateFaces || tmpSurface.vertCount > TMP_VERTICIES)
        {
            int i = 0;
            foreach (Face f in surf.Faces)
            {
                i++;
                AddFacets(f, tolerances[bestIndex]);
            }
        }
        else
        {
            //Console.WriteLine("Exporting single block for " + surf.Parent.Name + "\t(" + surf.Name + ")");
            AssetProperties assetProps = sharedValue;
            if (sharedValue == null)
            {
                assetProps = AssetProperties.Create(surf);
            }

            if (assetProps != null)
            {
                AddFacetsInternal(assetProps);
            }
        }
    }
コード例 #7
0
    /// <summary>
    /// Moves the mesh currently in the temporary mesh buffer into the mesh structure itself,
    /// with material information from the asset properties.
    /// </summary>
    /// <param name="assetProps">Material information to use</param>
    private void AddFacetsInternal(AssetProperties assetProps)
    {
        if (tmpSurface.vertCount > TMP_VERTICIES)
        {
            // This is just bad.  It could be fixed by exporting it per-face instead of with a single block.
            System.Windows.Forms.MessageBox.Show("Warning: Mesh segment exceededed " + TMP_VERTICIES + " verticies.  Strange things may begin to happen.");
        }
        // If adding this would cause the sub mesh to overflow dump what currently exists.
        if (tmpSurface.vertCount + postSurface.vertCount >= TMP_VERTICIES)
        {
            DumpMeshBuffer();
        }

        Array.Copy(tmpSurface.verts, 0, postSurface.verts, postSurface.vertCount * 3, tmpSurface.vertCount * 3);
        Array.Copy(tmpSurface.norms, 0, postSurface.norms, postSurface.vertCount * 3, tmpSurface.vertCount * 3);
#if USE_TEXTURES
        Array.Copy(tmpSurface.textureCoords, 0, postSurface.textureCoords, postSurface.vertCount * 2, tmpSurface.vertCount * 2);
#endif

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

        nextSurface.color = 0xFFFFFFFF;

        if (assetProps.color != null)
        {
            nextSurface.hasColor = true;
            nextSurface.color    = ((uint)assetProps.color.Red << 0) | ((uint)assetProps.color.Green << 8) | ((uint)assetProps.color.Blue << 16) | ((((uint)(assetProps.color.Opacity * 255)) & 0xFF) << 24);
        }
        nextSurface.transparency = (float)assetProps.transparency;
        nextSurface.translucency = (float)assetProps.translucency;
        nextSurface.specular     = (float)assetProps.specular;

        nextSurface.indicies = new int[tmpSurface.facetCount * 3];

        // Raw copy the indicies for now, then fix the offset in a background thread.
        Array.Copy(tmpSurface.indicies, nextSurface.indicies, nextSurface.indicies.Length);

        #region Fix Index Buffer Offset
        // Make sure we haven't exceeded the maximum number of background tasks.
        if (waitingThreads.Count > MAX_BACKGROUND_THREADS)
        {
            // Console.WriteLine("Got ahead of ourselves....");
            System.Threading.WaitHandle.WaitAll(waitingThreads.ToArray());
            waitingThreads.Clear();
        }
        {
            System.Threading.ManualResetEvent lockThing = new System.Threading.ManualResetEvent(false);
            waitingThreads.Add(lockThing);
            int offset            = postSurface.vertCount;
            int backingFacetCount = tmpSurface.facetCount;
            System.Threading.ThreadPool.QueueUserWorkItem(delegate(object obj)
            {
                for (int i = 0; i < backingFacetCount * 3; i++)
                {
                    nextSurface.indicies[i] = nextSurface.indicies[i] + offset - 1;
                    // Inventor has one-based indicies.  Zero-based is the way to go for everything except Inventor.
                }
                lockThing.Set();
            }, waitingThreads.Count);
        }
        #endregion

        postSurfaces.Add(nextSurface);

        postSurface.facetCount += tmpSurface.facetCount;
        postSurface.vertCount  += tmpSurface.vertCount;
    }