Example #1
0
        private static unsafe bool getMeshOutputs(Xenko.Rendering.Mesh modelMesh, out List <Vector3> positions, out List <int> indicies)
        {
            if (modelMesh.Draw is StagedMeshDraw)
            {
                StagedMeshDraw smd = modelMesh.Draw as StagedMeshDraw;

                object verts = smd.Verticies;

                if (verts is VertexPositionNormalColor[])
                {
                    VertexPositionNormalColor[] vpnc = verts as VertexPositionNormalColor[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions[k] = vpnc[k].Position;
                    }
                }
                else if (verts is VertexPositionNormalTexture[])
                {
                    VertexPositionNormalTexture[] vpnc = verts as VertexPositionNormalTexture[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions[k] = vpnc[k].Position;
                    }
                }
                else if (verts is VertexPositionNormalTextureTangent[])
                {
                    VertexPositionNormalTextureTangent[] vpnc = verts as VertexPositionNormalTextureTangent[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions[k] = vpnc[k].Position;
                    }
                }
                else
                {
                    positions = null;
                    indicies  = null;
                    return(false);
                }

                // take care of indicies
                indicies = new List <int>((int[])(object)smd.Indicies);
            }
            else
            {
                Xenko.Graphics.Buffer buf  = modelMesh.Draw?.VertexBuffers[0].Buffer;
                Xenko.Graphics.Buffer ibuf = modelMesh.Draw?.IndexBuffer.Buffer;
                if (buf == null || buf.VertIndexData == null ||
                    ibuf == null || ibuf.VertIndexData == null)
                {
                    positions = null;
                    indicies  = null;
                    return(false);
                }

                if (ModelBatcher.UnpackRawVertData(buf.VertIndexData, modelMesh.Draw.VertexBuffers[0].Declaration,
                                                   out Vector3[] arraypositions, out Core.Mathematics.Vector3[] normals, out Core.Mathematics.Vector2[] uvs,
Example #2
0
        private static unsafe bool getMeshOutputs(Xenko.Rendering.Mesh modelMesh, out List <Vector3> positions, out List <int> indicies)
        {
            if (modelMesh.Draw is StagedMeshDraw)
            {
                StagedMeshDraw smd = modelMesh.Draw as StagedMeshDraw;

                object verts = smd.Verticies;

                if (verts is VertexPositionNormalColor[])
                {
                    VertexPositionNormalColor[] vpnc = verts as VertexPositionNormalColor[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions.Add(vpnc[k].Position);
                    }
                }
                else if (verts is VertexPositionNormalTexture[])
                {
                    VertexPositionNormalTexture[] vpnc = verts as VertexPositionNormalTexture[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions.Add(vpnc[k].Position);
                    }
                }
                else if (verts is VertexPositionNormalTextureTangent[])
                {
                    VertexPositionNormalTextureTangent[] vpnc = verts as VertexPositionNormalTextureTangent[];
                    positions = new List <Vector3>(vpnc.Length);
                    for (int k = 0; k < vpnc.Length; k++)
                    {
                        positions.Add(vpnc[k].Position);
                    }
                }
                else
                {
                    throw new ArgumentException("Couldn't get StageMeshDraw mesh, unknown vert type for " + modelMesh.Name);
                }

                // take care of indicies
                indicies = new List <int>(smd.Indicies.Length);
                for (int i = 0; i < smd.Indicies.Length; i++)
                {
                    indicies.Add((int)smd.Indicies[i]);
                }
            }
            else
            {
                Xenko.Graphics.Buffer buf  = modelMesh.Draw?.VertexBuffers[0].Buffer;
                Xenko.Graphics.Buffer ibuf = modelMesh.Draw?.IndexBuffer.Buffer;
                if (buf == null || buf.VertIndexData == null ||
                    ibuf == null || ibuf.VertIndexData == null)
                {
                    throw new ArgumentException("Couldn't get mesh for " + modelMesh.Name + ", buffer wasn't stored probably. Try Xenko.Graphics.Buffer.CaptureAllModelBuffers to true.");
                }

                if (ModelBatcher.UnpackRawVertData(buf.VertIndexData, modelMesh.Draw.VertexBuffers[0].Declaration,
                                                   out Vector3[] arraypositions, out Core.Mathematics.Vector3[] normals, out Core.Mathematics.Vector2[] uvs,
Example #3
0
        protected override void EndDraw(bool present)
        {
            base.EndDraw(present);

            // handle any VR flushing
            if (VRDeviceSystem.Device != null)
            {
                VRDeviceSystem.Device.Flush();
            }

            // have any staged mesh draws to clear out?
            StagedMeshDraw.FlushTrash();
        }
Example #4
0
        private static unsafe void ProcessMaterial(List <BatchingChunk> chunks, MaterialInstance material, Model prefabModel, HashSet <Entity> unbatched = null)
        {
            //actually create the mesh
            List <VertexPositionNormalTextureTangent> vertsNT = null;
            List <VertexPositionNormalColor>          vertsNC = null;
            List <uint> indiciesList = new List <uint>();
            BoundingBox bb           = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity),
                                                       new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity));
            uint indexOffset = 0;

            for (int i = 0; i < chunks.Count; i++)
            {
                BatchingChunk chunk = chunks[i];
                if (unbatched != null && unbatched.Contains(chunk.Entity))
                {
                    continue;                                                        // don't try batching other things in this entity if some failed
                }
                if (chunk.Entity != null)
                {
                    chunk.Entity.Transform.UpdateLocalMatrix();
                    chunk.Entity.Transform.UpdateWorldMatrixInternal(true, false);
                }
                Matrix worldMatrix = chunk.Entity == null ? (chunk.Transform ?? Matrix.Identity) : chunk.Entity.Transform.WorldMatrix;
                Matrix rot;
                if (worldMatrix != Matrix.Identity)
                {
                    worldMatrix.GetRotationMatrix(out rot);
                }
                else
                {
                    rot = Matrix.Identity;
                }
                for (int j = 0; j < chunk.Model.Meshes.Count; j++)
                {
                    Mesh modelMesh = chunk.Model.Meshes[j];
                    //process only right material
                    if (modelMesh.MaterialIndex == chunk.MaterialIndex)
                    {
                        Vector3[] positions = null, normals = null;
                        Vector4[] tangents  = null;
                        Vector2[] uvs       = null;
                        Color4[]  colors    = null;

                        //vertexes
                        if (CachedModelData.TryGet(modelMesh, out var information))
                        {
                            // clone positions and normals, since they may change
                            positions = (Vector3[])information.positions.Clone();
                            normals   = (Vector3[])information.normals.Clone();
                            tangents  = information.tangents;
                            uvs       = information.uvs;
                            colors    = information.colors;
                            for (int k = 0; k < information.indicies.Length; k++)
                            {
                                indiciesList.Add(information.indicies[k] + indexOffset);
                            }
                        }
                        else if (modelMesh.Draw is StagedMeshDraw)
                        {
                            StagedMeshDraw smd = modelMesh.Draw as StagedMeshDraw;

                            object verts = smd.Verticies;

                            if (verts is VertexPositionNormalColor[])
                            {
                                VertexPositionNormalColor[] vpnc = verts as VertexPositionNormalColor[];
                                positions = new Vector3[vpnc.Length];
                                normals   = new Vector3[vpnc.Length];
                                colors    = new Color4[vpnc.Length];
                                for (int k = 0; k < vpnc.Length; k++)
                                {
                                    positions[k] = vpnc[k].Position;
                                    normals[k]   = vpnc[k].Normal;
                                    colors[k]    = vpnc[k].Color;
                                }
                            }
                            else if (verts is VertexPositionNormalTexture[])
                            {
                                VertexPositionNormalTexture[] vpnc = verts as VertexPositionNormalTexture[];
                                positions = new Vector3[vpnc.Length];
                                normals   = new Vector3[vpnc.Length];
                                uvs       = new Vector2[vpnc.Length];
                                for (int k = 0; k < vpnc.Length; k++)
                                {
                                    positions[k] = vpnc[k].Position;
                                    normals[k]   = vpnc[k].Normal;
                                    uvs[k]       = vpnc[k].TextureCoordinate;
                                }
                            }
                            else if (verts is VertexPositionNormalTextureTangent[])
                            {
                                VertexPositionNormalTextureTangent[] vpnc = verts as VertexPositionNormalTextureTangent[];
                                positions = new Vector3[vpnc.Length];
                                normals   = new Vector3[vpnc.Length];
                                uvs       = new Vector2[vpnc.Length];
                                tangents  = new Vector4[vpnc.Length];
                                for (int k = 0; k < vpnc.Length; k++)
                                {
                                    positions[k] = vpnc[k].Position;
                                    normals[k]   = vpnc[k].Normal;
                                    uvs[k]       = vpnc[k].TextureCoordinate;
                                    tangents[k]  = vpnc[k].Tangent;
                                }
                            }
                            else
                            {
                                // unsupported StagedMeshDraw
                                if (unbatched != null)
                                {
                                    unbatched.Add(chunk.Entity);
                                }
                                continue;
                            }

                            // take care of indicies
                            for (int k = 0; k < smd.Indicies.Length; k++)
                            {
                                indiciesList.Add(smd.Indicies[k] + indexOffset);
                            }

                            // cache this for later
                            CachedModelData.Add(modelMesh,
                                                new CachedData()
                            {
                                colors    = colors,
                                indicies  = smd.Indicies,
                                normals   = (Vector3[])normals.Clone(),
                                positions = (Vector3[])positions.Clone(),
                                tangents  = tangents,
                                uvs       = uvs
                            }
                                                );
                        }
                        else
                        {
                            Xenko.Graphics.Buffer buf  = modelMesh.Draw?.VertexBuffers[0].Buffer;
                            Xenko.Graphics.Buffer ibuf = modelMesh.Draw?.IndexBuffer.Buffer;
                            if (buf == null || buf.VertIndexData == null ||
                                ibuf == null || ibuf.VertIndexData == null)
                            {
                                if (unbatched != null)
                                {
                                    unbatched.Add(chunk.Entity);
                                }
                                continue;
                            }

                            if (UnpackRawVertData(buf.VertIndexData, modelMesh.Draw.VertexBuffers[0].Declaration,
                                                  out positions, out normals, out uvs, out colors, out tangents) == false)
                            {
                                if (unbatched != null)
                                {
                                    unbatched.Add(chunk.Entity);
                                }
                                continue;
                            }

                            CachedData cmd = new CachedData()
                            {
                                colors    = colors,
                                positions = (Vector3[])positions.Clone(),
                                normals   = (Vector3[])normals.Clone(),
                                uvs       = uvs,
                                tangents  = tangents
                            };

                            // indicies
                            fixed(byte *pdst = ibuf.VertIndexData)
                            {
                                int numIndices = modelMesh.Draw.IndexBuffer.Count;

                                cmd.indicies = new uint[numIndices];

                                if (modelMesh.Draw.IndexBuffer.Is32Bit)
                                {
                                    var dst = (uint *)(pdst + modelMesh.Draw.IndexBuffer.Offset);
                                    for (var k = 0; k < numIndices; k++)
                                    {
                                        // Offset indices
                                        cmd.indicies[k] = dst[k];
                                        indiciesList.Add(dst[k] + indexOffset);
                                    }
                                }
                                else
                                {
                                    var dst = (ushort *)(pdst + modelMesh.Draw.IndexBuffer.Offset);
                                    for (var k = 0; k < numIndices; k++)
                                    {
                                        // Offset indices
                                        cmd.indicies[k] = dst[k];
                                        indiciesList.Add(dst[k] + indexOffset);
                                    }
                                }
                            }

                            CachedModelData.Add(modelMesh, cmd);
                        }

                        // what kind of structure will we be making, if we haven't picked one already?
                        if (vertsNT == null && vertsNC == null)
                        {
                            if (uvs != null)
                            {
                                vertsNT = new List <VertexPositionNormalTextureTangent>(positions.Length);
                            }
                            else
                            {
                                vertsNC = new List <VertexPositionNormalColor>(positions.Length);
                            }
                        }

                        // bounding box/finish list
                        bool needmatrix = worldMatrix != Matrix.Identity;
                        for (int k = 0; k < positions.Length; k++)
                        {
                            if (needmatrix)
                            {
                                Vector3.Transform(ref positions[k], ref worldMatrix, out positions[k]);

                                if (normals != null)
                                {
                                    Vector3.TransformNormal(ref normals[k], ref rot, out normals[k]);
                                }
                            }

                            // update bounding box?
                            Vector3 pos = positions[k];
                            if (pos.X > bb.Maximum.X)
                            {
                                bb.Maximum.X = pos.X;
                            }
                            if (pos.Y > bb.Maximum.Y)
                            {
                                bb.Maximum.Y = pos.Y;
                            }
                            if (pos.Z > bb.Maximum.Z)
                            {
                                bb.Maximum.Z = pos.Z;
                            }
                            if (pos.X < bb.Minimum.X)
                            {
                                bb.Minimum.X = pos.X;
                            }
                            if (pos.Y < bb.Minimum.Y)
                            {
                                bb.Minimum.Y = pos.Y;
                            }
                            if (pos.Z < bb.Minimum.Z)
                            {
                                bb.Minimum.Z = pos.Z;
                            }

                            if (vertsNT != null)
                            {
                                vertsNT.Add(new VertexPositionNormalTextureTangent
                                {
                                    Position          = positions[k],
                                    Normal            = normals != null ? normals[k] : Vector3.UnitY,
                                    TextureCoordinate = uvs[k],
                                    Tangent           = tangents != null ? tangents[k] : Vector4.UnitW
                                });
                            }
                            else
                            {
                                vertsNC.Add(new VertexPositionNormalColor
                                {
                                    Position = positions[k],
                                    Normal   = normals != null ? normals[k] : Vector3.UnitY,
                                    Color    = colors != null ? colors[k] : Color4.White
                                });
                            }
                        }

                        indexOffset += (uint)positions.Length;
                    }
                }
            }

            if (indiciesList.Count <= 0)
            {
                return;
            }

            uint[] indicies = indiciesList.ToArray();

            // make stagedmesh with verts
            StagedMeshDraw md;

            if (vertsNT != null)
            {
                var vertsNTa = vertsNT.ToArray();
                md = StagedMeshDraw.MakeStagedMeshDraw <VertexPositionNormalTextureTangent>(ref indicies, ref vertsNTa, VertexPositionNormalTextureTangent.Layout);
            }
            else if (vertsNC != null)
            {
                var vertsNCa = vertsNC.ToArray();
                md = StagedMeshDraw.MakeStagedMeshDraw <VertexPositionNormalColor>(ref indicies, ref vertsNCa, VertexPositionNormalColor.Layout);
            }
            else
            {
                return;
            }

            Mesh m = new Mesh
            {
                Draw          = md,
                BoundingBox   = bb,
                MaterialIndex = prefabModel.Materials.Count
            };

            prefabModel.Add(m);
            if (material != null)
            {
                prefabModel.Add(material);
            }
        }