public override void SetOutputDescription(CompleteOutputDescription coDesc) { //MetaBlobsSchemeSettings settings = (MetaBlobsSchemeSettings)coDesc.SchemeSettings; atomsBufferCreators = new AtomGeometryCreator[] { new AtomBlobBufferCreator() }; atomsBufferCreators[0].SetupForCreation(null); this.coDesc = coDesc; }
public void ApplySettings(CompleteOutputDescription outputDesc) { this.outputDesc = outputDesc; this.outputDesc.AtomShadingDesc.MoleculeMaterials = modules[0]; this.outputDesc.BondShadingDesc.MoleculeMaterials = modules[0]; if (renderContext != null) { renderContext.ApplyOutputDescription(outputDesc); renderContext.OnResize(Width, Height); } }
public void ApplyOutputDescription(CompleteOutputDescription desc) { desc.CompareAgainst(desc, true); outputDescription = desc; /*if (desc.GeneralShadingDesc.AntiAliasing > 0) * presentParams.MultiSample = MultiSampleType.FourSamples; * else * presentParams.MultiSample = MultiSampleType.None;*/ try { device.Reset(presentParams); } catch (Exception e) { log.AddItem(new LogItem(string.Format("Device failed to reset with pParams={0},{1},{2},{3},{4},{5},{6}: Exception is - {7}", presentParams.AutoDepthStencilFormat, presentParams.BackBufferFormat, presentParams.BackBufferHeight, presentParams.BackBufferWidth, presentParams.EnableAutoDepthStencil, presentParams.MultiSample, presentParams.SwapEffect, e.Message), LogItem.ItemLevel.Error)); throw; } sceneManager.SetScheme(desc.SchemeSettings.GetScheme(device)); sceneManager.SetOutputDesc(desc); if (desc.GeneralShadingDesc.Wireframe) { device.RenderState.FillMode = FillMode.WireFrame; } else { device.RenderState.FillMode = FillMode.Solid; } switch (desc.GeneralShadingDesc.ShadingMode) { case NuGenSVisualLib.Rendering.Shading.GeneralShadingDesc.ShadingModes.Smooth: device.RenderState.ShadeMode = ShadeMode.Phong; break; case NuGenSVisualLib.Rendering.Shading.GeneralShadingDesc.ShadingModes.Flat: device.RenderState.ShadeMode = ShadeMode.Flat; break; } RefreshDescription(); }
public override void SetOutputDescription(CompleteOutputDescription coDesc) { //SpriteSchemeSettings settings = (SpriteSchemeSettings)coDesc.SchemeSettings; atomsBufferCreators = new AtomGeometryCreator[] { new AtomSpriteBufferCreator() }; atomsBufferCreators[0].SetupForCreation(null); lightBonds = false; lightAtoms = true; this.coDesc = coDesc; }
public override void SetOutputDescription(CompleteOutputDescription coDesc) { //SpaceFillSchemeSettings settings = (SpaceFillSchemeSettings)coDesc.SchemeSettings; atomsBufferCreators = new AtomGeometryCreator[] { new AtomSphereBufferCreator(0.5f, 16, 12) }; atomsBufferCreators[0].SetupForCreation(null); bondsBufferCreators = null; lightAtoms = true; this.coDesc = coDesc; }
public void SetScheme(MoleculeRenderingScheme scheme, CompleteOutputDescription coDesc) { latestCoDesc = new CompleteOutputDescription(coDesc); sceneManger.SetScheme(scheme); sceneManger.SetOutputDesc(coDesc); scheme.device = device; // build preview via thread if (generatorThread.ThreadState == ThreadState.Running) { // abort thread generatorThread.Abort(); generatorThread.Join(); } generatorThread = new Thread(GeneratePreviewProcess); generatorThread.Start(); wantPreview = true; }
public void UpdateBonds(CompleteOutputDescription latestCoDesc, IBond[] bonds) { if (scheme.HandlesBonds) { scheme.SetOutputDescription(coDesc); DataFields[][] allStreams = new DataFields[1][]; IGeometryCreator[] schStreams = scheme.GetBondStreams(); GeomDataBufferStream[] geomStream = new GeomDataBufferStream[schStreams.Length]; for (int i = 0; i < geomStream.Length; i++) { allStreams[0] = schStreams[i].Fields; GeomDataTransformer.CreateBufferStream(allStreams, out geomStream[i]); } // fill buffer stream scheme.SetBondData(bonds, geomStream); } }
public MoleculeSchemeDlg(HashTableSettings settings, OutputCaps outCaps, Device device, CompleteOutputDescription coDesc) { InitializeComponent(); currentEffects = new List <Effect>(); this.settings = settings; LoadLocalResources(); this.refDevice = device; this.outCaps = outCaps; this.refcoDesc = coDesc; this.coDesc = new CompleteOutputDescription(coDesc); using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.LightingPresets.config")) { LoadLightingPresets(stream); } SetupLightingPreview(); SetupEffectPreview(); schemePreviewControl.OnNewPreview += new EventHandler(schemePreviewControl_OnNewPreview); using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.MoleculeSchemes.config")) { if (stream != null) { XmlDocument xml = new XmlDocument(); xml.Load(stream); LoadSchemes(xml); LoadEffects(xml); LoadMaterials(xml); } } previewReady = true; updateThread = new Thread(this.UpdatePreviewsProcess); updateThread.Start(); }
public void UpdateAtoms(CompleteOutputDescription coDesc, IAtom[] atoms) { if (scheme.HandlesAtoms) { scheme.SetOutputDescription(coDesc); // pass throught scheme & effects IGeometryCreator[] schStreams = scheme.GetAtomStreams(); DataFields[][] allStreams = new DataFields[1][]; GeomDataBufferStream[] geomStream = new GeomDataBufferStream[schStreams.Length]; for (int i = 0; i < geomStream.Length; i++) { allStreams[0] = schStreams[i].Fields; GeomDataTransformer.CreateBufferStream(allStreams, out geomStream[i]); } // fill buffer stream scheme.SetAtomData(atoms, geomStream); } }
private void CreatePreviewData() { atoms = new IAtom[] { new Atom("O", new Point3d(0, 0, 0)) }; ElementPTFactory elements = ElementPTFactory.Instance; foreach (IAtom atom in atoms) { PeriodicTableElement pe = elements.getElement(atom.Symbol); if (pe != null) { atom.AtomicNumber = pe.AtomicNumber; atom.Properties["PeriodicTableElement"] = pe; atom.Properties["Period"] = int.Parse(pe.Period); } } projMat = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, Width / Height, 0.1f, 20); viewMat = Matrix.LookAtLH(new Vector3(2, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); latestCoDesc = CompleteOutputDescription.New(); latestCoDesc.SchemeSettings = new BallAndStickSchemeSettings(); latestCoDesc.SchemeSettings.AtomLOD = 3; }
public void Init(HashTableSettings settings, ICommonDeviceInterface cdi) { this.settings = settings; settings["Molecule.Shading.Material.Type"] = "BySerie"; // load settings BackColor = (Color)settings["View3D.BgClr"]; // load local modules foreach (ISettingsModule module in modules) { module.LoadModuleSettings(settings); } renderContext = new ChemRenderingContext3DDX9(settings, this, (CommonDeviceInterface)cdi); renderContext.BackColor = BackColor; // load default output settings CompleteOutputDescription desc = CompleteOutputDescription.LoadDescription(Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.defaultOutput.xml")); desc.SchemeSettings = new BallAndStickSchemeSettings(); desc.SchemeSettings.AtomLOD = 2; ApplySettings(desc); }
private void LoadOutputSettings() { outputDesc = CompleteOutputDescription.LoadDescription(outputSettingsXmlFile); outputDesc.SchemeSettings = new BallAndStickSchemeSettings(); ApplySettings(outputDesc); }
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 SetOutputDescription(CompleteOutputDescription coDesc) { bool updateAtomLOD = true; bool updateBondLOD = true; bool updateSymbols = true; bool updateGlow = true; bool updateBondSize = true; bool updateBonds = true; bool updateAtoms = true; bool updateScheme = true; if (this.coDesc != null) { this.coDesc = coDesc; updateAtoms = coDesc.CheckChange("AtomShadingDesc."); if (updateAtoms) { updateSymbols = coDesc.CheckChange("AtomShadingDesc.", "SymbolText"); updateGlow = coDesc.CheckChange("SchemeSettings.", "Glow"); } updateBonds = coDesc.CheckChange("BondShadingDesc."); updateScheme = coDesc.CheckChange("SchemeSettings."); if (updateScheme) { updateAtomLOD = coDesc.CheckChange("SchemeSettings.", "AtomLOD"); updateBondLOD = coDesc.CheckChange("SchemeSettings.", "BondLOD"); updateBondSize = coDesc.CheckChange("SchemeSettings.", "StickThickness"); } } else { this.coDesc = coDesc; } BallAndStickSchemeSettings settings = (BallAndStickSchemeSettings)coDesc.SchemeSettings; int atomDetail1 = 4; int atomDetail2 = 1; if (updateAtoms || updateScheme) { /*if (updateAtomLOD) * {*/ switch (settings.AtomLOD) { case 0: atomDetail1 = 4; atomDetail2 = 1; break; case 1: atomDetail1 = 8; atomDetail2 = 6; break; case 2: atomDetail1 = 12; atomDetail2 = 9; break; case 3: atomDetail1 = 16; atomDetail2 = 12; break; case 4: atomDetail1 = 24; atomDetail2 = 18; break; case 5: atomDetail1 = 32; atomDetail2 = 26; break; } //} int bufCount = 1; if (settings.ElectronChargeCloud) { bufCount++; } if (settings.Glow > 0) { bufCount++; } if (coDesc.AtomShadingDesc.SymbolText) { bufCount++; } // TODO: Reconfigure previous creators atomsBufferCreators = new AtomGeometryCreator[bufCount]; atomsBufferCreators[0] = new AtomSphereBufferCreator(0.2f, atomDetail1, atomDetail2); bufCount = 1; if (settings.Glow > 0) { atomsBufferCreators[bufCount++] = new AtomSpriteBufferCreator(); } if (settings.ElectronChargeCloud) { atomsBufferCreators[bufCount++] = new AtomMetaballsBufferCreator(true); } if (coDesc.AtomShadingDesc.SymbolText) { atomsBufferCreators[bufCount++] = new AtomSymbolSpriteBufferCreator(); } foreach (AtomGeometryCreator creator in atomsBufferCreators) { creator.SetupForCreation(null); } } if (updateBonds || updateScheme) { if (updateBondSize) { if (settings.StickThickness == 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondLinesBufferCreator))) { bondsBufferCreators = new BondGeometryCreator[] { new BondLinesBufferCreator() } } ; else if (settings.StickThickness > 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondThickLinesBufferCreator))) { bondsBufferCreators = new BondGeometryCreator[] { new BondThickLinesBufferCreator(5) } } ; bondsBufferCreators[0].SetupForCreation(null); } } lightBonds = false; lightAtoms = true; this.coDesc = coDesc; } }
public override void SetOutputDescription(CompleteOutputDescription coDesc) { bool updateAtomLOD = true; bool updateBondLOD = true; bool updateSymbols = true; bool updateGlow = true; bool updateBondSize = true; bool updateBonds = true; bool updateAtoms = true; bool updateScheme = true; if (this.coDesc != null) { this.coDesc = coDesc; updateAtoms = coDesc.CheckChange("AtomShadingDesc."); if (updateAtoms) { updateSymbols = coDesc.CheckChange("AtomShadingDesc.", "SymbolText"); updateGlow = coDesc.CheckChange("SchemeSettings.", "Glow"); } updateBonds = coDesc.CheckChange("BondShadingDesc."); updateScheme = coDesc.CheckChange("SchemeSettings."); if (updateScheme) { updateAtomLOD = coDesc.CheckChange("SchemeSettings.", "AtomLOD"); updateBondLOD = coDesc.CheckChange("SchemeSettings.", "BondLOD"); updateBondSize = coDesc.CheckChange("SchemeSettings.", "StickThickness"); } } else this.coDesc = coDesc; BallAndStickSchemeSettings settings = (BallAndStickSchemeSettings)coDesc.SchemeSettings; int atomDetail1 = 4; int atomDetail2 = 1; if (updateAtoms || updateScheme) { /*if (updateAtomLOD) {*/ switch (settings.AtomLOD) { case 0: atomDetail1 = 4; atomDetail2 = 1; break; case 1: atomDetail1 = 8; atomDetail2 = 6; break; case 2: atomDetail1 = 12; atomDetail2 = 9; break; case 3: atomDetail1 = 16; atomDetail2 = 12; break; case 4: atomDetail1 = 24; atomDetail2 = 18; break; case 5: atomDetail1 = 32; atomDetail2 = 26; break; } //} int bufCount = 1; if (settings.ElectronChargeCloud) bufCount++; if (settings.Glow > 0) bufCount++; if (coDesc.AtomShadingDesc.SymbolText) bufCount++; // TODO: Reconfigure previous creators atomsBufferCreators = new AtomGeometryCreator[bufCount]; atomsBufferCreators[0] = new AtomSphereBufferCreator(0.2f, atomDetail1, atomDetail2); bufCount = 1; if (settings.Glow > 0) atomsBufferCreators[bufCount++] = new AtomSpriteBufferCreator(); if (settings.ElectronChargeCloud) atomsBufferCreators[bufCount++] = new AtomMetaballsBufferCreator(true); if (coDesc.AtomShadingDesc.SymbolText) atomsBufferCreators[bufCount++] = new AtomSymbolSpriteBufferCreator(); foreach (AtomGeometryCreator creator in atomsBufferCreators) { creator.SetupForCreation(null); } } if (updateBonds || updateScheme) { if (updateBondSize) { if (settings.StickThickness == 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondLinesBufferCreator))) bondsBufferCreators = new BondGeometryCreator[] { new BondLinesBufferCreator() }; else if (settings.StickThickness > 0 && (bondsBufferCreators == null || !(bondsBufferCreators[0] is BondThickLinesBufferCreator))) bondsBufferCreators = new BondGeometryCreator[] { new BondThickLinesBufferCreator(5) }; bondsBufferCreators[0].SetupForCreation(null); } } lightBonds = false; lightAtoms = true; this.coDesc = coDesc; }
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(); }
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(); }
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(); }
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(); }
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(); }
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; // 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 void SetOutputDesc(CompleteOutputDescription desc) { this.coDesc = new CompleteOutputDescription(desc); scheme.SetOutputDescription(desc); }
public abstract void SetOutputDescription(CompleteOutputDescription coDesc);
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 <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(); }
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 abstract void CreateGeometryForObjects(Device device, ICollection <IBond> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc);
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); } } } }