/// <summary> /// Adds a mesh to the current batch, or to a new one if the current one does not support /// it. Whenever the batch changes, <code>onBatchComplete</code> is called for the previous /// one. /// </summary> /// <param name="mesh">The mesh to add to the current(or new) batch.</param> /// <param name="state">The render state from which to take the current settings for alpha, /// modelview matrix, and blend mode.</param> /// <param name="subset">The subset of the mesh you want to add, or<code>null</code> for /// the complete mesh.</param> /// <param name="ignoreTransformations">When enabled, the mesh's vertices will be added /// without transforming them in any way (no matter the value of the /// state's <code>modelviewMatrix</code></param> public void AddMesh(Mesh mesh, RenderState state, MeshSubset subset = null, bool ignoreTransformations = false) { if (subset == null) { subset = SMeshSubset; subset.VertexId = subset.IndexId = 0; subset.NumVertices = mesh.NumVertices; subset.NumIndices = mesh.NumIndices; } else { if (subset.NumVertices < 0) { subset.NumVertices = mesh.NumVertices - subset.VertexId; } if (subset.NumIndices < 0) { subset.NumIndices = mesh.NumIndices - subset.IndexId; } } if (subset.NumVertices > 0) { if (_currentBatch == null || !_currentBatch.CanAddMesh(mesh, subset.NumVertices)) { FinishBatch(); _currentStyleType = mesh.Style.Type; _currentBatch = _batchPool.GetBatch(_currentStyleType); _currentBatch.BlendMode = state != null ? state.BlendMode : mesh.BlendMode; _cacheToken.SetTo(_batches.Count); _batches.Add(_currentBatch); } Matrix2D matrix = state != null ? state._modelviewMatrix : null; float alpha = state != null ? state.Alpha : 1.0f; _currentBatch.AddMesh(mesh, matrix, alpha, subset, ignoreTransformations); _cacheToken.VertexID += subset.NumVertices; _cacheToken.IndexID += subset.NumIndices; } }
public override void Read(BinaryReader r) { base.Read(r); Flags = r.ReadUInt32(); // Might be a ref to this chunk NumMeshSubset = r.ReadUInt32(); // number of mesh subsets SkipBytes(r, 8); MeshSubsets = new MeshSubset[NumMeshSubset]; for (var i = 0; i < NumMeshSubset; i++) { MeshSubsets[i].FirstIndex = r.ReadUInt32(); MeshSubsets[i].NumIndices = r.ReadUInt32(); MeshSubsets[i].FirstVertex = r.ReadUInt32(); MeshSubsets[i].NumVertices = r.ReadUInt32(); MeshSubsets[i].MatID = r.ReadUInt32(); MeshSubsets[i].Radius = r.ReadSingle(); MeshSubsets[i].Center.x = r.ReadSingle(); MeshSubsets[i].Center.y = r.ReadSingle(); MeshSubsets[i].Center.z = r.ReadSingle(); } }
/// <summary> /// Adds a mesh to the batch by appending its vertices and indices. /// </summary> /// <param name="mesh">The mesh to add to the batch.</param> /// <param name="matrix">Transform all vertex positions with a certain matrix. If this /// parameter is omitted, <code>mesh.transformationMatrix</code> /// will be used instead (except if the last parameter is enabled).</param> /// <param name="alpha">Will be multiplied with each vertex' alpha value.</param> /// <param name="subset">The subset of the mesh you want to add, or <code>null</code> for /// the complete mesh.</param> /// <param name="ignoreTransformations">When enabled, the mesh's vertices will be added /// without transforming them in any way (no matter the value of the /// <code>matrix</code>)</param> public void AddMesh(Mesh mesh, Matrix2D matrix = null, float alpha = 1.0f, MeshSubset subset = null, bool ignoreTransformations = false) { if (ignoreTransformations) { matrix = null; } else if (matrix == null) { matrix = mesh.TransformationMatrix; } if (subset == null) { subset = SFullMeshSubset; } int targetVertexId = _vertexData.NumVertices; int targetIndexId = _indexData.NumIndices; MeshStyle meshStyle = mesh._style; if (targetVertexId == 0) { SetupFor(mesh); } meshStyle.BatchVertexData(_style, targetVertexId, matrix, subset.VertexId, subset.NumVertices); meshStyle.BatchIndexData(_style, targetIndexId, targetVertexId - subset.VertexId, subset.IndexId, subset.NumIndices); if (alpha != 1.0f) { _vertexData.ScaleAlphas(alpha, targetVertexId, subset.NumVertices); } if (_parent != null) { SetRequiresRedraw(); } _indexSyncRequired = _vertexSyncRequired = true; }
/// <summary> /// Draws all meshes from the render cache between <code>startToken</code> and /// (but not including) <code>endToken</code>. The render cache contains all meshes /// rendered in the previous frame. /// </summary> public void DrawFromCache(BatchToken startToken, BatchToken endToken) { MeshSubset subset = SMeshSubset; if (!startToken.Equals(endToken)) { PushState(); for (int i = startToken.BatchID; i <= endToken.BatchID; ++i) { var meshBatch = _batchProcessorPrev.GetBatchAt(i); subset.SetTo(); // resets subset if (i == startToken.BatchID) { subset.VertexId = startToken.VertexID; subset.IndexId = startToken.IndexID; subset.NumVertices = meshBatch.NumVertices - subset.VertexId; subset.NumIndices = meshBatch.NumIndices - subset.IndexId; } if (i == endToken.BatchID) { subset.NumVertices = endToken.VertexID - subset.VertexId; subset.NumIndices = endToken.IndexID - subset.IndexId; } if (subset.NumVertices != 0) { _state.Alpha = 1.0f; _state.BlendMode = meshBatch.BlendMode; _batchProcessor.AddMesh(meshBatch, _state, subset, true); } } PopState(); } }
// mesh rendering /// <summary> /// Adds a mesh to the current batch of unrendered meshes. If the current batch is not /// compatible with the mesh, all previous meshes are rendered at once and the batch /// is cleared. /// </summary> /// <param name="mesh"> The mesh to batch.</param> /// <param name="subset">The range of vertices to be batched. If <code>null</code>, the complete /// mesh will be used.</param> public void BatchMesh(Mesh mesh, MeshSubset subset = null) { _batchProcessor.AddMesh(mesh, _state, subset); }
public void Init(float radius, int slices, int sections) { try { m_radius = radius; m_numberSlices = slices; m_numberSections = sections; Point3d sunPosition = SunCalculator.GetGeocentricPosition(TimeKeeper.CurrentTimeUtc); Vector3 sunVector = new Vector3( (float)-sunPosition.X, (float)-sunPosition.Y, (float)-sunPosition.Z); m_vLight = sunVector * 100000000f; m_vLightDirection = new Vector3( m_vLight.X / m_vLight.Length(), m_vLight.Y / m_vLight.Length(), m_vLight.Z / m_vLight.Length() ); m_fScale = 1 / (m_fOuterRadius - m_fInnerRadius); m_meshList.Clear(); double latRange = 180.0 / (double)TilesHigh; double lonRange = 360.0 / (double)TilesWide; int meshDensity = m_numberSlices / TilesHigh; for (int y = 0; y < TilesHigh; y++) { for (int x = 0; x < TilesWide; x++) { MeshSubset mesh = new MeshSubset(); double north = y * latRange + latRange - 90; double south = y * latRange - 90; double west = x * lonRange - 180; double east = x * lonRange + lonRange - 180; mesh.Vertices = CreateMesh(south, north, west, east, meshDensity); mesh.HigherResolutionVertices = CreateMesh(south, north, west, east, 2 * meshDensity); mesh.BoundingBox = new BoundingBox((float)south, (float)north, (float)west, (float)east, (float)radius, (float)radius); m_meshList.Add(mesh); } } m_indices = computeIndices(meshDensity); m_indicesHighResolution = computeIndices(2 * meshDensity); m_nSamples = 4; // Number of sample rays to use in integral equation m_Kr = 0.0025f; // Rayleigh scattering constant m_Kr4PI = m_Kr * 4.0f * (float)Math.PI; m_Km = 0.0015f; // Mie scattering constant m_Km4PI = m_Km * 4.0f * (float)Math.PI; m_ESun = 15.0f; // Sun brightness constant m_g = -0.85f; // The Mie phase asymmetry factor m_fWavelength[0] = 0.650f; // 650 nm for red m_fWavelength[1] = 0.570f; // 570 nm for green m_fWavelength[2] = 0.475f; // 475 nm for blue m_fWavelength4[0] = (float)Math.Pow(m_fWavelength[0], 4.0f); m_fWavelength4[1] = (float)Math.Pow(m_fWavelength[1], 4.0f); m_fWavelength4[2] = (float)Math.Pow(m_fWavelength[2], 4.0f); m_fRayleighScaleDepth = 0.25f; m_fMieScaleDepth = 0.1f; } catch (Exception ex) { Log.Write(ex); } }
private void UpdateColor(DrawArgs drawArgs, MeshSubset meshSubset, bool doHighResolution) { int blank = System.Drawing.Color.FromArgb(255, 0, 0, 0).ToArgb(); if (doHighResolution) { for (int i = 0; i < meshSubset.HigherResolutionVertices.Length; i++) { if (Vector3.Dot(drawArgs.WorldCamera.Position, new Vector3(meshSubset.HigherResolutionVertices[i].X, meshSubset.HigherResolutionVertices[i].Y, meshSubset.HigherResolutionVertices[i].Z)) > 0) SetColor(ref meshSubset.HigherResolutionVertices[i], drawArgs); else meshSubset.HigherResolutionVertices[i].Color = blank; } } else { for (int i = 0; i < meshSubset.Vertices.Length; i++) { if (Vector3.Dot(drawArgs.WorldCamera.Position, new Vector3(meshSubset.Vertices[i].X, meshSubset.Vertices[i].Y, meshSubset.Vertices[i].Z)) > 0) SetColor(ref meshSubset.Vertices[i], drawArgs); else meshSubset.Vertices[i].Color = blank; } } }
public ShadingGroup( MeshSubset subset, MaterialInstance material ) { StartIndex = subset.StartPrimitive * 3; IndicesCount= subset.PrimitiveCount * 3; Material = material; }
public override void DrawSubset(Context context, MeshSubset subset, Material material) { GraphicsDevice.DrawIndexed(subset.PrimitiveCount * 3, subset.StartPrimitive, 0); }