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); }
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); }
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(); } }
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); }
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); } }
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); } }
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); }