} // Dispose() #endregion #region Render /// <summary> /// Render /// </summary> /// <param name="renderMatrix">Render matrix</param> public void Render(Matrix renderMatrix, float alpha) { // Make sure alpha is valid if (alpha <= 0) { return; // skip, no reason to render this! } if (alpha > 1) { alpha = 1; } float distanceSquared = Vector3.DistanceSquared( BaseGame.CameraPos, renderMatrix.Translation); // Check out if object is behind us or not visible, then we can skip // rendering. This is the GREATEST performance gain in the whole game! // Object must be away at least 20 units! if (distanceSquared > 20 * 20) { Vector3 objectDirection = Vector3.Normalize(BaseGame.CameraPos - renderMatrix.Translation); // Half field of view should be fov / 2, but because of // the aspect ratio (1.33) and an additional offset we need // to include to see objects at the borders. float objAngle = Vector3Helper.GetAngleBetweenVectors( BaseGame.CameraRotation, objectDirection); if (objAngle > BaseGame.FieldOfView) //.ViewableFieldOfView) // Skip. { return; } } // if (distanceSquared) // Just render the only renderable mesh we got. The mesh part adds // the render matrix to be picked up in the mesh rendering later. renderableMesh.thisFrameRenderMatricesAndAlpha.Add( new MeshRenderManager.MatrixAndAlpha(objectMatrix * renderMatrix, alpha)); } // Render(renderMatrix, alpha)
/// <summary> /// Render /// </summary> /// <param name="renderMatrix">Render matrix</param> public void Render(Matrix renderMatrix) { // Optimization to skip smaller objects, which are very far away! // Display 1 meter big objects only if in a distance of 250 meters! // Scaling is guessed by the length of the first vector in our matrix, // because we always use the same scaling for x, y, z this should be // correct! float maxDistance = maxViewDistance * scaling; float distanceSquared = Vector3.DistanceSquared( BaseGame.CameraPos, renderMatrix.Translation); if (distanceSquared > maxDistance * maxDistance) { // Don't render, too far away! return; } // Check out if object is behind us or not visible, then we can skip // rendering. This is the GREATEST performance gain in the whole game! // Object must be away at least 20 units! if (distanceSquared > 20 * 20 && // And the object size must be small distanceSquared > (10 * scaling) * (10 * scaling)) { Vector3 objectDirection = Vector3.Normalize(BaseGame.CameraPos - renderMatrix.Translation); // Half field of view should be fov / 2, but because of // the aspect ratio (1.33) and an additional offset we need // to include to see objects at the borders. float objAngle = Vector3Helper.GetAngleBetweenVectors( BaseGame.CameraRotation, objectDirection); if (objAngle > BaseGame.ViewableFieldOfView) { // Skip. return; } } // Multiply object matrix by render matrix, result is used multiple // times here. renderMatrix = objectMatrix * renderMatrix; // Go through all meshes in the model for (int meshNum = 0; meshNum < xnaModel.Meshes.Count; meshNum++) { ModelMesh mesh = xnaModel.Meshes[meshNum]; // Assign world matrix Matrix worldMatrix = transforms[mesh.ParentBone.Index] * renderMatrix; // Got animation? if (animatedMesh == mesh) { worldMatrix = Matrix.CreateRotationZ( // Use pseudo number for this object for different rotations renderMatrix.Translation.Length() * 3 + renderMatrix.Determinant() * 5 + (1.0f + ((int)(renderMatrix.M42 * 33.3f) % 100) * 0.00123f) * BaseGame.TotalTime / 0.654f) * transforms[mesh.ParentBone.Index] * renderMatrix; } // Just add this world matrix to our render matrices for each part. for (int partNum = 0; partNum < mesh.MeshParts.Count; partNum++) { // Find mesh part in the renderableMeshes dictionary and add the // new render matrix to be picked up in the mesh rendering later. renderableMeshes[mesh.MeshParts[partNum]].renderMatrices.Add( worldMatrix); } } }