Пример #1
0
        Mesh CreateConvexHullShape(ConvexHullShape shape)
        {
            ShapeHull hull = new ShapeHull(shape);

            hull.BuildHull(shape.Margin);

            UIntArray    hullIndices = hull.Indices;
            Vector3Array points      = hull.Vertices;


            int vertexCount = hull.NumIndices;
            int faceCount   = hull.NumTriangles;

            bool index32 = vertexCount > 65536;

            Mesh mesh = new Mesh(device, faceCount, vertexCount,
                                 MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0), VertexFormat.Position | VertexFormat.Normal);


            SlimDX.DataStream indices = mesh.LockIndexBuffer(LockFlags.Discard);
            int i;

            if (index32)
            {
                for (i = 0; i < vertexCount; i++)
                {
                    indices.Write(i);
                }
            }
            else
            {
                for (i = 0; i < vertexCount; i++)
                {
                    indices.Write((short)i);
                }
            }
            mesh.UnlockIndexBuffer();

            SlimDX.DataStream verts = mesh.LockVertexBuffer(LockFlags.Discard);
            Vector3           scale = Vector3.Multiply(shape.LocalScaling, 1.0f + shape.Margin);

            for (i = 0; i < vertexCount; i += 3)
            {
                verts.Write(Vector3.Modulate(points[(int)hullIndices[i]], scale));
                verts.Position += 12;
                verts.Write(Vector3.Modulate(points[(int)hullIndices[i + 1]], scale));
                verts.Position += 12;
                verts.Write(Vector3.Modulate(points[(int)hullIndices[i + 2]], scale));
                verts.Position += 12;
            }
            mesh.UnlockVertexBuffer();

            mesh.ComputeNormals();
            shapes.Add(shape, mesh);

            return(mesh);
        }
Пример #2
0
        Mesh CreateStaticPlaneShape(StaticPlaneShape shape)
        {
            // Load shader
            if (planeShader == null)
            {
                Assembly assembly     = Assembly.GetExecutingAssembly();
                Stream   shaderStream = assembly.GetManifestResourceStream("DemoFramework.checker_shader.fx");

                planeShader = Effect.FromStream(device, shaderStream, ShaderFlags.None);
            }


            Vector3[] vertices = new Vector3[4 * 2];

            Mesh mesh = new Mesh(device, 2, 4, MeshFlags.SystemMemory, VertexFormat.Position | VertexFormat.Normal);

            Vector3 planeOrigin = shape.PlaneNormal * shape.PlaneConstant;
            Vector3 vec0, vec1;

            PlaneSpace1(shape.PlaneNormal, out vec0, out vec1);
            float size = 1000;

            Vector3[] verts = new Vector3[4]
            {
                planeOrigin + vec0 * size,
                planeOrigin - vec0 * size,
                planeOrigin + vec1 * size,
                planeOrigin - vec1 * size
            };

            SlimDX.DataStream vertexBuffer = mesh.LockVertexBuffer(LockFlags.Discard);
            vertexBuffer.Write(verts[0]);
            vertexBuffer.Position += 12;
            vertexBuffer.Write(verts[1]);
            vertexBuffer.Position += 12;
            vertexBuffer.Write(verts[2]);
            vertexBuffer.Position += 12;
            vertexBuffer.Write(verts[3]);
            vertexBuffer.Position += 12;
            mesh.UnlockVertexBuffer();

            SlimDX.DataStream indexBuffer = mesh.LockIndexBuffer(LockFlags.Discard);
            indexBuffer.Write((short)1);
            indexBuffer.Write((short)2);
            indexBuffer.Write((short)0);
            indexBuffer.Write((short)1);
            indexBuffer.Write((short)3);
            indexBuffer.Write((short)0);
            mesh.UnlockIndexBuffer();

            mesh.ComputeNormals();

            complexShapes.Add(shape, mesh);

            return(mesh);
        }
Пример #3
0
        public void RenderSoftBodyTextured(SoftBody softBody)
        {
            if (!(softBody.UserObject is Array))
            {
                return;
            }

            object[]   userObjArr   = softBody.UserObject as object[];
            FloatArray vertexBuffer = userObjArr[0] as FloatArray;
            IntArray   indexBuffer  = userObjArr[1] as IntArray;

            int vertexCount = (vertexBuffer.Count / 8);

            if (vertexCount > 0)
            {
                int faceCount = indexBuffer.Count / 2;

                bool index32 = vertexCount > 65536;

                Mesh mesh = new Mesh(device, faceCount, vertexCount,
                                     MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0),
                                     VertexFormat.Position | VertexFormat.Normal | VertexFormat.Texture1);

                SlimDX.DataStream indices = mesh.LockIndexBuffer(LockFlags.Discard);
                if (index32)
                {
                    foreach (int i in indexBuffer)
                    {
                        indices.Write(i);
                    }
                }
                else
                {
                    foreach (int i in indexBuffer)
                    {
                        indices.Write((short)i);
                    }
                }
                mesh.UnlockIndexBuffer();

                SlimDX.DataStream verts = mesh.LockVertexBuffer(LockFlags.Discard);
                foreach (float f in vertexBuffer)
                {
                    verts.Write(f);
                }
                mesh.UnlockVertexBuffer();

                mesh.ComputeNormals();
                mesh.DrawSubset(0);
                mesh.Dispose();
            }
        }
