/// <inheritdoc/> public override void Extract() { var renderModelObjectInfo = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); nodeInfoCount = 0; //foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences) Dispatcher.ForEach(RootRenderFeature.ObjectNodeReferences, objectNodeReference => { var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference); var renderMesh = (RenderMesh)objectNode.RenderObject; var skeleton = renderMesh.RenderModel.ModelComponent.Skeleton; var skinning = renderMesh.Mesh.Skinning; // Skip unskinned meshes if (skinning == null) { renderModelObjectInfo[objectNodeReference] = new RenderModelFrameInfo(); return; } var bones = skinning.Bones; var boneCount = bones.Length; // Reserve space in the node buffer var newNodeInfoCount = Interlocked.Add(ref nodeInfoCount, boneCount); var nodeInfoOffset = newNodeInfoCount - boneCount; renderModelObjectInfo[objectNodeReference] = new RenderModelFrameInfo { NodeInfoOffset = nodeInfoOffset, NodeInfoCount = boneCount }; // Ensure buffer capacity if (nodeInfos.Length < newNodeInfoCount) { lock (nodeInfoLock) { if (nodeInfos.Length < newNodeInfoCount) { Array.Resize(ref nodeInfos, Math.Max(newNodeInfoCount, nodeInfos.Length * 2)); } } } var nodeTransformations = skeleton.NodeTransformations; for (int index = 0; index < boneCount; index++) { var nodeIndex = bones[index].NodeIndex; nodeInfos[nodeInfoOffset + index] = new NodeFrameInfo { LinkToMeshMatrix = bones[index].LinkToMeshMatrix, NodeTransformation = nodeTransformations[nodeIndex].WorldMatrix }; } }); }
/// <inheritdoc/> public override void Extract() { var renderModelObjectInfo = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); Dispatcher.ForEach(RootRenderFeature.ObjectNodeReferences, objectNodeReference => { var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference); var renderMesh = (RenderMesh)objectNode.RenderObject; // TODO GRAPHICS REFACTOR: Extract copy of matrices renderModelObjectInfo[objectNodeReference] = renderMesh.BlendMatrices; }); }
/// <param name="context"></param> /// <inheritdoc/> public override void PrepareEffectPermutations(RenderDrawContext context) { var skinningInfos = RootRenderFeature.RenderData.GetData(skinningInfoKey); var renderEffects = RootRenderFeature.RenderData.GetData(renderEffectKey); int effectSlotCount = ((RootEffectRenderFeature)RootRenderFeature).EffectPermutationSlotCount; //foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences) Dispatcher.ForEach(((RootEffectRenderFeature)RootRenderFeature).ObjectNodeReferences, objectNodeReference => { var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference); var renderMesh = (RenderMesh)objectNode.RenderObject; var staticObjectNode = renderMesh.StaticObjectNode; var skinningInfo = skinningInfos[staticObjectNode]; var parameters = renderMesh.Mesh.Parameters; if (parameters != skinningInfo.Parameters || parameters.PermutationCounter != skinningInfo.PermutationCounter) { skinningInfo.Parameters = parameters; skinningInfo.PermutationCounter = parameters.PermutationCounter; skinningInfo.HasSkinningPosition = parameters.Get(MaterialKeys.HasSkinningPosition); skinningInfo.HasSkinningNormal = parameters.Get(MaterialKeys.HasSkinningNormal); skinningInfo.HasSkinningTangent = parameters.Get(MaterialKeys.HasSkinningTangent); skinningInfos[staticObjectNode] = skinningInfo; } for (int i = 0; i < effectSlotCount; ++i) { var staticEffectObjectNode = staticObjectNode * effectSlotCount + i; var renderEffect = renderEffects[staticEffectObjectNode]; // Skip effects not used during this frame if (renderEffect == null || !renderEffect.IsUsedDuringThisFrame(RenderSystem)) { continue; } if (renderMesh.Mesh.Skinning != null) { renderEffect.EffectValidator.ValidateParameter(MaterialKeys.HasSkinningPosition, skinningInfo.HasSkinningPosition); renderEffect.EffectValidator.ValidateParameter(MaterialKeys.HasSkinningNormal, skinningInfo.HasSkinningNormal); renderEffect.EffectValidator.ValidateParameter(MaterialKeys.HasSkinningTangent, skinningInfo.HasSkinningTangent); var skinningBones = Math.Max(MaxBones, renderMesh.Mesh.Skinning.Bones.Length); renderEffect.EffectValidator.ValidateParameter(MaterialKeys.SkinningMaxBones, skinningBones); } } }); }
/// <inheritdoc/> public override void Extract() { var renderModelObjectInfo = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); //for (int index = 0; index < RootRenderFeature.ObjectNodeReferences.Count; index++) Dispatcher.For(0, RootRenderFeature.ObjectNodeReferences.Count, index => { var objectNodeReference = RootRenderFeature.ObjectNodeReferences[index]; var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference); var renderMesh = objectNode.RenderObject as RenderMesh; // TODO: Extract world renderModelObjectInfo[objectNodeReference].World = renderMesh != null ? renderMesh.World : Matrix.Identity; }); }
/// <inheritdoc/> public override void Extract() { var renderModelObjectInfo = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences) { var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference); var renderMesh = objectNode.RenderObject as RenderMesh; // TODO: Extract world var world = (renderMesh != null) ? renderMesh.World : Matrix.Identity; renderModelObjectInfo[objectNodeReference] = new RenderModelFrameInfo { World = world }; } }
/// <inheritdoc/> public override void Extract() { var renderModelObjectInfo = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); nodeInfos.Clear(); foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences) { var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference); var renderMesh = (RenderMesh)objectNode.RenderObject; var skeleton = renderMesh.RenderModel.ModelComponent.Skeleton; var skinning = renderMesh.Mesh.Skinning; // Skip unskinned meshes if (skinning == null) { renderModelObjectInfo[objectNodeReference] = new RenderModelFrameInfo(); continue; } var bones = skinning.Bones; var boneCount = bones.Length; // Reserve space in the node buffer renderModelObjectInfo[objectNodeReference] = new RenderModelFrameInfo { NodeInfoOffset = nodeInfos.Count, NodeInfoCount = boneCount }; // Ensure buffer capacity nodeInfos.EnsureCapacity(nodeInfos.Count + boneCount); // Copy matrices for (int index = 0; index < boneCount; index++) { var nodeIndex = bones[index].NodeIndex; nodeInfos.Add(new NodeFrameInfo { LinkToMeshMatrix = bones[index].LinkToMeshMatrix, NodeTransformation = skeleton.NodeTransformations[nodeIndex].WorldMatrix }); } } }
/// <param name="context"></param> /// <inheritdoc/> public override unsafe void Prepare(RenderDrawContext context) { // Compute WorldView, WorldViewProj var renderModelObjectInfoData = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); var renderModelViewInfoData = RootRenderFeature.RenderData.GetData(renderModelViewInfoKey); // Update PerFrame (time) // TODO Move that to RootEffectRenderFeature? foreach (var frameLayout in ((RootEffectRenderFeature)RootRenderFeature).FrameLayouts) { var timeOffset = frameLayout.GetConstantBufferOffset(time); if (timeOffset == -1) { continue; } var resourceGroup = frameLayout.Entry.Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perFrameTime = (PerFrameTime *)((byte *)mappedCB + timeOffset); perFrameTime->Time = (float)Context.Time.Total.TotalSeconds; perFrameTime->TimeStep = (float)Context.Time.Elapsed.TotalSeconds; } // Update PerView (View, Proj, etc...) for (int index = 0; index < RenderSystem.Views.Count; index++) { var view = RenderSystem.Views[index]; var viewFeature = view.Features[RootRenderFeature.Index]; // Compute WorldView and WorldViewProjection Dispatcher.ForEach(viewFeature.ViewObjectNodes, renderPerViewNodeReference => { var renderPerViewNode = RootRenderFeature.GetViewObjectNode(renderPerViewNodeReference); ref var renderModelFrameInfo = ref renderModelObjectInfoData[renderPerViewNode.ObjectNode]; ref var renderModelViewInfo = ref renderModelViewInfoData[renderPerViewNodeReference]; Matrix.Multiply(ref renderModelFrameInfo.World, ref view.View, out renderModelViewInfo.WorldView); Matrix.Multiply(ref renderModelFrameInfo.World, ref view.ViewProjection, out renderModelViewInfo.WorldViewProjection); });
/// <param name="context"></param> /// <inheritdoc/> public unsafe override void Prepare(RenderDrawContext context) { // Compute WorldView, WorldViewProj var renderModelObjectInfoData = RootRenderFeature.RenderData.GetData(renderModelObjectInfoKey); var renderModelViewInfoData = RootRenderFeature.RenderData.GetData(renderModelViewInfoKey); // Update PerFrame (time) // TODO Move that to RootEffectRenderFeature? foreach (var frameLayout in ((RootEffectRenderFeature)RootRenderFeature).FrameLayouts) { var timeOffset = frameLayout.GetConstantBufferOffset(time); if (timeOffset == -1) { continue; } var resourceGroup = frameLayout.Entry.Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perFrameTime = (PerFrameTime *)((byte *)mappedCB + timeOffset); perFrameTime->Time = (float)Context.Time.Total.TotalSeconds; perFrameTime->TimeStep = (float)Context.Time.Elapsed.TotalSeconds; } // Update PerView (View, Proj, etc...) for (int index = 0; index < RenderSystem.Views.Count; index++) { var view = RenderSystem.Views[index]; var viewFeature = view.Features[RootRenderFeature.Index]; // Compute WorldView and WorldViewProjection foreach (var renderPerViewNodeReference in viewFeature.ViewObjectNodes) { var renderPerViewNode = RootRenderFeature.GetViewObjectNode(renderPerViewNodeReference); var renderModelFrameInfo = renderModelObjectInfoData[renderPerViewNode.ObjectNode]; var renderModelViewInfo = new RenderModelViewInfo(); Matrix.Multiply(ref renderModelFrameInfo.World, ref view.View, out renderModelViewInfo.WorldView); Matrix.Multiply(ref renderModelFrameInfo.World, ref view.ViewProjection, out renderModelViewInfo.WorldViewProjection); // TODO: Use ref locals or Utilities instead, to avoid double copy renderModelViewInfoData[renderPerViewNodeReference] = renderModelViewInfo; } // Copy ViewProjection to PerView cbuffer foreach (var viewLayout in viewFeature.Layouts) { var viewProjectionOffset = viewLayout.GetConstantBufferOffset(this.view); if (viewProjectionOffset == -1) { continue; } var resourceGroup = viewLayout.Entries[view.Index].Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perView = (PerView *)((byte *)mappedCB + viewProjectionOffset); // Fill PerView perView->View = view.View; Matrix.Invert(ref view.View, out perView->ViewInverse); perView->Projection = view.Projection; Matrix.Invert(ref view.Projection, out perView->ProjectionInverse); perView->ViewProjection = view.ViewProjection; perView->ProjScreenRay = new Vector2(-1.0f / view.Projection.M11, 1.0f / view.Projection.M22); // TODO GRAPHICS REFACTOR avoid cbuffer read perView->Eye = new Vector4(perView->ViewInverse.M41, perView->ViewInverse.M42, perView->ViewInverse.M43, 1.0f); } // Copy Camera to PerView cbuffer var cameraComponent = view.Camera; if (cameraComponent != null) { foreach (var viewLayout in viewFeature.Layouts) { var cameraOffset = viewLayout.GetConstantBufferOffset(camera); if (cameraOffset == -1) { continue; } var resourceGroup = viewLayout.Entries[view.Index].Resources; var mappedCB = resourceGroup.ConstantBuffer.Data; var perViewCamera = (PerViewCamera *)((byte *)mappedCB + cameraOffset); perViewCamera->NearClipPlane = cameraComponent.NearClipPlane; perViewCamera->FarClipPlane = cameraComponent.FarClipPlane; perViewCamera->ZProjection = CameraKeys.ZProjectionACalculate(cameraComponent.NearClipPlane, cameraComponent.FarClipPlane); if (view.SceneCameraRenderer != null) { perViewCamera->ViewSize = new Vector2(view.SceneCameraRenderer.ComputedViewport.Width, view.SceneCameraRenderer.ComputedViewport.Height); } perViewCamera->AspectRatio = cameraComponent.AspectRatio; perViewCamera->VerticalFieldOfView = cameraComponent.VerticalFieldOfView; perViewCamera->OrthoSize = cameraComponent.OrthographicSize; } } } // Update PerDraw (World, WorldViewProj, etc...) // Copy Entity.World to PerDraw cbuffer // TODO: Have a PerObject cbuffer? foreach (var renderNode in ((RootEffectRenderFeature)RootRenderFeature).RenderNodes) { var perDrawLayout = renderNode.RenderEffect.Reflection.PerDrawLayout; if (perDrawLayout == null) { continue; } var worldOffset = perDrawLayout.GetConstantBufferOffset(this.world); if (worldOffset == -1) { continue; } var renderModelObjectInfo = renderModelObjectInfoData[renderNode.RenderObject.ObjectNode]; var renderModelViewInfo = renderModelViewInfoData[renderNode.ViewObjectNode]; var mappedCB = renderNode.Resources.ConstantBuffer.Data; var perDraw = (PerDraw *)((byte *)mappedCB + worldOffset); // Fill PerDraw perDraw->World = renderModelObjectInfo.World; Matrix.Invert(ref renderModelObjectInfo.World, out perDraw->WorldInverse); // TODO GRAPHICS REFACTOR avoid cbuffer read Matrix.Transpose(ref perDraw->WorldInverse, out perDraw->WorldInverseTranspose); perDraw->WorldView = renderModelViewInfo.WorldView; Matrix.Invert(ref renderModelViewInfo.WorldView, out perDraw->WorldViewInverse); perDraw->WorldViewProjection = renderModelViewInfo.WorldViewProjection; perDraw->WorldScale = new Vector3( ((Vector3)renderModelObjectInfo.World.Row1).Length(), ((Vector3)renderModelObjectInfo.World.Row2).Length(), ((Vector3)renderModelObjectInfo.World.Row3).Length()); // TODO GRAPHICS REFACTOR avoid cbuffer read perDraw->EyeMS = new Vector4(perDraw->WorldViewInverse.M41, perDraw->WorldViewInverse.M42, perDraw->WorldViewInverse.M43, 1.0f); } }
/// <summary> /// Attach this <see cref="SubRenderFeature"/> to a <see cref="RootRenderFeature"/>. /// </summary> /// <param name="rootRenderFeature"></param> internal void AttachRootRenderFeature(RootRenderFeature rootRenderFeature) { RootRenderFeature = rootRenderFeature; RenderSystem = rootRenderFeature.RenderSystem; }
public RenderNodeFeatureReference(RootRenderFeature rootRenderFeature, RenderNodeReference renderNode, RenderObject renderObject) { RootRenderFeature = rootRenderFeature; RenderNode = renderNode; RenderObject = renderObject; }
public RenderNodeFeatureReference(RootRenderFeature rootRenderFeature, RenderNodeReference renderNode, RenderObject renderObject) { RootRenderFeature = rootRenderFeature; RenderNode = renderNode; RenderObject = renderObject; }
/// <summary> /// Attach this <see cref="SubRenderFeature"/> to a <see cref="RootRenderFeature"/>. /// </summary> /// <param name="rootRenderFeature"></param> internal void AttachRootRenderFeature(RootRenderFeature rootRenderFeature) { RootRenderFeature = rootRenderFeature; RenderSystem = rootRenderFeature.RenderSystem; }