예제 #1
0
        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));
            }
        }
예제 #2
0
        /// <summary>
        /// Updates previously computed world matrices to TransformationKeys.World for each <see cref="RenderMesh" />.
        /// </summary>
        /// <param name="renderMesh">The render mesh.</param>
        internal void UpdateRenderMesh(RenderMesh renderMesh)
        {
            var nodeIndex = renderMesh.Mesh.NodeIndex;
            var enabled   = nodeTransformations[nodeIndex].RenderingEnabledRecursive;

            renderMesh.Enabled = enabled;
            if (enabled && renderMesh.MatrixCounter != matrixCounter)
            {
                renderMesh.WorldMatrix        = nodeTransformations[nodeIndex].WorldMatrix;
                renderMesh.IsGeometryInverted = nodeTransformations[nodeIndex].IsScalingNegative;
                renderMesh.MatrixCounter      = matrixCounter;
            }
        }
예제 #3
0
        public void Update(ModelViewHierarchyUpdater hierarchyUpdater, RenderMesh renderMesh, out BoundingBoxExt boundingBox)
        {
            var mesh     = renderMesh.Mesh;
            var skinning = mesh.Skinning;

            if (skinning == null)
            {
                // For unskinned meshes, use the original bounding box
                var boundingBoxExt = (BoundingBoxExt)mesh.BoundingBox;
                boundingBoxExt.Transform(renderMesh.WorldMatrix);
                boundingBox = boundingBoxExt;
                return;
            }

            var bones = skinning.Bones;

            // Make sure there is enough spaces in boneMatrices
            if (bones.Length > boneMatrices.Length)
            {
                boneMatrices = new Matrix[bones.Length];
            }

            var bindPoseBoundingBox = new BoundingBoxExt(renderMesh.Mesh.BoundingBox);

            boundingBox = BoundingBoxExt.Empty;

            for (int index = 0; index < bones.Length; index++)
            {
                var nodeIndex = bones[index].NodeIndex;

                // Compute bone matrix
                Matrix.Multiply(ref bones[index].LinkToMeshMatrix, ref hierarchyUpdater.NodeTransformations[nodeIndex].WorldMatrix, out boneMatrices[index]);

                // Calculate and extend bounding box for each bone
                // TODO: Move runtime bounding box into ModelViewHierarchyUpdater?

                // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
                // Compute transformed AABB (by world)
                var boundingBoxExt = bindPoseBoundingBox;
                boundingBoxExt.Transform(boneMatrices[index]);
                BoundingBoxExt.Merge(ref boundingBox, ref boundingBoxExt, out boundingBox);
            }

            // Upload bones
            renderMesh.Parameters.Set(TransformationSkinningKeys.BlendMatrixArray, boneMatrices, 0, bones.Length);
        }
예제 #4
0
        public void Update(ModelViewHierarchyUpdater hierarchyUpdater, RenderMesh renderMesh, out BoundingBoxExt boundingBox)
        {
            var mesh = renderMesh.Mesh;
            var skinning = mesh.Skinning;

            if (skinning == null)
            {
                // For unskinned meshes, use the original bounding box
                var boundingBoxExt = (BoundingBoxExt)mesh.BoundingBox;
                boundingBoxExt.Transform(renderMesh.WorldMatrix);
                boundingBox = boundingBoxExt;
                return;
            }

            var bones = skinning.Bones;

            // Make sure there is enough spaces in boneMatrices
            if (bones.Length > boneMatrices.Length)
                boneMatrices = new Matrix[bones.Length];

            var bindPoseBoundingBox = new BoundingBoxExt(renderMesh.Mesh.BoundingBox);
            boundingBox = BoundingBoxExt.Empty;

            for (int index = 0; index < bones.Length; index++)
            {
                var nodeIndex = bones[index].NodeIndex;

                // Compute bone matrix
                Matrix.Multiply(ref bones[index].LinkToMeshMatrix, ref hierarchyUpdater.NodeTransformations[nodeIndex].WorldMatrix, out boneMatrices[index]);

                // Calculate and extend bounding box for each bone
                // TODO: Move runtime bounding box into ModelViewHierarchyUpdater?

                // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
                // Compute transformed AABB (by world)
                var boundingBoxExt = bindPoseBoundingBox;
                boundingBoxExt.Transform(boneMatrices[index]);
                BoundingBoxExt.Merge(ref boundingBox, ref boundingBoxExt, out boundingBox);
            }

            // Upload bones
            renderMesh.Parameters.Set(TransformationSkinningKeys.BlendMatrixArray, boneMatrices, 0, bones.Length);
        }