Пример #4
0
        Mesh CreateTriangleMeshShape(TriangleMeshShape shape)
        {
            StridingMeshInterface meshInterface = shape.MeshInterface;

            BulletSharp.DataStream verts, indices;
            int           numVerts, numFaces;
            PhyScalarType vertsType, indicesType;
            int           vertexStride, indexStride;

            meshInterface.GetLockedReadOnlyVertexIndexData(out verts, out numVerts, out vertsType, out vertexStride,
                                                           out indices, out indexStride, out numFaces, out indicesType);

            bool index32 = numVerts > 65536;

            Mesh mesh = new Mesh(device, numFaces, numVerts,
                                 MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0), VertexFormat.Position | VertexFormat.Normal);

            SlimDX.DataStream data = mesh.LockVertexBuffer(LockFlags.None);
            while (verts.Position < verts.Length)
            {
                Vector3 v = verts.Read <Vector3>();
                data.Write(v);

                verts.Position += vertexStride - 12;

                // Normals will be calculated later
                data.Position += 12;
            }
            mesh.UnlockVertexBuffer();

            data = mesh.LockIndexBuffer(LockFlags.None);
            while (indices.Position < indices.Length)
            {
                int index = indices.Read <int>();
                if (index32)
                {
                    data.Write(index);
                }
                else
                {
                    data.Write((short)index);
                }
            }
            mesh.UnlockVertexBuffer();

            mesh.ComputeNormals();

            shapes.Add(shape, mesh);
            return(mesh);
        }
Пример #5
0
        Mesh CreateGImpactMeshShape(GImpactMeshShape shape)
        {
            BulletSharp.DataStream verts, indices;
            int           numVerts, numFaces;
            PhyScalarType vertsType, indicesType;
            int           vertexStride, indexStride;

            shape.MeshInterface.GetLockedReadOnlyVertexIndexData(out verts, out numVerts, out vertsType, out vertexStride,
                                                                 out indices, out indexStride, out numFaces, out indicesType);

            bool index32 = numVerts > 65536;

            Mesh mesh = new Mesh(device, numFaces, numVerts,
                                 MeshFlags.SystemMemory | (index32 ? MeshFlags.Use32Bit : 0), VertexFormat.Position | VertexFormat.Normal);

            SlimDX.DataStream vertexBuffer = mesh.LockVertexBuffer(LockFlags.Discard);
            while (vertexBuffer.Position < vertexBuffer.Length)
            {
                vertexBuffer.Write(verts.Read <Vector3>());
                vertexBuffer.Position += 12;
            }
            mesh.UnlockVertexBuffer();

            SlimDX.DataStream indexBuffer = mesh.LockIndexBuffer(LockFlags.Discard);
            if (index32)
            {
                while (indexBuffer.Position < indexBuffer.Length)
                {
                    indexBuffer.Write(indices.Read <int>());
                }
            }
            else
            {
                while (indexBuffer.Position < indexBuffer.Length)
                {
                    indexBuffer.Write((short)indices.Read <int>());
                }
            }
            mesh.UnlockIndexBuffer();

            mesh.ComputeNormals();
            shapes.Add(shape, mesh);

            return(mesh);
        }
        /// <summary>
        /// Creates a new instance of <see cref="D3D10VertexBufferImplementation"/> initialized with the vertex data array.
        /// </summary>
        /// <param name="renderer">The D3D10 renderer.</param>
        /// <param name="decl">The vertex declaration.</param>
        /// <param name="usage">The resource usage.</param>
        /// <param name="data">The array of vertex data.</param>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if creating the underlying D3D10 buffer or writing to it failed.</exception>
        internal D3D10VertexBufferImplementation(D3D10Renderer renderer, VertexDeclaration decl, ResourceUsage usage, params DataBuffer[] data)
            : base(decl, usage, data)
        {
            _renderer       = renderer;
            _graphicsDevice = renderer.GraphicsDevice;

            int totalSizeInBytes = base.VertexCount * decl.VertexStride;
            int vertexStride     = decl.VertexStride;

            try {
                //Now initialize the buffer with the supplied vertex store
                using (SDX.DataStream interleaved = new SDX.DataStream(totalSizeInBytes, true, true)) {
                    //Create the interleaved buffer
                    byte[] vertex = new byte[vertexStride];
                    for (int i = 0; i < base.VertexCount; i++)
                    {
                        int offset = 0;
                        for (int j = 0; j < data.Length; j++)
                        {
                            DataBuffer db          = data[j];
                            int        elementSize = db.ElementSizeInBytes;
                            db.Get(vertex, offset, elementSize);
                            offset += elementSize;
                        }
                        interleaved.Write(vertex, 0, vertexStride);
                    }
                    interleaved.Position = 0;
                    //Now create and populate appropiate D3D10 buffer
                    if (base.BufferUsage == ResourceUsage.Static)
                    {
                        D3D.ResourceUsage  rUsage    = D3D.ResourceUsage.Default;
                        D3D.CpuAccessFlags cpuAccess = D3D.CpuAccessFlags.None;
                        _buffer = new D3D.Buffer(_graphicsDevice, interleaved, new D3D.BufferDescription(totalSizeInBytes, rUsage, D3D.BindFlags.VertexBuffer, cpuAccess, D3D.ResourceOptionFlags.None));
                    }
                    else if (base.BufferUsage == ResourceUsage.Dynamic)
                    {
                        D3D.ResourceUsage  rUsage    = D3D.ResourceUsage.Dynamic;
                        D3D.CpuAccessFlags cpuAccess = D3D.CpuAccessFlags.Write;
                        _buffer = new D3D.Buffer(_graphicsDevice, interleaved, new D3D.BufferDescription(totalSizeInBytes, rUsage, D3D.BindFlags.VertexBuffer, cpuAccess, D3D.ResourceOptionFlags.None));
                    }
                }

                //Add to tracker
                _renderer.Resources.AddTrackedObject(_buffer.ComPointer, this);
            } catch (Exception e) {
                Dispose();
                throw new TeslaException("Error creating D3D10 buffer: \n" + e.Message, e);
            }
        }
