private void PrepareRenderMeshes(RenderModel renderModel, List <Mesh> meshes, ref FastListStruct <RenderMesh> renderMeshes, RenderItemCollection opaqueList, RenderItemCollection transparentList) { // Add new render meshes for (int i = renderMeshes.Count; i < meshes.Count; i++) { var renderMesh = new RenderMesh(renderModel, meshes[i]); renderMeshes.Add(renderMesh); } // Create the bounding frustum locally on the stack, so that frustum.Contains is performed with boundingBox that is also on the stack var frustum = new BoundingFrustum(ref ViewProjectionMatrix); var sceneCameraRenderer = Context.Tags.Get(SceneCameraRenderer.Current); var cullingMode = CullingModeOverride ?? (sceneCameraRenderer?.CullingMode ?? CameraCullingMode.None); for (int i = 0; i < renderMeshes.Count; i++) { var renderMesh = renderMeshes[i]; // Update the model hierarchy var modelViewHierarchy = renderModel.ModelComponent.ModelViewHierarchy; modelViewHierarchy.UpdateRenderMesh(renderMesh); if (!renderMesh.Enabled || !renderMesh.UpdateMaterial()) { continue; } // Upload skinning blend matrices BoundingBoxExt boundingBox; skinningUpdater.Update(modelViewHierarchy, renderMesh, out boundingBox); // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/ // Compute transformed AABB (by world) // TODO: CameraCullingMode should be pluggable // TODO: This should not be necessary. Add proper bounding boxes to gizmos etc. if (cullingMode == CameraCullingMode.Frustum && boundingBox.Extent != Vector3.Zero && !frustum.Contains(ref boundingBox)) { continue; } // Project the position // TODO: This could be done in a SIMD batch, but we need to figure-out how to plugin in with RenderMesh object var worldPosition = new Vector4(renderMesh.WorldMatrix.TranslationVector, 1.0f); Vector4 projectedPosition; Vector4.Transform(ref worldPosition, ref ViewProjectionMatrix, out projectedPosition); var projectedZ = projectedPosition.Z / projectedPosition.W; renderMesh.RasterizerState = renderMesh.IsGeometryInverted ? RasterizerStateForInvertedGeometry : RasterizerState; renderMesh.ForceRasterizer = ForceRasterizer; var list = renderMesh.HasTransparency ? transparentList : opaqueList; list.Add(new RenderItem(this, renderMesh, projectedZ)); } }
private List <RenderMesh> PrepareModelForRendering(RenderContext context, RenderModel renderModel) { // Create the list of RenderMesh objects var renderMeshes = renderModel.RenderMeshesList[modelRenderSlot]; var modelMeshes = renderModel.ModelComponent.Model.Meshes; // If render mesh is new or the model changed, generate new render mesh if (renderMeshes == null || (renderMeshes.Count == 00 && modelMeshes.Count > 0)) { if (renderMeshes == null) { renderMeshes = new RenderMeshCollection(); renderModel.RenderMeshesList[modelRenderSlot] = renderMeshes; } foreach (var mesh in modelMeshes) { var renderMesh = new RenderMesh(renderModel, mesh); //UpdateEffect(context, renderMesh, null); // Register mesh for rendering renderMeshes.Add(renderMesh); } } // Update RenderModel transform if (!renderMeshes.TransformUpdated) { // Update the model hierarchy var modelViewHierarchy = renderModel.ModelComponent.ModelViewHierarchy; modelViewHierarchy.UpdateToRenderModel(renderModel, modelRenderSlot); // Upload skinning blend matrices MeshSkinningUpdater.Update(modelViewHierarchy, renderModel, modelRenderSlot); renderMeshes.TransformUpdated = true; } return(renderMeshes); }