예제 #5
0
        /// <summary>
        /// Create or update the Effect of the effect mesh.
        /// </summary>
        protected void UpdateEffect(RenderContext context, RenderMesh renderMesh, ParameterCollection passParameters)
        {
            if (dynamicEffectCompiler.Update(renderMesh, passParameters))
            {
                try
                {
                    renderMesh.Initialize(context.GraphicsDevice);
                }
                catch (Exception e)
                {
                    Log.Error("Could not initialize RenderMesh, trying again with error fallback effect", e);

                    // Try again with error effect to show user something failed with this model
                    // TODO: What if an exception happens in this case too? Mark renderMesh as ignored or null?
                    dynamicEffectCompiler.SwitchFallbackEffect(FallbackEffectType.Error, renderMesh, passParameters);
                    renderMesh.Initialize(context.GraphicsDevice);
                }
            }
        }
예제 #6
0
        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);
        }
        private void PreRenderMesh(RenderContext context, RenderMesh renderMesh)
        {
            var contextParameters = context.Parameters;
            RenderModelLights renderModelLights;
            if (!modelToLights.TryGetValue(renderMesh.RenderModel, out renderModelLights))
            {
                contextParameters.Set(LightingKeys.DirectLightGroups, null);
                contextParameters.Set(LightingKeys.EnvironmentLights, null);
                return;
            }

            // TODO: copy shadow receiver info to mesh
            var isShadowReceiver = renderMesh.IsShadowReceiver;
            if (currentModelLightShadersPermutationEntry != renderModelLights.LightShadersPermutation || currentModelShadersParameters != renderModelLights.Parameters || currentShadowReceiver != isShadowReceiver)
            {
                currentModelLightShadersPermutationEntry = renderModelLights.LightShadersPermutation;
                currentModelShadersParameters = renderModelLights.Parameters;
                currentShadowReceiver = isShadowReceiver;

                if (currentShadowReceiver)
                {
                    currentModelShadersParameters.Parameters.CopySharedTo(contextParameters);
                }
                else
                {
                    currentModelShadersParameters.ParametersNoShadows.CopySharedTo(contextParameters);
                }
            }
        }
예제 #8
0
 /// <summary>
 /// Create or update the Effect of the effect mesh.
 /// </summary>
 protected void UpdateEffect(RenderContext context, RenderMesh renderMesh, ParameterCollection passParameters)
 {
     if (dynamicEffectCompiler.Update(renderMesh, passParameters))
     {
         renderMesh.Initialize(context.GraphicsDevice);
     }
 }
예제 #9
0
        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);

            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)
                {
                    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: CullingMode should be pluggable
                // TODO: This should not be necessary. Add proper bounding boxes to gizmos etc.
                if (CullingMode == CullingMode.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.UpdateMaterial();

                var list = renderMesh.HasTransparency ? transparentList : opaqueList;
                list.Add(new RenderItem(this, renderMesh, projectedZ));
            }
        }
예제 #10
0
 /// <summary>
 /// Updates previously computed world matrices to TransformationKeys.World for each <see cref="RenderMesh" />.
 /// </summary>
 /// <param name="renderMesh">The render mesh.</param>
 internal void UpdateRenderMesh(RenderMesh renderMesh)
 {
     var nodeIndex = renderMesh.Mesh.NodeIndex;
     var enabled = nodeTransformations[nodeIndex].RenderingEnabledRecursive;
     renderMesh.Enabled = enabled;
     if (enabled && renderMesh.MatrixCounter != matrixCounter)
     {
         renderMesh.WorldMatrix = nodeTransformations[nodeIndex].WorldMatrix;
         renderMesh.IsGeometryInverted = nodeTransformations[nodeIndex].IsScalingNegative;
         renderMesh.MatrixCounter = matrixCounter;
     }
 }
예제 #11
0
        /// <summary>
        /// Create or update the Effect of the effect mesh.
        /// </summary>
        protected void UpdateEffect(RenderContext context, RenderMesh renderMesh, ParameterCollection passParameters)
        {
            if (dynamicEffectCompiler.Update(renderMesh, passParameters))
            {
                try
                {
                    renderMesh.Initialize(context.GraphicsDevice);
                }
                catch (Exception e)
                {
                    Log.Error("Could not initialize RenderMesh, trying again with error fallback effect", e);

                    // Try again with error effect to show user something failed with this model
                    // TODO: What if an exception happens in this case too? Mark renderMesh as ignored or null?
                    dynamicEffectCompiler.SwitchFallbackEffect(FallbackEffectType.Error, renderMesh, passParameters);
                    renderMesh.Initialize(context.GraphicsDevice);
                }
            }
        }