Пример #7
0
        public Physics(VehicleDemo game)
        {
            CollisionShape groundShape = new BoxShape(50, 3, 50);

            CollisionShapes.Add(groundShape);

            CollisionConf = new DefaultCollisionConfiguration();
            Dispatcher    = new CollisionDispatcher(CollisionConf);
            Solver        = new SequentialImpulseConstraintSolver();

            Vector3 worldMin = new Vector3(-10000, -10000, -10000);
            Vector3 worldMax = new Vector3(10000, 10000, 10000);

            Broadphase = new AxisSweep3(worldMin, worldMax);
            //Broadphase = new DbvtBroadphase();

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);

            int    i;
            Matrix tr;
            Matrix vehicleTr;

            if (UseTrimeshGround)
            {
                const float scale = 20.0f;

                //create a triangle-mesh ground
                int vertStride  = Vector3.SizeInBytes;
                int indexStride = 3 * sizeof(int);

                const int NUM_VERTS_X = 20;
                const int NUM_VERTS_Y = 20;
                const int totalVerts  = NUM_VERTS_X * NUM_VERTS_Y;

                const int totalTriangles = 2 * (NUM_VERTS_X - 1) * (NUM_VERTS_Y - 1);

                TriangleIndexVertexArray vertexArray = new TriangleIndexVertexArray();
                IndexedMesh mesh = new IndexedMesh();
                mesh.Allocate(totalVerts, vertStride, totalTriangles, indexStride, PhyScalarType.Int32, PhyScalarType.Single);

                BulletSharp.DataStream data = mesh.LockVerts();
                for (i = 0; i < NUM_VERTS_X; i++)
                {
                    for (int j = 0; j < NUM_VERTS_Y; j++)
                    {
                        float wl     = .2f;
                        float height = 20.0f * (float)(Math.Sin(i * wl) * Math.Cos(j * wl));

                        data.Write((i - NUM_VERTS_X * 0.5f) * scale);
                        data.Write(height);
                        data.Write((j - NUM_VERTS_Y * 0.5f) * scale);
                    }
                }

                int      index = 0;
                IntArray idata = mesh.TriangleIndices;
                for (i = 0; i < NUM_VERTS_X - 1; i++)
                {
                    for (int j = 0; j < NUM_VERTS_Y - 1; j++)
                    {
                        idata[index++] = j * NUM_VERTS_X + i;
                        idata[index++] = j * NUM_VERTS_X + i + 1;
                        idata[index++] = (j + 1) * NUM_VERTS_X + i + 1;

                        idata[index++] = j * NUM_VERTS_X + i;
                        idata[index++] = (j + 1) * NUM_VERTS_X + i + 1;
                        idata[index++] = (j + 1) * NUM_VERTS_X + i;
                    }
                }

                vertexArray.AddIndexedMesh(mesh);
                groundShape = new BvhTriangleMeshShape(vertexArray, true);

                tr        = Matrix.Identity;
                vehicleTr = Matrix.Translation(0, -2, 0);
            }
            else
            {
                // Use HeightfieldTerrainShape

                int width = 40, length = 40;
                //int width = 128, length = 128; // Debugging is too slow for this
                float   maxHeight   = 10.0f;
                float   heightScale = maxHeight / 256.0f;
                Vector3 scale       = new Vector3(20.0f, maxHeight, 20.0f);

                //PhyScalarType scalarType = PhyScalarType.PhyUChar;
                //FileStream file = new FileStream(heightfieldFile, FileMode.Open, FileAccess.Read);

                // Use float data
                PhyScalarType scalarType = PhyScalarType.Single;
                byte[]        terr       = new byte[width * length * 4];
                MemoryStream  file       = new MemoryStream(terr);
                BinaryWriter  writer     = new BinaryWriter(file);
                for (i = 0; i < width; i++)
                {
                    for (int j = 0; j < length; j++)
                    {
                        writer.Write((float)((maxHeight / 2) + 4 * Math.Sin(j * 0.5f) * Math.Cos(i)));
                    }
                }
                writer.Flush();
                file.Position = 0;

                HeightfieldTerrainShape heightterrainShape = new HeightfieldTerrainShape(width, length,
                                                                                         file, heightScale, 0, maxHeight, upIndex, scalarType, false);
                heightterrainShape.SetUseDiamondSubdivision(true);

                groundShape = heightterrainShape;
                groundShape.LocalScaling = new Vector3(scale.X, 1, scale.Z);

                tr        = Matrix.Translation(new Vector3(-scale.X / 2, scale.Y / 2, -scale.Z / 2));
                vehicleTr = Matrix.Translation(new Vector3(20, 3, -3));


                // Create graphics object

                file.Position = 0;
                BinaryReader reader = new BinaryReader(file);

                int totalTriangles = (width - 1) * (length - 1) * 2;
                int totalVerts     = width * length;

                game.groundMesh = new Mesh(game.Device, totalTriangles, totalVerts,
                                           MeshFlags.SystemMemory | MeshFlags.Use32Bit, VertexFormat.Position | VertexFormat.Normal);
                SlimDX.DataStream data = game.groundMesh.LockVertexBuffer(LockFlags.None);
                for (i = 0; i < width; i++)
                {
                    for (int j = 0; j < length; j++)
                    {
                        float height;
                        if (scalarType == PhyScalarType.Single)
                        {
                            // heightScale isn't applied internally for float data
                            height = reader.ReadSingle();
                        }
                        else if (scalarType == PhyScalarType.Byte)
                        {
                            height = file.ReadByte() * heightScale;
                        }
                        else
                        {
                            height = 0.0f;
                        }

                        data.Write((j - length * 0.5f) * scale.X);
                        data.Write(height);
                        data.Write((i - width * 0.5f) * scale.Z);

                        // Normals will be calculated later
                        data.Position += 12;
                    }
                }
                game.groundMesh.UnlockVertexBuffer();
                file.Close();

                data = game.groundMesh.LockIndexBuffer(LockFlags.None);
                for (i = 0; i < width - 1; i++)
                {
                    for (int j = 0; j < length - 1; j++)
                    {
                        // Using diamond subdivision
                        if ((j + i) % 2 == 0)
                        {
                            data.Write(j * width + i);
                            data.Write((j + 1) * width + i + 1);
                            data.Write(j * width + i + 1);

                            data.Write(j * width + i);
                            data.Write((j + 1) * width + i);
                            data.Write((j + 1) * width + i + 1);
                        }
                        else
                        {
                            data.Write(j * width + i);
                            data.Write((j + 1) * width + i);
                            data.Write(j * width + i + 1);

                            data.Write(j * width + i + 1);
                            data.Write((j + 1) * width + i);
                            data.Write((j + 1) * width + i + 1);
                        }

                        /*
                         * // Not using diamond subdivision
                         * data.Write(j * width + i);
                         * data.Write((j + 1) * width + i);
                         * data.Write(j * width + i + 1);
                         *
                         * data.Write(j * width + i + 1);
                         * data.Write((j + 1) * width + i);
                         * data.Write((j + 1) * width + i + 1);
                         */
                    }
                }
                game.groundMesh.UnlockIndexBuffer();

                game.groundMesh.ComputeNormals();
            }

            CollisionShapes.Add(groundShape);


            //create ground object
            RigidBody ground = LocalCreateRigidBody(0, tr, groundShape);

            ground.UserObject = "Ground";


            CollisionShape chassisShape = new BoxShape(1.0f, 0.5f, 2.0f);

            CollisionShapes.Add(chassisShape);

            CompoundShape compound = new CompoundShape();

            CollisionShapes.Add(compound);

            //localTrans effectively shifts the center of mass with respect to the chassis
            Matrix localTrans = Matrix.Translation(Vector3.UnitY);

            compound.AddChildShape(localTrans, chassisShape);
            RigidBody carChassis = LocalCreateRigidBody(800, Matrix.Identity, compound);

            carChassis.UserObject = "Chassis";
            //carChassis.SetDamping(0.2f, 0.2f);

            //CylinderShapeX wheelShape = new CylinderShapeX(wheelWidth, wheelRadius, wheelRadius);


            // clientResetScene();

            // create vehicle
            RaycastVehicle.VehicleTuning tuning           = new RaycastVehicle.VehicleTuning();
            IVehicleRaycaster            vehicleRayCaster = new DefaultVehicleRaycaster(World);

            vehicle = new RaycastVehicle(tuning, carChassis, vehicleRayCaster);

            carChassis.ActivationState = ActivationState.DisableDeactivation;
            World.AddAction(vehicle);


            float connectionHeight = 1.2f;
            bool  isFrontWheel     = true;

            // choose coordinate system
            vehicle.SetCoordinateSystem(rightIndex, upIndex, forwardIndex);

            Vector3   connectionPointCS0 = new Vector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius);
            WheelInfo a = vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);

            connectionPointCS0 = new Vector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius);
            vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);

            isFrontWheel       = false;
            connectionPointCS0 = new Vector3(-CUBE_HALF_EXTENTS + (0.3f * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius);
            vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);

            connectionPointCS0 = new Vector3(CUBE_HALF_EXTENTS - (0.3f * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius);
            vehicle.AddWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, isFrontWheel);


            for (i = 0; i < vehicle.NumWheels; i++)
            {
                WheelInfo wheel = vehicle.GetWheelInfo(i);
                wheel.SuspensionStiffness      = suspensionStiffness;
                wheel.WheelsDampingRelaxation  = suspensionDamping;
                wheel.WheelsDampingCompression = suspensionCompression;
                wheel.FrictionSlip             = wheelFriction;
                wheel.RollInfluence            = rollInfluence;
            }

            vehicle.RigidBody.WorldTransform = vehicleTr;
        }
        protected void InitializePrimitive()
        {
            if (materialShader == null)
                materialShader = MaterialShader.DefaultMaterial(Renderer);
            if (this.GetType() == typeof(SkinnedMeshPrimitive))
                GeometryData.VertexDefinition = MaterialShader.SkinnedMeshVertexDefinition;
            else
                GeometryData.VertexDefinition = MaterialShader.StaticMeshVertexDefinition;
            GeometryData.VertexStride = GeometryData.VertexDefinition.SizeInBytes;
            GeometryData.VertexCount = GeometryData.Vertices.Count;
            GeometryData.IndexCount = GeometryData.Indices.Count;

            DataStream VerticesStream = new DataStream(GeometryData.VertexCount * GeometryData.VertexStride, true, true);
            Vector3[] Tangent;
            Vector3[] Bitangent;
            GenerateTangentFrame(out Tangent, out Bitangent);
            for (int j = 0; j < GeometryData.Vertices.Count; j++)
            {
                Vertex v = GeometryData.Vertices[j];
                for (int i = 0; i < GeometryData.VertexDefinition.Parameters.Count; i++)
                {
                    VertexParameterType vp = GeometryData.VertexDefinition.Parameters[i];
                    if (vp == VertexParameterType.Position)
                        VerticesStream.Write(v.GetVertex<Vector3>(vp).Value);
                    else if (vp == VertexParameterType.Normal)
                        VerticesStream.Write(v.GetVertex<Vector3>(vp).Value);
                    else if (vp == VertexParameterType.TextureCoordinate)
                        VerticesStream.Write(v.GetVertex<Vector2>(vp).Value);
                    else if (vp == VertexParameterType.Tangent)
                    {
                        //VerticesStream.Write(Vector3.Normalize(Tangent[j]));
                        VerticesStream.Write(MathHelper.CalculateTangent(v.GetVertex<Vector3>(VertexParameterType.Normal).Value));
                        /*if ((j + (GeometryData.Vertices.Count % 3)) % 3 == 0 & GeometryData.Vertices.Count - (j + (GeometryData.Vertices.Count % 3)) > 2)
                        {
                            tan = MathHelper.CalculateTangent(
                            v.GetVertex<Vector3>(VertexParameterType.Position).Value,
                            GeometryData.Vertices[j + 1].GetVertex<Vector3>(VertexParameterType.Position).Value,
                            GeometryData.Vertices[j + 2].GetVertex<Vector3>(VertexParameterType.Position).Value,
                            v.GetVertex<Vector2>(VertexParameterType.TextureCoordinate).Value,
                            GeometryData.Vertices[j + 1].GetVertex<Vector2>(VertexParameterType.TextureCoordinate).Value,
                            GeometryData.Vertices[j + 2].GetVertex<Vector2>(VertexParameterType.TextureCoordinate).Value
                            );
                        }
                        Vector3 val = v.GetVertex<Vector3>(VertexParameterType.Normal).Value;
                        Vector3 vec = MathHelper.ToVector3(Vector3.Transform(val, Matrix.RotationX(MathHelper.PiOver2)));
                        if (v is VertexPosNorTexTanBin)
                        {
                            VerticesStream.Write(v.GetVertex<Vector3>(vp).Value);
                        }
                        else
                        {
                            VerticesStream.Write(MathHelper.CalculateTangent(v.GetVertex<Vector3>(VertexParameterType.Normal).Value));
                        }*/
                    }
                    else if (vp == VertexParameterType.Binormal)
                    {
                        //VerticesStream.Write(Vector3.Normalize(Bitangent[j]));
                        VerticesStream.Write(-MathHelper.CalculateTangent(v.GetVertex<Vector3>(VertexParameterType.Normal).Value));
                        /*if ((j + (GeometryData.Vertices.Count % 3)) % 3 == 0 & GeometryData.Vertices.Count - (j + (GeometryData.Vertices.Count % 3)) > 2)
                        {
                            bin = MathHelper.CalculateBitangent(
                                v.GetVertex<Vector3>(VertexParameterType.Position).Value,
                                GeometryData.Vertices[j + 1].GetVertex<Vector3>(VertexParameterType.Position).Value,
                                GeometryData.Vertices[j + 2].GetVertex<Vector3>(VertexParameterType.Position).Value,
                                v.GetVertex<Vector2>(VertexParameterType.TextureCoordinate).Value,
                                GeometryData.Vertices[j + 1].GetVertex<Vector2>(VertexParameterType.TextureCoordinate).Value,
                                GeometryData.Vertices[j + 2].GetVertex<Vector2>(VertexParameterType.TextureCoordinate).Value
                                );
                        }
                        Vector3 val = v.GetVertex<Vector3>(VertexParameterType.Normal).Value;
                        Vector3 vec = MathHelper.ToVector3(Vector3.Transform(val, Matrix.RotationZ(MathHelper.PiOver2)));
                        if (v is VertexPosNorTexTanBin)
                        {
                            VerticesStream.Write(v.GetVertex<Vector3>(vp).Value);
                        }
                        else
                        {
                            VerticesStream.Write(MathHelper.CalculateBitangent(v.GetVertex<Vector3>(VertexParameterType.Normal).Value));
                        }*/
                    }
                    else if (vp == VertexParameterType.Bones32Bit)
                    {
                        Vector4 vec = (v.GetVertex<Vector4>(vp).Value);
                        VerticesStream.Write((uint)vec.X);
                        VerticesStream.Write((uint)vec.Y);
                        VerticesStream.Write((uint)vec.Z);
                        VerticesStream.Write((uint)vec.W);
                    }
                    else if (vp == VertexParameterType.Weights)
                    {
                        Vector4 vec = (v.GetVertex<Vector4>(vp).Value);
                        VerticesStream.Write(v.GetVertex<Vector4>(vp).Value);
                    }
                    else if (vp == VertexParameterType.ColorRGB)
                        VerticesStream.Write(v.GetVertex<Vector3>(vp).Value);
                }
            }
            VerticesStream.Position = 0;
            GeometryData.VertexBuffer = new Buffer(Renderer.Device, VerticesStream, GeometryData.VertexStride * GeometryData.VertexCount,
                ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, GeometryData.VertexStride);

            DataStream IndicesStream = new DataStream(GeometryData.Indices.ToArray(), true, true);
            IndicesStream.Position = 0;

            GeometryData.IndexBuffer = new Buffer(Renderer.Device, IndicesStream, sizeof(ushort) * GeometryData.IndexCount,
                ResourceUsage.Default, BindFlags.IndexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, sizeof(ushort));

            IndicesStream.Close();
            VerticesStream.Close();
        }
        /// <summary>
        /// Sets the vertex data from an array source.
        /// </summary>
        /// <typeparam name="T">The type of data in the vertex buffer.</typeparam>
        /// <param name="data">Array that holds the vertex data</param>
        /// <param name="startIndex">Starting index of the element in the array at which to start copying from</param>
        /// <param name="elementCount">Number of elements to copy from the array</param>
        /// <param name="offsetInBytes">Offset in bytes from the beginning of the vertex buffer to the data.</param>
        /// <param name="vertexStride">Size of an element in bytes.</param>
        /// <param name="writeOptions">Writing options for the vertex buffer. None, discard, or no overwrite.</param>
        /// <exception cref="System.ObjectDisposedException">Thrown if Dispose() has been called.</exception>
        /// <exception cref="System.InvalidOperationException">Thrown if the write options are incompatible with the resource usage of the buffer.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the data's vertex stride is too small, the offset in bytes is out of range,
        /// or the byte offset and number of elements to write will cause overflow.</exception>
        /// <exception cref="Tesla.Core.TeslaException">Thrown if there was an error writing to the buffer.</exception>
        public override void SetData <T>(T[] data, int startIndex, int elementCount, int offsetInBytes, int vertexStride, DataWriteOptions writeOptions)
        {
            if (_buffer == null || _buffer.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            //Throw an error if an invalid write options is specified
            if (base.BufferUsage == ResourceUsage.Static && writeOptions != DataWriteOptions.None)
            {
                throw new InvalidOperationException("Can only specify write options other than DataWriteOptions.None for dynamic vertex buffers.");
            }

            //Check if array bounds are out of range
            D3D10Helper.CheckArrayBounds(data, startIndex, elementCount);

            VertexDeclaration vertexDecl = base.VertexDeclaration;
            int vertexCount = base.VertexCount;

            int vbSize     = vertexCount * vertexDecl.VertexStride;
            int elemSize   = MemoryHelper.SizeOf <T>();
            int dataSize   = elementCount * elemSize;
            int vertexStep = vertexStride;

            if (vertexStride != 0)
            {
                vertexStep -= elemSize;
                if (vertexStep < 0)
                {
                    throw new ArgumentOutOfRangeException("vertexStride", "Vertex stride is too small for requested data size.");
                }
                //If we get this far, we need to make sure the actual bytes we're going to look at matches up,
                //since we can grab specific parts of a vertex and not the whole thing
                if (elementCount > 1)
                {
                    dataSize = ((elementCount - 1) * vertexStep) + dataSize;
                }
            }

            //Prevent overflow out of range errors
            if ((offsetInBytes < 0) || (offsetInBytes > vbSize))
            {
                throw new ArgumentOutOfRangeException("offsetInbytes", "Byte offset is out of range.");
            }

            if ((offsetInBytes + dataSize) > vbSize)
            {
                throw new ArgumentOutOfRangeException("data", "Byte offset and elements to write will cause in buffer overflow.");
            }

            //Create scratch buffer, if it hasn't been created already
            bool usesStaging = false;

            if (base.BufferUsage == ResourceUsage.Static || writeOptions == DataWriteOptions.None)
            {
                CreateStaging();
                usesStaging = true;
            }

            try {
                if (usesStaging)
                {
                    //If we're not going to be writing the entire vertex structure, we need to first
                    //copy the contents of the affected vertex data into the staging buffer
                    if (vertexStep != vertexStride)
                    {
                        //If we're going to be working with all the verts, no need to copy a subresource region
                        if (offsetInBytes == 0 && startIndex == 0 && vertexCount == data.Length)
                        {
                            _graphicsDevice.CopyResource(_buffer, _staging);
                        }
                        else
                        {
                            D3D.ResourceRegion region = new D3D.ResourceRegion();
                            region.Left  = offsetInBytes;
                            region.Right = offsetInBytes + dataSize;
                            region.Front = region.Top = 0;
                            region.Back  = region.Bottom = 1;
                            _graphicsDevice.CopySubresourceRegion(_buffer, 0, region, _staging, 0, offsetInBytes, 0, 0);
                        }
                    }

                    using (SDX.DataStream ds = _staging.Map(D3D.MapMode.Read, D3D.MapFlags.None)) {
                        //If the step is zero, that means we're dealing with the entire vertex and not a subset of it
                        if (vertexStep == 0)
                        {
                            ds.Position = offsetInBytes;
                            ds.WriteRange <T>(data, startIndex, elementCount);
                        }
                        else
                        {
                            ds.Position = offsetInBytes;
                            int count = elementCount - 1;
                            int index = startIndex;
                            ds.Write <T>(data[index++]);
                            while (count > 0)
                            {
                                ds.Position += vertexStep;
                                ds.Write <T>(data[index]);
                                count--;
                                index++;
                            }
                        }
                        _staging.Unmap();

                        //If we're writing to the entire VB just copy the whole thing
                        if (offsetInBytes == 0 && startIndex == 0 && dataSize == vbSize)
                        {
                            _graphicsDevice.CopyResource(_staging, _buffer);
                        }
                        else
                        {
                            D3D.ResourceRegion region = new D3D.ResourceRegion();
                            region.Left  = offsetInBytes;
                            region.Right = offsetInBytes + dataSize;
                            region.Front = region.Top = 0;
                            region.Back  = region.Bottom = 1;
                            _graphicsDevice.CopySubresourceRegion(_staging, 0, region, _buffer, 0, offsetInBytes, 0, 0);
                        }
                    }
                    //Dynamic vertex buffers only
                }
                else
                {
                    D3D.MapMode mode = (writeOptions == DataWriteOptions.Discard) ? D3D.MapMode.WriteDiscard : D3D.MapMode.WriteNoOverwrite;
                    using (SDX.DataStream ds = _buffer.Map(mode, D3D.MapFlags.None)) {
                        //If the step is zero, that means we're dealing with the entire vertex and not a subset of it
                        if (vertexStep == 0)
                        {
                            ds.Position = offsetInBytes;
                            ds.WriteRange <T>(data, startIndex, elementCount);
                        }
                        else
                        {
                            ds.Position = offsetInBytes;
                            int count = elementCount - 1;
                            int index = startIndex;
                            ds.Write <T>(data[index++]);
                            while (count > 0)
                            {
                                ds.Position += vertexStep;
                                ds.Write <T>(data[index]);
                                count--;
                                index++;
                            }
                        }
                        _buffer.Unmap();
                    }
                }
            } catch (Exception e) {
                throw new TeslaException("Error reading from D3D10 Buffer.", e);
            }
        }
        /// <summary>
        /// Convienence method that takes an array of data buffers, each representing a vertex element (in the order
        /// declared by the vertex declaration), and writes all of the data to the vertex buffer. The buffers must match
        /// the vertex declaration as well as the byte sizes of each element and all be of the same length.
        /// </summary>
        /// <param name="data">Array of databuffers representing the vertex data.</param>
        /// <exception cref="System.ArgumentNullException">Thrown if data is null.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the number of buffers do not match the number
        /// of vertex elements, or if the number of vertices in each buffer does not match the vertex count,
        /// or if there is a byte size mismatch of any kind.</exception>
        public override void SetInterleavedData(params DataBuffer[] data)
        {
            if (_buffer == null || _buffer.Disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            if (data == null || data.Length == 0)
            {
                throw new ArgumentNullException("data", "Data cannot be null.");
            }

            VertexDeclaration vertexDecl = base.VertexDeclaration;
            int vertexCount = base.VertexCount;

            //Verify if the incoming vertex streams match right with the supplied vertex declaration
            VertexElement[] elems = vertexDecl.VertexElements;
            if (elems.Length != data.Length)
            {
                throw new ArgumentOutOfRangeException("data", "Number of vertex streams do not match up the number of declared vertex elements.");
            }

            int totalSizeInBytes = 0;
            int vertexStride     = 0;

            for (int i = 0; i < data.Length; i++)
            {
                DataBuffer    db           = data[i];
                VertexElement element      = elems[i];
                int           vSizeInBytes = db.ElementSizeInBytes;
                int           vCount       = db.SizeInBytes / vSizeInBytes;

                if (vCount != vertexCount)
                {
                    throw new ArgumentOutOfRangeException("data", "Vertex count mismatch, buffers must be of same length.");
                }
                if (vSizeInBytes != VertexDeclaration.GetVertexElementSize(element.Format))
                {
                    throw new ArgumentOutOfRangeException("data", "Supplied vertex buffer element size mismatch with actual vertex element size.");
                }

                totalSizeInBytes += db.SizeInBytes;
                vertexStride     += vSizeInBytes;
                db.Position       = 0;
            }

            if (totalSizeInBytes != vertexDecl.VertexStride * vertexCount)
            {
                throw new ArgumentOutOfRangeException("data", "Vertex data must match the size of the vertex buffer in bytes!");
            }

            CreateStaging();

            try {
                using (SDX.DataStream interleaved = _staging.Map(D3D.MapMode.Write, D3D.MapFlags.None)) {
                    byte[] vertex = new byte[vertexStride];
                    for (int i = 0; i < vertexCount; i++)
                    {
                        int startIndex = 0;
                        for (int j = 0; j < data.Length; j++)
                        {
                            DataBuffer db          = data[j];
                            int        elementSize = db.ElementSizeInBytes;
                            db.Get(vertex, startIndex, elementSize);
                            startIndex += elementSize;
                        }
                        interleaved.Write(vertex, 0, vertexStride);
                    }
                    _staging.Unmap();
                    //Copy entire resource
                    _graphicsDevice.CopyResource(_staging, _buffer);
                }
            } catch (Exception e) {
                throw new TeslaException("Error writing to D3D10 Buffer.", e);
            }
        }
Пример #11
0
        public Mesh createMesh(Device dev)
        {
            int numIndices  = 10;
            int numVertices = 5;

            Matrix4x4 Projection = new Matrix4x4(
                1, 0, 0, 0,
                0, 1, 0, 0,
                0, 0, 1, 0,
                p, p, p, 0
                );

            vertex[0] = new Vector4D(0, 0, 0, 1);
            vertex[1] = new Vector4D(-0.559, 0.559, 0.559, -0.25);
            vertex[2] = new Vector4D(0.559, -0.559, 0.559, -0.25);
            vertex[3] = new Vector4D(0.559, 0.559, -0.559, -0.25);
            vertex[4] = new Vector4D(-0.559, -0.559, -0.559, -0.25);

            for (int i = 0; i < numVertices; i++)
            {
                // scale it
                vertex[i] *= radius;

                // project it from 4d to 3d
                vertex[i] = Projection * vertex[i];

                vertex[i] = (new Vector4D(a, b, c, d)) & vertex[i] & (new Vector4D(-a, -b, -c, d));
                //FHost.Log(TLogType.Debug, "vertex " + i + " =" + vertex[i].x + ";" + vertex[i].y + ";" + vertex[i].z + ";" + vertex[i].w);
            }

            // create new Mesh
            Mesh newMesh = new Mesh(dev, numIndices, numVertices,
                                    MeshFlags.Dynamic | MeshFlags.WriteOnly,
                                    VertexFormat.Position);

            // lock buffers
            sVx = newMesh.LockVertexBuffer(LockFlags.Discard);
            sIx = newMesh.LockIndexBuffer(LockFlags.Discard);

            // write buffers
            for (int i = 0; i < numVertices; i++)
            {
                //Vector3 v = VVVV.Shared.VSlimDX.VSlimDXUtils.Vector3DToSlimDXVector3(vertex[i].xyz);
                //sVx.Write(v);

                sVx.Write((float)vertex[i].x);
                sVx.Write((float)vertex[i].y);
                sVx.Write((float)vertex[i].z);
            }

            sIx.Write <short>(0); sIx.Write <short>(1); sIx.Write <short>(2);
            sIx.Write <short>(0); sIx.Write <short>(1); sIx.Write <short>(3);
            sIx.Write <short>(0); sIx.Write <short>(1); sIx.Write <short>(4);
            sIx.Write <short>(0); sIx.Write <short>(2); sIx.Write <short>(3);
            sIx.Write <short>(0); sIx.Write <short>(2); sIx.Write <short>(4);
            sIx.Write <short>(0); sIx.Write <short>(3); sIx.Write <short>(4);
            sIx.Write <short>(1); sIx.Write <short>(2); sIx.Write <short>(3);
            sIx.Write <short>(1); sIx.Write <short>(2); sIx.Write <short>(4);
            sIx.Write <short>(1); sIx.Write <short>(3); sIx.Write <short>(4);
            sIx.Write <short>(2); sIx.Write <short>(3); sIx.Write <short>(4);

            // unlock buffers
            newMesh.UnlockIndexBuffer();
            newMesh.UnlockVertexBuffer();

            return(newMesh);
        }