private void GenericDrawBondSolidBlended(Vector3 start, Vector3 end, IMoleculeMaterial matA, IMoleculeMaterial matB, GraphicsStream data, ref long pos, int stride, int positionPos, int diffusePos) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(start.X); data.Write(start.Y); data.Write(start.Z); data.Seek(pos + stride + positionPos, SeekOrigin.Begin); data.Write(end.X); data.Write(end.Y); data.Write(end.Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); data.Seek(pos + stride + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += stride * 2; }
public void UpdateBuffer(BufferedGeometryData buffer, Vector3 viewPos, Matrix worldMat, IAtom[] atoms) { int stride = buffer.vBuffers[0].Stride; int objs = buffer.vBuffers[0].NumElements; GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); long pos = 0; foreach (IAtom atom in atoms) { // transform atom point to world-space Vector3 atomPos = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); Vector4 atomPosT = Vector3.Transform(atomPos, worldMat); // calc V to view pos Vector3 atomToView = new Vector3(atomPosT.X, atomPosT.Y, atomPosT.Z) - viewPos; atomToView.Normalize(); Vector3 atomNewPos = (atomToView * 0.3f) + atomPos; data.Seek(pos, SeekOrigin.Begin); data.Write(atomNewPos.X); data.Write(atomNewPos.Y); data.Write(atomNewPos.Z); pos += stride; } buffer.vBuffers[0].Buffer.Unlock(); }
private void DrawSolidBondBlended(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, int positionPos, int normalPos, int diffusePos, ref long pos, int stride, Matrix rotation) { // write transformed template to buffer Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); int halfWay = tfTriangles.Length / 2; for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); if (pointIdx < halfWay) { data.Write(matA.BaseColor.ToArgb()); } else { data.Write(matB.BaseColor.ToArgb()); } } pos += stride; } }
/// <summary> /// Called once per frame, the call is the entry point for animating the scene. /// </summary> protected override void FrameMove() { device.TextureState[0].BumpEnvironmentMaterial00 = 0.01f; device.TextureState[0].BumpEnvironmentMaterial01 = 0.00f; device.TextureState[0].BumpEnvironmentMaterial10 = 0.00f; device.TextureState[0].BumpEnvironmentMaterial11 = 0.01f; // We will lock the data into a stream because we // have set the data to be 'WriteOnly'. This way // we won't overwrite any data by seeking to the places // we want to write to. // In this case we want to write the first set of UV // coords (the bump map coords) to make the 'underwater' // effect GraphicsStream stm = waterBuffer.Lock(0, 0, 0); // Skip the position and normal, write our data, and skip to the next vertex stm.Seek(24, System.IO.SeekOrigin.Current); float u1 = 0.000f, v1 = 0.5f * appTime + 2.0f; stm.Write(u1); stm.Write(v1); // Skip the position and normal, write our data, and skip to the next vertex stm.Seek(32, System.IO.SeekOrigin.Current); u1 = 0.000f; v1 = 0.5f * appTime; stm.Write(u1); stm.Write(v1); // Skip the position and normal, write our data, and skip to the next vertex stm.Seek(32, System.IO.SeekOrigin.Current); u1 = 1.000f; v1 = 0.5f * appTime; stm.Write(u1); stm.Write(v1); // Skip the position and normal, write our data, and skip to the next vertex stm.Seek(32, System.IO.SeekOrigin.Current); u1 = 1.000f; v1 = 0.5f * appTime + 2.0f; stm.Write(u1); stm.Write(v1); waterBuffer.Unlock(); }
/// <summary> /// Called once per frame, the call is the entry point for animating the scene. /// </summary> protected override void FrameMove() { float fAngle = appTime / 2.0f; // Play with the volume texture coordinate GraphicsStream stm = vertex.Lock(0, 0, 0); // Seek to the correct spot and write the data for (int i = 0; i < 4; i++) { stm.Seek(24, System.IO.SeekOrigin.Current); // Seek 24 bytes into the structure stm.Write((float)(Math.Sin(fAngle) * Math.Cos(fAngle))); } vertex.Unlock(); }
public void Set3D(int left_index, int right_index) { Rectangle destRect = new Rectangle(0, 0, _size.Width, _size.Height); _device.StretchRectangle(_imageLeftList[left_index], _size, _imageBuf, destRect, TextureFilter.None); destRect.X = _size.Width; _device.StretchRectangle(_imageRightList[right_index], _size, _imageBuf, destRect, TextureFilter.None); GraphicsStream gStream = _imageBuf.LockRectangle(LockFlags.None); byte[] data = new byte[] { 0x4e, 0x56, 0x33, 0x44, //NVSTEREO_IMAGE_SIGNATURE = 0x4433564e 0x00, 0x0F, 0x00, 0x00, //Screen width * 2 = 1920*2 = 3840 = 0x00000F00; 0x38, 0x04, 0x00, 0x00, //Screen height = 1080 = 0x00000438; 0x20, 0x00, 0x00, 0x00, //dwBPP = 32 = 0x00000020; 0x02, 0x00, 0x00, 0x00 }; //dwFlags = SIH_SCALE_TO_FIT = 0x00000002; gStream.Seek(_size.Width * 2 * _size.Height * 4, System.IO.SeekOrigin.Begin); //last row gStream.Write(data, 0, data.Length); gStream.Close(); _imageBuf.UnlockRectangle(); }
private void DrawSolidBondBlended(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, int positionPos, int normalPos, int diffusePos, ref long pos, int stride, Matrix rotation) { // write transformed template to buffer Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); int halfWay = tfTriangles.Length / 2; for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); if (pointIdx < halfWay) data.Write(matA.BaseColor.ToArgb()); else data.Write(matB.BaseColor.ToArgb()); } pos += stride; } }
/// <summary> /// Sets the data for the current vertex buffers. /// </summary> /// <param name="data"></param> /// <param name="device"></param> public void setData(List <oSingleData> data, ref Device device) { if (data == null || device == null) { return; } // Clear the link vertex arrays vertexBufferLinks = null; vertexLinks = null; // Clear the status of the previous executed functions foreach (int index in executedVertexIndices) { // Clear this vertex colouring vertexFunctions[index].Color = Color.FromArgb(60, 60, 60).ToArgb(); } executedVertexIndices.Clear(); // Clear the vertex function call links vertexLinks = new CustomVertex.TransformedColored[data.Count * 2]; vertexLinksCount = 0; if (data.Count > 0) { // Convert the data //Int32[] callArray = (Int32[]) oMemoryFunctions.RawDataToObject(ref data, typeof (Int32[])); //uint[] callArray = oMemoryFunctions.ByteArrayToUintArray(ref data); // Process the new function calls) for (int i = 0; i < data.Count; i++) { // Process this function call // Load the source function address uint sourceFunctionAddress; if (directCallSourcesHash.Contains((uint)data[i].source)) { // We can perform a hash table lookup. This was probably a direct fixed offset call. sourceFunctionAddress = (uint)directCallSourcesHash[(uint)data[i].source]; } else { // We have to do a binary search lookup, this is more expensive computationally. This was probably a PE table call. int n = functionLocationsList.BinarySearch((uint)data[i].source); if (n < 0) { n = ~n - 1; } if (n < 0) { n = 0; } sourceFunctionAddress = (uint)functionLocationsList[n]; } // Load the source vertex index, or create a new vertex if needed int sourceVertexIndex; if (functionLocationsHash.Contains(sourceFunctionAddress)) { sourceVertexIndex = (int)functionLocationsHash[sourceFunctionAddress]; } else { // We need to create the vertex for this funciton sourceVertexIndex = moduleManager.addNewFunction(sourceFunctionAddress); } if (sourceVertexIndex >= 0) { // Highlight the source index function vertexFunctions[sourceVertexIndex].Color = Color.FromArgb(255, 255, 50).ToArgb(); executedVertexIndices.Add(sourceVertexIndex); } // Load the destination vertex index, or create a new vertex if needed int destinationVertexIndex; if (functionLocationsHash.Contains((uint)((oSingleData)data[i]).destination)) { destinationVertexIndex = (int)functionLocationsHash[(uint)data[i].destination]; } else { // We need to create the vertex for this funciton destinationVertexIndex = moduleManager.addNewFunction((uint)data[i].destination); } if (destinationVertexIndex >= 0) { // Highlight the destination index function vertexFunctions[destinationVertexIndex].Color = Color.FromArgb(255, 255, 50).ToArgb(); executedVertexIndices.Add(destinationVertexIndex); } // Draw the link line if (destinationVertexIndex >= 0 && sourceVertexIndex >= 0) { vertexLinks[vertexLinksCount] = new CustomVertex.TransformedColored(vertexFunctions[sourceVertexIndex].X, vertexFunctions[sourceVertexIndex].Y + 1, vertexFunctions[sourceVertexIndex].Z, vertexFunctions[sourceVertexIndex].Rhw, Color.FromArgb(150, 0, 0).ToArgb()); vertexLinks[vertexLinksCount + 1] = new CustomVertex.TransformedColored(vertexFunctions[destinationVertexIndex].X, vertexFunctions[destinationVertexIndex].Y + 1, vertexFunctions[destinationVertexIndex].Z, vertexFunctions[destinationVertexIndex].Rhw, Color.FromArgb(0, 0, 150).ToArgb()); vertexLinksCount += 2; } } } else { vertexLinksCount = 0; } // Write the function vertex buffers if (vertexFunctionsCount > 0) { CustomVertex.TransformedColored[] vertexFunctionsRange = new CustomVertex.TransformedColored[vertexFunctionsCount]; Array.Copy(vertexFunctions, vertexFunctionsRange, vertexFunctionsRange.Length); if (vertexBufferFunctions != null) { vertexBufferFunctions.Dispose(); } vertexBufferFunctions = new VertexBuffer(typeof(CustomVertex.TransformedColored), vertexFunctionsCount, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferFunctions.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(vertexFunctionsRange); vertexBufferFunctions.Unlock(); stm.Dispose(); } // Write the link line vertex buffers if (vertexLinksCount > 0) { CustomVertex.TransformedColored[] vertexLinksRange = new CustomVertex.TransformedColored[vertexLinksCount]; Array.Copy(vertexLinks, vertexLinksRange, vertexLinksRange.Length); if (vertexBufferLinks != null) { vertexBufferLinks.Dispose(); } vertexBufferLinks = new VertexBuffer(typeof(CustomVertex.TransformedColored), vertexLinksCount, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferLinks.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(vertexLinksRange); vertexBufferLinks.Unlock(); stm.Dispose(); } else { vertexBufferLinks = null; } }
//IOpsCommand public void Run(OpsContext context, OpsStatement statement) { CloneVDataArguments arguments = statement.Arguments as CloneVDataArguments; OpsConsole.WriteLine(String.Format("Cloning vertex element {0} as {1}", arguments.FriendlySrcName, arguments.FriendlyDstName)); foreach (OpsModel model in statement.GetContent(context)) { foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator()) { int srcIdx; int dstIdx; VertexElement[] OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[]; int srcUsageIdx = arguments.srcUsageIdx; if (arguments.hasSrcUsageIdx == false) { for (int i = 0; i < OldVEs.Length; i++) { if (OldVEs[i].DeclarationUsage == arguments.srcUsage) { srcUsageIdx = OldVEs[i].UsageIndex; break; } } } if (srcUsageIdx < 0) { continue; } if (!MeshDeclarationHelper.FindElement(OldVEs, arguments.srcUsage, srcUsageIdx, out srcIdx)) { throw new OpsException("Could not find source vertex element"); } int dstUsageIdxPerMesh = arguments.dstUsageIdx; if (!arguments.hasDstUsageIdx) { if (MeshDeclarationHelper.FindValidUsageIndex(OldVEs, arguments.dstUsage, out dstUsageIdxPerMesh, out dstIdx)) { throw new OpsException("Could not find open usage index for destination vertex element"); } } int copyIdx; VertexElement[] VEs = MeshDeclarationHelper.AddElement(OldVEs, OldVEs[srcIdx].DeclarationType, arguments.dstUsage, dstUsageIdxPerMesh, out copyIdx); if (!MeshDeclarationHelper.FindElement(VEs, arguments.srcUsage, srcUsageIdx, out srcIdx)) { throw new OpsException("Could not find source vertex element"); } if (!MeshDeclarationHelper.FindElement(VEs, arguments.dstUsage, dstUsageIdxPerMesh, out dstIdx)) { throw new OpsException("Could not find destination vertex element"); } Mesh newMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device); int sizeInBytes = MeshDeclarationHelper.GetTypeSize(VEs[srcIdx].DeclarationType); int srcOffset = VEs[srcIdx].Offset; int dstOffset = VEs[dstIdx].Offset; byte[] copyBuffer = new byte[sizeInBytes]; VertexBuffer vb = newMesh.VertexBuffer; GraphicsStream gs = vb.Lock(0, 0, LockFlags.None); for (int iVertex = 0; iVertex < newMesh.NumberVertices; iVertex++) { gs.Seek(newMesh.NumberBytesPerVertex * iVertex + srcOffset, SeekOrigin.Begin); gs.Read(copyBuffer, 0, sizeInBytes); gs.Seek(newMesh.NumberBytesPerVertex * iVertex + dstOffset, SeekOrigin.Begin); gs.Write(copyBuffer, 0, sizeInBytes); } vb.Unlock(); gs = null; vb = null; meshContainer.ReplaceMesh(newMesh); } } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } break; } } } // actually create the metaball triangles or points IVolume[] volumes = new IVolume[objs.Count]; int sIdx = 0; AtomShadingDesc aShading = coDesc.AtomShadingDesc; IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; foreach (IAtom atom in objs) { IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } volumes[sIdx++] = new Metaball(new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d), 0.17f, material.BaseColor); } // process volume into triangles GenericVolumeScene scene = new GenericVolumeScene(volumes); int[] triangles = null; Vector3[] vertices; Color[] colours; Vector3[] normals = null; if (!pointsOnly) { IsosurfaceGenerator3D.GenerateSimpleMesh(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, false, out triangles, out vertices, out colours); MeshOptimzer.GenerateTriPointNormals(triangles, vertices, out normals); } else { IsosurfaceGenerator3D.GenerateSimplePointOutline(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, out vertices, out colours); } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * vertices.Length, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = vertices.Length; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; if (pointsOnly) { buffer.iBuffers[0].NumPrimitives = vertices.Length; buffer.iBuffers[0].PrimType = PrimitiveType.PointList; buffer.Light = false; } else { buffer.iBuffers[0].NumPrimitives = triangles.Length / 3; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), triangles.Length, device, Usage.WriteOnly, Pool.Managed); } // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields int clr = Color.FromArgb(255, 255, 255).ToArgb(); long pos = 0; for (int i = 0; i < vertices.Length; i++) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(vertices[i].X); data.Write(vertices[i].Y); data.Write(vertices[i].Z); } if (normalPos != -1 && !pointsOnly) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(normals[i].X); data.Write(normals[i].Y); data.Write(normals[i].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(colours[i].ToArgb()); } //verts[i].Color = colours[i].ToArgb(); pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); if (!pointsOnly) { buffer.iBuffers[0].Buffer.SetData(triangles, 0, LockFlags.None); } // dispose of temp data }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; int texPos = -1; // match field locations //int[] fieldsPos = new int[fields.Length]; for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "TEXTURE0") { texPos = geomStream.FieldPositions[gf]; } //fieldsPos[i] = geomStream.FieldPositions[gf]; break; } } } int numVerts = sphereDetail1 * sphereDetail2 * 6; int numTris = sphereDetail1 * sphereDetail2 * 2; // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numVerts * objs.Count, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count * numVerts; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; buffer.iBuffers[0].NumPrimitives = objs.Count * numTris; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields bool newWay = true; if (!newWay) { // create template sphere SphereMathHelper.SphereN sphere = SphereMathHelper.CalcSphereWNormals(sphereDetail1, sphereDetail2, 1.0f, new Vector3(), true); // clone and scale template for each size required Vector3 center = new Vector3(); Dictionary <int, Vector3[]> spheres = new Dictionary <int, Vector3[]>(); AtomShadingDesc aShading = coDesc.AtomShadingDesc; //int vertsIdx = 0; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } // check for existing if (!spheres.ContainsKey(period)) { // scale template float size = period * _Scaling; Vector4[] vertices = Vector3.Transform(sphere.Positions, Matrix.Scaling(size, size, size)); Vector3[] vertices3 = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertices3[i] = new Vector3(vertices[i].X, vertices[i].Y, vertices[i].Z); } spheres.Add(period, vertices3); } Vector3[] sphereData = spheres[period]; // write to buffer IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } // copy sphere Vector3 atomSpace = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); /*Vector4 clr = new Vector4((float)material.BaseColor.R / 255f, (float)material.BaseColor.G / 255f, * (float)material.BaseColor.B / 255f, (float)material.BaseColor.A / 255f);*/ int clr = material.BaseColor.ToArgb(); for (int v = 0; v < sphereData.Length; v++) { if (positionPos != -1) { Vector3 position = sphereData[v] + atomSpace; data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(position.X); data.Write(position.Y); data.Write(position.Z); } if (texPos != -1) { data.Seek(pos + texPos, SeekOrigin.Begin); data.Write(0f); //sphere.TexCoords[v].X); data.Write(0f); //sphere.TexCoords[v].Y); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(sphere.Normals[v].X); data.Write(sphere.Normals[v].Y); data.Write(sphere.Normals[v].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); /*data.Write(clr.X); * data.Write(clr.Y); * data.Write(clr.Z); * data.Write(clr.W);*/ data.Write((Int32)clr); } pos += geomStream.Stride; } } } else { Vector3[] Positions, normals; Vector2[] texCoords; SphereMathHelper.CreateSphereTriangles(new Vector3(), 1, sphereDetail1, out Positions, out normals, out texCoords); // clone and scale template for each size required Vector3 center = new Vector3(); Dictionary <int, Vector3[]> spheres = new Dictionary <int, Vector3[]>(); AtomShadingDesc aShading = coDesc.AtomShadingDesc; int vertsIdx = 0; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } // check for existing if (!spheres.ContainsKey(period)) { // scale template float size = period * _Scaling; Vector4[] vertices = Vector3.Transform(Positions, Matrix.Scaling(size, size, size)); Vector3[] vertices3 = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertices3[i] = new Vector3(vertices[i].X, vertices[i].Y, vertices[i].Z); } spheres.Add(period, vertices3); } Vector3[] sphereData = spheres[period]; // write to buffer IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } // copy sphere Vector3 atomSpace = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); int clr = material.BaseColor.ToArgb(); for (int v = 0; v < sphereData.Length; v++) { if (positionPos != -1) { Vector3 position = sphereData[v] + atomSpace; data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(position.X); data.Write(position.Y); data.Write(position.Z); } if (texPos != -1) { data.Seek(pos + texPos, SeekOrigin.Begin); data.Write(texCoords[v].X); data.Write(texCoords[v].Y); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(normals[v].X); data.Write(normals[v].Y); data.Write(normals[v].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); /*data.Write(clr.X); * data.Write(clr.Y); * data.Write(clr.Z); * data.Write(clr.W);*/ data.Write((Int32)clr); } pos += geomStream.Stride; } } } buffer.vBuffers[0].Buffer.Unlock(); }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int sizePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "POINTSIZE") { sizePos = geomStream.FieldPositions[gf]; } break; } } } // pre-scan for index groups Dictionary <string, List <int> > groups = new Dictionary <string, List <int> >(); int aIdx = 0; foreach (IAtom atom in objs) { if (!groups.ContainsKey(atom.Symbol)) { groups[atom.Symbol] = new List <int>(); } groups[atom.Symbol].Add(aIdx++); } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(typeof(PointSprite), objs.Count, device, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count; buffer.vBuffers[0].Format = geomStream.Format; buffer.DataValidity = BufferedGeometryData.DataValidityType.View; ChemSymbolTextures cTex = ChemSymbolTextures.Instance; buffer.iBuffers = new BufferedGeometryData.IndexData[groups.Count]; int gIdx = 0; foreach (KeyValuePair <string, List <int> > group in groups) { buffer.iBuffers[gIdx] = new BufferedGeometryData.IndexData(); buffer.iBuffers[gIdx].Desc = BufferedGeometryData.IndexData.Description.Sprites; buffer.iBuffers[gIdx].NumPrimitives = group.Value.Count; buffer.iBuffers[gIdx].PrimType = PrimitiveType.PointList; buffer.iBuffers[gIdx].Textures = new Texture[] { cTex[group.Key] }; buffer.iBuffers[gIdx].Buffer = new IndexBuffer(typeof(int), group.Value.Count, device, Usage.WriteOnly, Pool.Managed); int[] indices = (int[])buffer.iBuffers[gIdx].Buffer.Lock(0, LockFlags.None); for (int i = 0; i < indices.Length; i++) { indices[i] = group.Value[i]; } buffer.iBuffers[gIdx].Buffer.Unlock(); gIdx++; } // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); AtomShadingDesc aShading = coDesc.AtomShadingDesc; long pos = 0; foreach (IAtom atom in objs) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write((float)atom.X3d); data.Write((float)atom.Y3d); data.Write((float)atom.Z3d); } if (sizePos != -1) { data.Seek(pos + sizePos, SeekOrigin.Begin); int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } data.Write((float)period * 0.2f); } pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { if (spriteTexture == null) { Stream texstm = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.Resources.Atom.PNG"); spriteTexture = TextureLoader.FromStream(device, texstm); } // fillable fields int positionPos = -1; int sizePos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "POINTSIZE") { sizePos = geomStream.FieldPositions[gf]; } break; } } } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(typeof(PointSprite), objs.Count, device, Usage.WriteOnly, geomStream.Format, Pool.Managed); /*new VertexBuffer(device, geomStream.Stride * objs.Count, * Usage.None, geomStream.Format, Pool.Managed);*/ buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Sprites; buffer.iBuffers[0].NumPrimitives = objs.Count; buffer.iBuffers[0].PrimType = PrimitiveType.PointList; buffer.iBuffers[0].Textures = new Texture[] { spriteTexture }; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); AtomShadingDesc aShading = coDesc.AtomShadingDesc; long pos = 0; foreach (IAtom atom in objs) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write((float)atom.X3d); data.Write((float)atom.Y3d); data.Write((float)atom.Z3d); } if (sizePos != -1) { data.Seek(pos + sizePos, SeekOrigin.Begin); int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } data.Write((float)period * 0.4f); } if (diffusePos != -1) { IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(material.BaseColor.ToArgb()); } pos += geomStream.Stride; } /*Dictionary<int, List<int>> atomSizeGroups = new Dictionary<int, List<int>>(); * // first split into group counts * int aIdx = 0; * foreach (IAtom[] atoms in atomSets) * { * foreach (IAtom atom in atoms) * { * int period = 1; * if (atom.Properties.ContainsKey("Period")) * period = (int)atom.Properties["Period"]; * * List<int> groupAtoms = null; * if (!atomSizeGroups.TryGetValue(period, out groupAtoms)) * atomSizeGroups.Add(period, groupAtoms = new List<int>()); * * groupAtoms.Add(aIdx++); * } * } * * int vertsIdx = 0; * Dictionary<int, List<int>>.Enumerator group = atomSizeGroups.GetEnumerator(); * sBuffer.groupLengths = new int[atomSizeGroups.Count]; * sBuffer.groupSizes = new int[atomSizeGroups.Count]; * sBuffer.groupStarts = new int[atomSizeGroups.Count]; * int bIdx = 0; * while (group.MoveNext()) * { * int groupPeriod = group.Current.Key; * List<int> groupMembers = group.Current.Value; * aIdx = 0; * int gIdx = 0; * sBuffer.groupSizes[bIdx] = groupPeriod; * sBuffer.groupStarts[bIdx] = vertsIdx; * sBuffer.groupLengths[bIdx] = groupMembers.Count; * foreach (IAtom[] atoms in atomSets) * { * foreach (IAtom atom in atoms) * { * if (aIdx == groupMembers[gIdx]) * { * IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; * IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); * IMoleculeMaterial material = null; * if (matTemp != null) * material = matTemp.BySymbol; * else * { * PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; * if (pe != null) * material = lookup.GetBySeries(pe.ChemicalSerie); * } * * atomVerts[vertsIdx].Position = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); * atomVerts[vertsIdx].Color = material.BaseColor.ToArgb(); * vertsIdx++; * gIdx++; * } * if (gIdx == groupMembers.Count) * break; * aIdx++; * } * if (gIdx == groupMembers.Count) * break; * } * bIdx++; * }*/ buffer.vBuffers[0].Buffer.Unlock(); }
private void updateAxisVertices(DISPLAY_RANGE range, float height, float yOffset) { if (device == null || functionList == null) { return; } if (!validAxis) { // Update the axis grid vertices System.Single z = 0.5f; System.Single yMin = yOffset; System.Single yMax = height + yOffset; // Pick the timescale float timecale = (range.tMax - range.tMin > 15 ? 1 : 10); // Calculate the number of vertices // 2 vertices per line. 1 main major marker per second, 9 minor markers inbetween. int numMarkers = (int)(timecale * (range.tMax - range.tMin)); verticesAxis = new CustomVertex.TransformedColored[2 * numMarkers]; // Loop through creating the markers float firstMarkerTime = ((float)((int)(timecale * range.tMin))) / timecale; for (int i = 0; i < numMarkers; i++) { Single time = i * (1 / timecale) + firstMarkerTime; // Create this axis line if ((Single)((int)time) == time) { // Major marker verticesAxis[2 * i] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)yMin), z, 1.0f, Color.FromArgb(150, 255, 150).ToArgb()); verticesAxis[2 * i + 1] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)((yMax - yMin) / 2 + yMin)), z, 1.0f, Color.FromArgb(150, 255, 150).ToArgb()); } else { // Minor Marker verticesAxis[2 * i] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)yMin), z, 1.0f, Color.FromArgb(100, 170, 100).ToArgb()); verticesAxis[2 * i + 1] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)((yMax - yMin) / 4 + yMin)), z, 1.0f, Color.FromArgb(100, 170, 100).ToArgb()); } } // Write the vertex drawing buffers if (verticesAxis.Length > 0) { if (vertexBufferAxis != null) { vertexBufferAxis.Dispose(); } vertexBufferAxis = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesAxis.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferAxis.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesAxis); vertexBufferAxis.Unlock(); } validAxis = true; } }
public override void CreateGeometryForObjects(Device device, ICollection <IBond> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; int texPos = -1; // match field locations //int[] fieldsPos = new int[fields.Length]; for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "TEXTURE0") { texPos = geomStream.FieldPositions[gf]; } //fieldsPos[i] = geomStream.FieldPositions[gf]; break; } } } // count bond orders via preview data int numActualBonds = 0; foreach (IBond bond in objs) { numActualBonds += (int)bond.Order; } int numVerts = 0; if (coDesc.BondShadingDesc.BlendEndClrs) { numVerts = numActualBonds * 2; } else { numVerts = numActualBonds * 4; } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = numVerts; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; buffer.iBuffers[0].NumPrimitives = numVerts / 2; buffer.iBuffers[0].PrimType = PrimitiveType.LineList; buffer.vBuffers[0].NumElements = numVerts; buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numVerts, Usage.WriteOnly, geomStream.Format, Pool.Managed); // write bonds to buffer Vector3 direction, directionUV; IAtom[] atoms; Vector3[] atomsPos; IMoleculeMaterial materialA, materialB; Vector3[] bondInstances = null; float midPos; BondShadingDesc bShading = coDesc.BondShadingDesc; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); long pos = 0; foreach (IBond bond in objs) { GenericBondSetup(bond, false, bShading, out direction, out directionUV, out atoms, out atomsPos, out materialA, out materialB); // calc bond positioning / instances GenericBondCalcPositions(bond, bShading, direction, directionUV, atoms, atomsPos, 0.1f, out bondInstances, out midPos, true); // draw bond instances for (int bInst = 0; bInst < bondInstances.Length; bInst += 2) { if (bShading.BlendEndClrs) { GenericDrawBondSolidBlended(bondInstances[bInst], bondInstances[bInst + 1], materialA, materialB, data, ref pos, geomStream.Stride, positionPos, diffusePos); //GenericDrawBondDashedBlended(bondInstances[bInst], bondInstances[bInst + 1], // materialA, materialB); } else { Vector3 sectA = directionUV * midPos; // convert into points (2 lines) if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(bondInstances[bInst].X); data.Write(bondInstances[bInst].Y); data.Write(bondInstances[bInst].Z); data.Seek(pos + geomStream.Stride + positionPos, SeekOrigin.Begin); Vector3 p = bondInstances[bInst] + sectA; data.Write(p.X); data.Write(p.Y); data.Write(p.Z); data.Seek(pos + geomStream.Stride + geomStream.Stride + positionPos, SeekOrigin.Begin); data.Write(p.X); data.Write(p.Y); data.Write(p.Z); data.Seek(pos + geomStream.Stride + geomStream.Stride + geomStream.Stride + positionPos, SeekOrigin.Begin); data.Write(bondInstances[bInst + 1].X); data.Write(bondInstances[bInst + 1].Y); data.Write(bondInstances[bInst + 1].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); int clr = materialA.BaseColor.ToArgb(); data.Write(clr); data.Seek(pos + geomStream.Stride + diffusePos, SeekOrigin.Begin); data.Write(clr); clr = materialB.BaseColor.ToArgb(); data.Seek(pos + geomStream.Stride + geomStream.Stride + diffusePos, SeekOrigin.Begin); data.Write(clr); data.Seek(pos + geomStream.Stride + geomStream.Stride + geomStream.Stride + diffusePos, SeekOrigin.Begin); data.Write(clr); } pos += geomStream.Stride * 4; } } } buffer.vBuffers[0].Buffer.Unlock(); }
//IOpsCommand public void Run(OpsContext context, OpsStatement statement) { OpsConsole.WriteLine("Cleaning models"); foreach (OpsModel model in statement.GetContent(context)) { foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator()) { string errorsAndWarnings; meshContainer.MeshData.Mesh.Validate(meshContainer.GetAdjacencyStream(), out errorsAndWarnings); if (errorsAndWarnings == null || errorsAndWarnings.Length == 0) { continue; } else { OpsConsole.WriteLine("Cleaning '{0}'", meshContainer.FriendlyName(model)); OpsConsole.WriteLine(errorsAndWarnings); } VertexElement[] OldVEs = null; int offsetOfIndex = -1; Mesh dirtyMesh = meshContainer.MeshData.Mesh; if (meshContainer.SkinInformation != null) { int psizeUsageIdx = -1; int remapIdx = -1; OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[]; if (!MeshDeclarationHelper.FindValidUsageIndex(OldVEs, DeclarationUsage.PointSize, out psizeUsageIdx)) { throw new OpsException("Could not add remapping-indexing vertex element to declaration"); } VertexElement[] VEs = MeshDeclarationHelper.AddElement(OldVEs, DeclarationType.Float1, DeclarationUsage.PointSize, psizeUsageIdx, out remapIdx); dirtyMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device); offsetOfIndex = VEs[remapIdx].Offset; VertexBuffer vb = dirtyMesh.VertexBuffer; GraphicsStream gs = vb.Lock(0, 0, LockFlags.None); for (int iVertex = 0; iVertex < dirtyMesh.NumberVertices; iVertex++) { gs.Seek(dirtyMesh.NumberBytesPerVertex * iVertex + offsetOfIndex, SeekOrigin.Begin); gs.Write(iVertex); } vb.Unlock(); gs = null; vb = null; } int[] adjOut; Mesh cleanedMesh = Mesh.Clean(CleanType.BackFacing | CleanType.BowTies, dirtyMesh, meshContainer.GetAdjacency(), out adjOut, out errorsAndWarnings); if (errorsAndWarnings != null && errorsAndWarnings.Length != 0) { OpsConsole.WriteLine("Remaining Errors and Warnings:"); OpsConsole.WriteLine(errorsAndWarnings); } if (meshContainer.SkinInformation != null) { int[] vertexRemap = new int[cleanedMesh.NumberVertices]; VertexBuffer vb = cleanedMesh.VertexBuffer; GraphicsStream gs = vb.Lock(0, 0, LockFlags.None); for (int iVertex = 0; iVertex < cleanedMesh.NumberVertices; iVertex++) { gs.Seek(cleanedMesh.NumberBytesPerVertex * iVertex + offsetOfIndex, SeekOrigin.Begin); vertexRemap[iVertex] = (int)gs.Read(typeof(int)); } vb.Unlock(); meshContainer.RemapSkin(vertexRemap); cleanedMesh = cleanedMesh.Clone(cleanedMesh.Options.Value, OldVEs, cleanedMesh.Device); } meshContainer.SetAdjacency(adjOut); meshContainer.ReplaceMesh(cleanedMesh); } } }
private void DrawSolidBondDistinct(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, float xyScale, float bLen2, Matrix rotation, Vector3 bondInstance1, Vector3 directionUV, float midPos, int positionPos, int normalPos, int diffusePos, ref long pos, int stride) { // side 1 Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal.Normalize(); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); } pos += stride; } // side 2 final = Matrix.Scaling(xyScale, xyScale, bLen2) * rotation * Matrix.Translation(bondInstance1 + (directionUV * midPos)); tfTriangles = Vector3.Transform(tCylinderPoints, final); for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal.Normalize(); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += stride; } }
private void updateCursorVertices(double cursorTime, double cursorWidth, DISPLAY_RANGE range, float height, float yOffset, bool hasCursor) { if (device == null || functionList == null) { return; } if (!validCursor) { System.Single yMin = 2 + yOffset; System.Single yMax = height - 2 + yOffset; // If the cursor is in this row, tell the main visualization to redraw with our cursor data. if (hasCursor) { // Gather the data List <oSingleData> data; if (functionList != null) { data = functionList.getDataRange(cursorTime, cursorWidth); } else { data = new List <oSingleData>(0); } // Now tell the main visualization to redraw mainVisualization.update(data); // Create the vertex buffer for the current mouse location if (verticesCursor == null) { // Initialize the vertices verticesCursor = new CustomVertex.TransformedColored[2 * 5]; for (int n = 0; n < verticesCursor.Length; n++) { verticesCursor[n] = new CustomVertex.TransformedColored(0.0f, 0.0f, 0.4f, 1.0f, Color.FromArgb(255, 255, 0).ToArgb()); } } // Set the vertice positions int i = 0; float xEnd = (float)((cursorTime - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin; float xStart = (float)((cursorTime - cursorWidth - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin; verticesCursor[i].X = xEnd - 3; verticesCursor[i++].Y = yMin; verticesCursor[i].X = xEnd + 3; verticesCursor[i++].Y = yMin; verticesCursor[i].X = xEnd - 3; verticesCursor[i++].Y = yMax; verticesCursor[i].X = xEnd + 3; verticesCursor[i++].Y = yMax; verticesCursor[i].X = xEnd; verticesCursor[i++].Y = yMin; verticesCursor[i].X = xEnd; verticesCursor[i++].Y = yMax; verticesCursor[i].X = xStart; verticesCursor[i++].Y = (yMax - yMin) / 2 + yMin; verticesCursor[i].X = xEnd; verticesCursor[i++].Y = (yMax - yMin) / 2 + yMin; verticesCursor[i].X = xStart; verticesCursor[i++].Y = (yMax - yMin) * 0.4f + yMin; verticesCursor[i].X = xStart; verticesCursor[i++].Y = (yMax - yMin) * 0.6f + yMin; // Write the vertex drawing buffers if (vertexBufferCursor != null) { vertexBufferCursor.Dispose(); } vertexBufferCursor = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesCursor.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferCursor.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesCursor); vertexBufferCursor.Unlock(); } else { // Cursor is not in this row vertexBufferCursor = null; } validCursor = true; } }
private void updateMouseVertices(int x, int y, double cursorWidth, DISPLAY_RANGE range, float height, float yOffset) { if (device == null || functionList == null) { return; } if (!validMouse) { System.Single yMin = yOffset; System.Single yMax = height + yOffset; // Check if the cursor is in this row bool inRow = false; if (y >= (int)yMin && y <= (int)yMax) { inRow = true; } // Set the mouse text values mouseTextPos = new Point(x + 2, (int)yMin + 3); mouseNumCalls = functionList.getDataSize( ((double)(x - range.xMin) / (double)(range.xMax - range.xMin)) * (range.tMax - range.tMin) + range.tMin, cursorWidth); if (inRow) { // Initialize the vertices verticesMouse = new CustomVertex.TransformedColored[4]; for (int n = 0; n < verticesMouse.Length; n++) { verticesMouse[n] = new CustomVertex.TransformedColored(0.0f, 0.0f, 0.0f, 1.0f, Color.FromArgb(0, 255, 0). ToArgb()); } // Set the vertice positions int i = 0; verticesMouse[i].X = x + 2; verticesMouse[i].Y = yMin; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x + 2; verticesMouse[i].Y = yMax; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x - 2; verticesMouse[i].Y = yMin; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x - 2; verticesMouse[i].Y = yMax; verticesMouse[i++].Z = 0.4f; } else { // Create the vertex buffer for the current mouse location // Initialize the vertices verticesMouse = new CustomVertex.TransformedColored[2]; for (int n = 0; n < verticesMouse.Length; n++) { verticesMouse[n] = new CustomVertex.TransformedColored(0.0f, 0.0f, 0.0f, 1.0f, Color.FromArgb(0, 100, 0). ToArgb()); } // Set the vertice positions int i = 0; verticesMouse[i].X = x; verticesMouse[i].Y = yMin; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x; verticesMouse[i].Y = yMax; verticesMouse[i++].Z = 0.4f; } // Write the vertex drawing buffers if (vertexBufferMouse != null) { vertexBufferMouse.Dispose(); } vertexBufferMouse = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesMouse.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferMouse.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesMouse); vertexBufferMouse.Unlock(); validMouse = true; } }
private void updateLogPlotVertices(DISPLAY_RANGE range, float height, float yOffset, double cursorTime, double cursorWidth) { // Check that we have a valid device if (device != null && functionList != null) { // Load the data List <oSingleData> rawData = this.functionList.getData(); if (rawData != null && rawData.Count > 0) { if (!validLogPlot || lastCallCount != rawData.Count || vertexBufferLogPlot == null || vertexBufferLogPlot.Disposed || range.tMax != lastTime) { // Update the main visualizataion to show the new data // Gather the data List <oSingleData> data = functionList.getDataRange(range.tMax, cursorWidth * 2);; //List<oSingleData> data = functionList.getDataRange(range.tMax, range.tMax - lastTime); ; // Now tell the main visualization to redraw mainVisualization.update(data); // Calculate the viewing range information validAxis = false; lastTime = range.tMax; System.Single z = 0.5f; System.Single yMin = 1 + yOffset; System.Single yMax = height - 1 + yOffset; // Create a value array to go with the vertexes double[] functionCount = new double[(int)((range.tMaxDataset - range.tMinDataset) / timeWidth + 0.5)]; double[] times = new double[functionCount.Length]; for (int i = 0; i < functionCount.Count(); i++) { functionCount[i] = 0; times[i] = 0; } // Loop through the time, calculating the call count associated with each time frame double maxFunctionCount = 0; int index = 0; for (int i = 0; i < functionCount.Count(); i++) { // Process this time step int tmpCount = this.functionList.getDataSize(i * timeWidth + range.tMinDataset, timeWidth); // This time index record is associated with this vertex double count = Math.Log10(tmpCount + 1); double nextCount = 0.0; if (i + 2 < functionCount.Count()) { // Calculate the next count nextCount = Math.Log10(this.functionList.getDataSize((i + 1) * timeWidth + range.tMinDataset, timeWidth) + 1); } if (count < 0) { count = 0; } if (nextCount < 0) { nextCount = 0; } if ((index == 0 || functionCount[index - 1] != count) || (nextCount != count) || index == functionCount.Length - 1) { // Create a new vertex functionCount[index] = count; // Set the time for this call times[index] = i * timeWidth + range.tMinDataset; if (functionCount[index] > maxFunctionCount) { maxFunctionCount = functionCount[index]; } index++; } } // Generate the log-graph verticesLogPlot if (maxFunctionCount <= 1) { maxFunctionCount = 1; } // Initialize the vertex array verticesLogPlot = new CustomVertex.TransformedColored[index + 2]; // Generate the log-scale frequency plot verticesLogPlot System.Single x; System.Single y; for (int i = 0; i < index; i++) { // Generate this vertex x = (float)((((double)times[i] - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin); y = (float)((yMin - yMax) * (functionCount[i] / maxFunctionCount) + yMax); verticesLogPlot[i] = new CustomVertex.TransformedColored((float)((int)(x)), (float)((int)y), z, 1.0f, Color.FromArgb(255, 255, 255).ToArgb()); } // Create the last two vertices x = (float)range.xMax; y = (float)yMax; verticesLogPlot[index] = new CustomVertex.TransformedColored((float)((int)(x)), (float)((int)y), z, 1.0f, Color.FromArgb(255, 255, 255).ToArgb()); verticesLogPlot[index + 1] = new CustomVertex.TransformedColored((float)((int)(x)), (float)(10000000000), z, 1.0f, Color.FromArgb(0, 0, 0).ToArgb()); // Setup the vertex buffer if (vertexBufferLogPlot != null) { vertexBufferLogPlot.Dispose(); } vertexBufferLogPlot = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesLogPlot.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); lastCallCount = rawData.Count; try { GraphicsStream stm = vertexBufferLogPlot.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesLogPlot); vertexBufferLogPlot.Unlock(); } catch (Exception ex) { // Do nothing } } validLogPlot = true; } else { // An empty dataset vertexBufferLogPlot = null; } } }
private void updateSelectionVertices(double selectStart, double selectEnd, DISPLAY_RANGE range, float height, float yOffset, bool isSelected) { if (device == null || functionList == null) { return; } if (!validSelection) { int colour; if (isSelected) { colour = Color.FromArgb(80, 80, 80).ToArgb(); // A bit lighter gray } else { colour = Color.FromArgb(40, 40, 40).ToArgb(); // Very dark gray } // Update the selection vertices verticesSelectionBackground = new CustomVertex.TransformedColored[3 * 2]; // Two triangles for a box. // General parameters System.Single z = 0.5f; System.Single yMin = yOffset; System.Single yMax = height + yOffset; int i = 0; // Draw the background verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectStart - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMin, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectEnd - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMin, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectEnd - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMax, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectStart - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMin, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectStart - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMax, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectEnd - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMax, z, 1.0f, colour); if (vertexBufferSelectionBackground != null) { vertexBufferSelectionBackground.Dispose(); } vertexBufferSelectionBackground = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesSelectionBackground.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferSelectionBackground.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesSelectionBackground); vertexBufferSelectionBackground.Unlock(); validSelection = true; } }
public override void CreateGeometryForObjects(Device device, ICollection <IBond> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; int texPos = -1; // match field locations //int[] fieldsPos = new int[fields.Length]; for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "TEXTURE0") { texPos = geomStream.FieldPositions[gf]; } //fieldsPos[i] = geomStream.FieldPositions[gf]; break; } } } // count bond orders via preview data int numActualBonds = 0; foreach (IBond bond in objs) { numActualBonds += (int)bond.Order; } if (!coDesc.BondShadingDesc.BlendEndClrs) { numActualBonds *= 2; } int numTriangles = objs.Count * (numSides * 2); SphereMathHelper.EndType endType = SphereMathHelper.EndType.Open; float offset = 0.0f; switch (coDesc.BondShadingDesc.EndType) { case BondShadingDesc.BondEndTypes.Open: break; case BondShadingDesc.BondEndTypes.Closed: numTriangles += numActualBonds * (numSides * 2); endType = SphereMathHelper.EndType.Flat; break; case BondShadingDesc.BondEndTypes.Point: offset = 0.05f; numTriangles += numActualBonds * (numSides * 2); endType = SphereMathHelper.EndType.Flat; break; case BondShadingDesc.BondEndTypes.Rounded: offset = 0.075f; numTriangles += numActualBonds * (numSides * 6); endType = SphereMathHelper.EndType.Rounded; break; } // build template bond Vector3[] tCylinderPoints, tCylinderEndPoints1, tCylinderEndPoints2; Vector3[] tCylinderNormals, tCylinderEndNormals1, tCylinderEndNormals2; int[] tCylinderTris, tCylinderEndTris1, tCylinderEndTris2; SphereMathHelper.CalcCylinderTriangles(numSides, 1, 1.0f, new Vector3(0, 0, 0), new Vector3(0, 0, 1), true, endType, offset, out tCylinderPoints, out tCylinderNormals, out tCylinderTris, out tCylinderEndPoints1, out tCylinderEndNormals1, out tCylinderEndTris1, out tCylinderEndPoints2, out tCylinderEndNormals2, out tCylinderEndTris2); int numActualVerts = tCylinderPoints.Length + tCylinderEndPoints1.Length + tCylinderEndPoints2.Length; int numActualTris = tCylinderTris.Length + tCylinderEndTris1.Length + tCylinderEndTris2.Length; // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = numActualVerts; buffer.vBuffers[0].Format = geomStream.Format; buffer.vBuffers[0].NumElements = numActualVerts * numActualBonds; buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numActualTris * numActualBonds * 3, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; buffer.iBuffers[0].NumPrimitives = numActualTris; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; buffer.iBuffers[0].NumPrimitives = (numActualTris * numActualBonds) / 3; /*buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), numActualTris * numActualBonds, device, * Usage.WriteOnly, Pool.Managed);*/ // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // write bonds to buffer Vector3 direction, directionUV; IAtom[] atoms; Vector3[] atomsPos; IMoleculeMaterial matA, matB; foreach (IBond bond in objs) { BondLinesBufferCreator.GenericBondSetup(bond, true, coDesc.BondShadingDesc, out direction, out directionUV, out atoms, out atomsPos, out matA, out matB); // calc bond positioning / instances Vector3[] bondInstances = null; float midPos; BondLinesBufferCreator.GenericBondCalcPositions(bond, coDesc.BondShadingDesc, direction, directionUV, atoms, atomsPos, 0.15f, out bondInstances, out midPos, false); long pos = 0; for (int bInst = 0; bInst < bondInstances.Length; bInst += 2) { // translation Matrix translate = Matrix.Translation(bondInstances[bInst]); // rotation double x = direction.X; double y = direction.Y; double z = direction.Z; double alpha = (z == 0) ? Math.PI / 2 : Math.Atan(x / z); double r = (alpha == 0) ? z : x / Math.Sin(alpha); float sign = 1f; if (z != 0) { sign *= Math.Sign(z); } else if (x != 0) { sign *= Math.Sign(x); } if (y != 0) { sign *= Math.Sign(y); } double theta = -sign *Math.Abs((r == 0)?Math.PI / 2 : Math.Atan(y / r)); Matrix rotation = Matrix.RotationX((float)theta) * Matrix.RotationY((float)alpha); // scaling float zScale; if (coDesc.BondShadingDesc.BlendEndClrs) { zScale = (bondInstances[1] - bondInstances[0]).Length();//(atomsPos[1] - atomsPos[0]).Length();//direction.Length(); } else { zScale = midPos; } float xyScale = 0.05f; // thickness Matrix scale = Matrix.Scaling(xyScale, xyScale, zScale); // rotate & translate ends if (tCylinderEndPoints1 != null) { Matrix endFinal = Matrix.Scaling(xyScale, xyScale, 1f) * rotation * translate; Vector4[] tfEndTriangles = Vector3.Transform(tCylinderEndPoints1, endFinal); // first end for (int point = 0; point < tCylinderEndTris1.Length; point++) { int pointIdx = tCylinderEndTris1[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfEndTriangles[pointIdx].X); data.Write(tfEndTriangles[pointIdx].Y); data.Write(tfEndTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderEndNormals1[pointIdx].X); data.Write(tCylinderEndNormals1[pointIdx].Y); data.Write(tCylinderEndNormals1[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); } pos += geomStream.Stride; } // second end endFinal = Matrix.Scaling(xyScale, xyScale, 1f) * rotation * Matrix.Translation(bondInstances[bInst + 1]); tfEndTriangles = Vector3.Transform(tCylinderEndPoints2, endFinal); // first end for (int point = 0; point < tCylinderEndTris2.Length; point++) { int pointIdx = tCylinderEndTris2[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfEndTriangles[pointIdx].X); data.Write(tfEndTriangles[pointIdx].Y); data.Write(tfEndTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderEndNormals2[pointIdx].X); data.Write(tCylinderEndNormals2[pointIdx].Y); data.Write(tCylinderEndNormals2[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += geomStream.Stride; } } Matrix final = scale * rotation * translate; if (coDesc.BondShadingDesc.BlendEndClrs) { DrawSolidBondBlended(tCylinderPoints, tCylinderNormals, tCylinderTris, matA, matB, final, data, positionPos, normalPos, diffusePos, ref pos, geomStream.Stride, rotation); } else { float bLen2 = (bondInstances[bInst + 1] - (bondInstances[bInst] + (directionUV * midPos))).Length(); DrawSolidBondDistinct(tCylinderPoints, tCylinderNormals, tCylinderTris, matA, matB, final, data, xyScale, bLen2, rotation, bondInstances[bInst], directionUV, midPos, positionPos, normalPos, diffusePos, ref pos, geomStream.Stride); } } } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int sizePos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "SIZEFLOAT") { sizePos = geomStream.FieldPositions[gf]; } break; } } } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(typeof(MetaBlobsEffect.PointVertex), objs.Count, device, Usage.None, VertexFormats.Position | VertexFormats.PointSize | VertexFormats.Diffuse, Pool.SystemMemory); /*new VertexBuffer(device, geomStream.Stride * objs.Count, * Usage.WriteOnly, geomStream.Format, Pool.SystemMemory);*/ buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count; buffer.vBuffers[0].Format = geomStream.Format; buffer.DataValidity = BufferedGeometryData.DataValidityType.Source; buffer.Target = BufferedGeometryData.DataTarget.Geometry; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields // create points AtomShadingDesc aShading = coDesc.AtomShadingDesc; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write((float)atom.X3d); data.Write((float)atom.Y3d); data.Write((float)atom.Z3d); } if (sizePos != -1) { data.Seek(pos + sizePos, SeekOrigin.Begin); data.Write((float)period); } if (diffusePos != -1) { IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } if (material != null) { data.Seek(pos + diffusePos, SeekOrigin.Begin); //data.Write((float)material.BaseColor.ToArgb()); if (material.BaseColor.R > 0) { data.Write(255f / material.BaseColor.R); } else { data.Write((float)0); } if (material.BaseColor.G > 0) { data.Write(255f / material.BaseColor.G); } else { data.Write((float)0); } if (material.BaseColor.B > 0) { data.Write(255f / material.BaseColor.B); } else { data.Write((float)0); } } } pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); }