//-------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="CascadedShadowMapRenderer"/> class. /// </summary> /// <param name="renderCallback"> /// The method which renders the scene into the shadow map. Must not be <see langword="null"/>. /// See <see cref="RenderCallback"/> for more information. /// </param> public CascadedShadowMapRenderer(Func<RenderContext, bool> renderCallback) { if (renderCallback == null) throw new ArgumentNullException("renderCallback"); RenderCallback = renderCallback; _splitVolume = new PerspectiveViewVolume(); _orthographicCameraNode = new CameraNode(new Camera(new OrthographicProjection())); }
// Creates a lot of random objects. private void CreateRandomObjects() { var random = new Random(); var isFirstHeightField = true; int currentShape = 0; int numberOfObjects = 0; while (true) { numberOfObjects++; if (numberOfObjects > ObjectsPerType) { currentShape++; numberOfObjects = 0; } Shape shape; switch (currentShape) { case 0: // Box shape = new BoxShape(ObjectSize, ObjectSize * 2, ObjectSize * 3); break; case 1: // Capsule shape = new CapsuleShape(0.3f * ObjectSize, 2 * ObjectSize); break; case 2: // Cone shape = new ConeShape(1 * ObjectSize, 2 * ObjectSize); break; case 3: // Cylinder shape = new CylinderShape(0.4f * ObjectSize, 2 * ObjectSize); break; case 4: // Sphere shape = new SphereShape(ObjectSize); break; case 5: // Convex hull of several points. ConvexHullOfPoints hull = new ConvexHullOfPoints(); hull.Points.Add(new Vector3F(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize)); hull.Points.Add(new Vector3F(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize)); hull.Points.Add(new Vector3F(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize)); hull.Points.Add(new Vector3F(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize)); hull.Points.Add(new Vector3F(-1 * ObjectSize, 0.7f * ObjectSize, -0.6f * ObjectSize)); shape = hull; break; case 6: // A composite shape: two boxes that form a "T" shape. var composite = new CompositeShape(); composite.Children.Add( new GeometricObject( new BoxShape(ObjectSize, 3 * ObjectSize, ObjectSize), new Pose(new Vector3F(0, 0, 0)))); composite.Children.Add( new GeometricObject( new BoxShape(2 * ObjectSize, ObjectSize, ObjectSize), new Pose(new Vector3F(0, 2 * ObjectSize, 0)))); shape = composite; break; case 7: shape = new CircleShape(ObjectSize); break; case 8: { var compBvh = new CompositeShape(); compBvh.Children.Add(new GeometricObject(new BoxShape(0.5f, 1, 0.5f), new Pose(new Vector3F(0, 0.5f, 0), Matrix33F.Identity))); compBvh.Children.Add(new GeometricObject(new BoxShape(0.8f, 0.5f, 0.5f), new Pose(new Vector3F(0.5f, 0.7f, 0), Matrix33F.CreateRotationZ(-MathHelper.ToRadians(15))))); compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3F(0, 1.15f, 0), Matrix33F.Identity))); compBvh.Children.Add(new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3F(0.6f, 1.15f, 0), Matrix33F.CreateRotationX(0.3f)))); compBvh.Partition = new AabbTree<int>(); shape = compBvh; break; } case 9: CompositeShape comp = new CompositeShape(); comp.Children.Add(new GeometricObject(new BoxShape(0.5f * ObjectSize, 1 * ObjectSize, 0.5f * ObjectSize), new Pose(new Vector3F(0, 0.5f * ObjectSize, 0), QuaternionF.Identity))); comp.Children.Add(new GeometricObject(new BoxShape(0.8f * ObjectSize, 0.5f * ObjectSize, 0.5f * ObjectSize), new Pose(new Vector3F(0.3f * ObjectSize, 0.7f * ObjectSize, 0), QuaternionF.CreateRotationZ(-MathHelper.ToRadians(45))))); comp.Children.Add(new GeometricObject(new SphereShape(0.3f * ObjectSize), new Pose(new Vector3F(0, 1.15f * ObjectSize, 0), QuaternionF.Identity))); shape = comp; break; case 10: shape = new ConvexHullOfPoints(new[] { new Vector3F(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize), new Vector3F(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize), new Vector3F(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize), new Vector3F(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize), new Vector3F(-1 * ObjectSize, 0.7f * ObjectSize, -0.6f * ObjectSize) }); break; case 11: ConvexHullOfShapes shapeHull = new ConvexHullOfShapes(); shapeHull.Children.Add(new GeometricObject(new SphereShape(0.3f * ObjectSize), new Pose(new Vector3F(0, 2 * ObjectSize, 0), Matrix33F.Identity))); shapeHull.Children.Add(new GeometricObject(new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize), Pose.Identity)); shape = shapeHull; break; case 12: shape = Shape.Empty; break; case 13: var numberOfSamplesX = 10; var numberOfSamplesZ = 10; var samples = new float[numberOfSamplesX * numberOfSamplesZ]; for (int z = 0; z < numberOfSamplesZ; z++) for (int x = 0; x < numberOfSamplesX; x++) samples[z * numberOfSamplesX + x] = (float)(Math.Cos(z / 3f) * Math.Sin(x / 2f) * BoxSize / 6); HeightField heightField = new HeightField(0, 0, 2 * BoxSize, 2 * BoxSize, samples, numberOfSamplesX, numberOfSamplesZ); shape = heightField; break; //case 14: //shape = new LineShape(new Vector3F(0.1f, 0.2f, 0.3f), new Vector3F(0.1f, 0.2f, -0.3f).Normalized); //break; case 15: shape = new LineSegmentShape( new Vector3F(0.1f, 0.2f, 0.3f), new Vector3F(0.1f, 0.2f, 0.3f) + 3 * ObjectSize * new Vector3F(0.1f, 0.2f, -0.3f)); break; case 16: shape = new MinkowskiDifferenceShape { ObjectA = new GeometricObject(new SphereShape(0.1f * ObjectSize)), ObjectB = new GeometricObject(new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize)) }; break; case 17: shape = new MinkowskiSumShape { ObjectA = new GeometricObject(new SphereShape(0.1f * ObjectSize)), ObjectB = new GeometricObject(new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize)), }; break; case 18: shape = new OrthographicViewVolume(0, ObjectSize, 0, ObjectSize, ObjectSize / 2, ObjectSize * 2); break; case 19: shape = new PerspectiveViewVolume(MathHelper.ToRadians(60f), 16f / 10, ObjectSize / 2, ObjectSize * 3); break; case 20: shape = new PointShape(0.1f, 0.3f, 0.2f); break; case 21: shape = new RayShape(new Vector3F(0.2f, 0, -0.12f), new Vector3F(1, 2, 3).Normalized, ObjectSize * 2); break; case 22: shape = new RayShape(new Vector3F(0.2f, 0, -0.12f), new Vector3F(1, 2, 3).Normalized, ObjectSize * 2) { StopsAtFirstHit = true }; break; case 23: shape = new RectangleShape(ObjectSize, ObjectSize * 2); break; case 24: shape = new TransformedShape( new GeometricObject( new BoxShape(1 * ObjectSize, 2 * ObjectSize, 3 * ObjectSize), new Pose(new Vector3F(0.1f, 1, -0.2f)))); break; case 25: shape = new TriangleShape( new Vector3F(ObjectSize, 0, 0), new Vector3F(0, ObjectSize, 0), new Vector3F(ObjectSize, ObjectSize, ObjectSize)); break; //case 26: // { // // Create a composite object from which we get the mesh. // CompositeShape compBvh = new CompositeShape(); // compBvh.Children.Add(new GeometricObject(new BoxShape(0.5f, 1, 0.5f), new Pose(new Vector3F(0, 0.5f, 0), Matrix33F.Identity))); // compBvh.Children.Add( // new GeometricObject( // new BoxShape(0.8f, 0.5f, 0.5f), // new Pose(new Vector3F(0.5f, 0.7f, 0), Matrix33F.CreateRotationZ(-(float)MathHelper.ToRadians(15))))); // compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3F(0, 1.15f, 0), Matrix33F.Identity))); // compBvh.Children.Add( // new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3F(0.6f, 1.15f, 0), Matrix33F.CreateRotationX(0.3f)))); // TriangleMeshShape meshBvhShape = new TriangleMeshShape { Mesh = compBvh.GetMesh(0.01f, 3) }; // meshBvhShape.Partition = new AabbTree<int>(); // shape = meshBvhShape; // break; // } //case 27: // { // // Create a composite object from which we get the mesh. // CompositeShape compBvh = new CompositeShape(); // compBvh.Children.Add(new GeometricObject(new BoxShape(0.5f, 1, 0.5f), new Pose(new Vector3F(0, 0.5f, 0), QuaternionF.Identity))); // compBvh.Children.Add( // new GeometricObject( // new BoxShape(0.8f, 0.5f, 0.5f), // new Pose(new Vector3F(0.5f, 0.7f, 0), QuaternionF.CreateRotationZ(-(float)MathHelper.ToRadians(15))))); // compBvh.Children.Add(new GeometricObject(new SphereShape(0.3f), new Pose(new Vector3F(0, 1.15f, 0), QuaternionF.Identity))); // compBvh.Children.Add( // new GeometricObject(new CapsuleShape(0.2f, 1), new Pose(new Vector3F(0.6f, 1.15f, 0), QuaternionF.CreateRotationX(0.3f)))); // TriangleMeshShape meshBvhShape = new TriangleMeshShape { Mesh = compBvh.GetMesh(0.01f, 3) }; // meshBvhShape.Partition = new AabbTree<int>(); // shape = meshBvhShape; // break; // } case 28: shape = new ConvexPolyhedron(new[] { new Vector3F(-1 * ObjectSize, -2 * ObjectSize, -1 * ObjectSize), new Vector3F(2 * ObjectSize, -1 * ObjectSize, -0.5f * ObjectSize), new Vector3F(1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize), new Vector3F(-1 * ObjectSize, 2 * ObjectSize, 1 * ObjectSize), new Vector3F(-1 * ObjectSize, 0.7f * ObjectSize, -0.6f * ObjectSize) }); break; case 29: return; default: currentShape++; continue; } // Create an object with the random shape, pose, color and velocity. Pose randomPose = new Pose( random.NextVector3F(-BoxSize + ObjectSize * 2, BoxSize - ObjectSize * 2), random.NextQuaternionF()); var newObject = new MovingGeometricObject { Pose = randomPose, Shape = shape, LinearVelocity = random.NextQuaternionF().Rotate(new Vector3F(MaxLinearVelocity, 0, 0)), AngularVelocity = random.NextQuaternionF().Rotate(Vector3F.Forward) * RandomHelper.Random.NextFloat(0, MaxAngularVelocity), }; if (RandomHelper.Random.NextBool()) newObject.LinearVelocity = Vector3F.Zero; if (RandomHelper.Random.NextBool()) newObject.AngularVelocity = Vector3F.Zero; if (shape is LineShape || shape is HeightField) { // Do not move lines or the height field. newObject.LinearVelocity = Vector3F.Zero; newObject.AngularVelocity = Vector3F.Zero; } // Create only 1 heightField! if (shape is HeightField) { if (isFirstHeightField) { isFirstHeightField = true; newObject.Pose = new Pose(new Vector3F(-BoxSize, -BoxSize, -BoxSize)); } else { currentShape++; numberOfObjects = 0; continue; } } // Add collision object to collision domain. _domain.CollisionObjects.Add(new CollisionObject(newObject)); //co.Type = CollisionObjectType.Trigger; //co.Name = "Object" + shape.GetType().Name + "_" + i; } }
public override void Update(GameTime gameTime) { Random random = new Random(1234567); // The debug renderer stores all draw commands. In this sample we recreate // the draw jobs each frame. --> Clear draw jobs of last frame. _debugRenderer.Clear(); // The DebugRenderer can draw stuff "in" the scene (enabled z test) or "over" // the scene (disabled z test). // Draw some points and line "in" and "over" the scene. for (int i = 0; i < 10; i++) { var position = new Vector3F(-6, 0, -3) + random.NextVector3F(-0.5f, 0.5f); _debugRenderer.DrawPoint(position, Color.Green, false); } for (int i = 0; i < 10; i++) { var position = new Vector3F(-4, 0, -3) + random.NextVector3F(-0.5f, 0.5f); _debugRenderer.DrawPoint(position, Color.Yellow, true); } for (int i = 0; i < 10; i++) { var start = new Vector3F(-2, 0, -3) + random.NextVector3F(-0.5f, 0.5f); var end = new Vector3F(-2, 0, -3) + random.NextVector3F(-0.5f, 0.5f); _debugRenderer.DrawLine(start, end, Color.Green, false); } for (int i = 0; i < 10; i++) { var start = new Vector3F(0, 0, -3) + random.NextVector3F(-0.5f, 0.5f); var end = new Vector3F(0, 0, -3) + random.NextVector3F(-0.5f, 0.5f); _debugRenderer.DrawLine(start, end, Color.Yellow, true); } // Text without a specified position is drawn at a default position. _debugRenderer.DefaultTextPosition = new Vector2F(10, 100); _debugRenderer.DrawText("White objects are positioned in screen space."); _debugRenderer.DrawText("Yellow objects are positioned in world space. Depth test disabled."); _debugRenderer.DrawText("Other objects are positioned in world space. Depth test enabled."); // Text can also be drawn in world space coordinates or in screen space coordinates. _debugRenderer.DrawText("WorldSpacePosition (0, 0, 0)", new Vector3F(0, 0, 0), Color.Green, false); _debugRenderer.DrawText("WorldSpacePosition (0, 0, -1)", new Vector3F(0, 0, -1), Color.Yellow, true); _debugRenderer.DrawText("ScreenPosition (600, 40)", new Vector2F(600, 40), Color.White); _debugRenderer.DrawText("ScreenPosition (640, 360)", new Vector2F(640, 360), Color.White); // It is often useful to copy textures to the screen for debugging. _debugRenderer.DrawTexture(NoiseHelper.GetGrainTexture(GraphicsService, 128), new Rectangle(1000, 10, 128, 128)); // Axes can be drawn to display poses (positions and orientations). _debugRenderer.DrawAxes(new Pose(new Vector3F(0, 0, 0)), 1, true); // Axis-aligned bounding boxes (AABB) _debugRenderer.DrawAabb(new Aabb(new Vector3F(-0.5f), new Vector3F(0.5f)), new Pose(new Vector3F(2, 0, -3)), Color.Green, false); _debugRenderer.DrawAabb(new Aabb(new Vector3F(-0.5f), new Vector3F(0.5f)), new Pose(new Vector3F(4, 0, -3)), Color.Yellow, true); // Box shapes var orientation = random.NextQuaternionF(); _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-6, 0, -5), orientation), new Color(255, 0, 0, 100), false, false); _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-6, 0, -5), orientation), Color.Green, true, false); _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-4, 0, -5), orientation), Color.Yellow, true, true); // View volumes (frustums) var viewVolume = new PerspectiveViewVolume(1, 2, 0.1f, 1f); _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(-2, 0, -5), orientation), new Color(0, 255, 0, 100), false, false); _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(-2, 0, -5), orientation), Color.Green, true, false); _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(0, 0, -5), orientation), Color.Yellow, true, true); // Spheres _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(2, 0, -5), orientation), new Color(0, 0, 255, 100), false, false); _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(2, 0, -5), orientation), Color.Green, true, false); _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(4, 0, -5), orientation), Color.Yellow, true, true); // Capsules _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-6, 0, -7), orientation), new Color(255, 255, 0, 100), false, false); _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-6, 0, -7), orientation), Color.Green, true, false); _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-4, 0, -7), orientation), Color.Yellow, true, true); // Cylinders _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(-2, 0, -7), orientation), new Color(255, 0, 255, 100), false, false); _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(-2, 0, -7), orientation), Color.Green, true, false); _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(0, 0, -7), orientation), Color.Yellow, true, true); // Cones _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(2, 0, -7), orientation), new Color(0, 255, 255, 100), false, false); _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(2, 0, -7), orientation), Color.Green, true, false); _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(4, 0, -7), orientation), Color.Yellow, true, true); // The debug renderer can draw any IGeometricObjects, like SceneNodes, RigidBodies, etc. _debugRenderer.DrawObject(_geometricObject, Color.Brown, false, false); _debugRenderer.DrawObject(_geometricObject, Color.Yellow, true, true); // The debug renderer can also an XNA model (without materials). _debugRenderer.DrawModel(_xnaModel, new Pose(new Vector3F(0, 2, -2), orientation), new Vector3F(1, 2, 1), new Color(128, 255, 64, 100), false, false); _debugRenderer.DrawModel(_xnaModel, new Pose(new Vector3F(0, 2, -2), orientation), new Vector3F(1, 2, 1), Color.LightCyan, true, false); // Draw a DigitalRune model. _debugRenderer.DrawModel(_modelNode, Color.Peru, true, false); // Draw the bounding shapes of the meshes in this model. foreach (var node in _modelNode.GetSubtree()) _debugRenderer.DrawObject(node, Color.PeachPuff, true, false); }
//-------------------------------------------------------------- #region Creation & Cleanup //-------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="VarianceShadowMapRenderer"/> class. /// </summary> /// <param name="render"> /// The method which renders the scene into the shadow map. Must not be <see langword="null"/>. /// See <see cref="RenderCallback"/> for more information. /// </param> public VarianceShadowMapRenderer(Func<RenderContext, bool> render) { if (render == null) throw new ArgumentNullException("render"); RenderCallback = render; _cameraVolume = new PerspectiveViewVolume(); _orthographicCameraNode = new CameraNode(new Camera(new OrthographicProjection())); }
/// <summary> /// Initializes a new instance of the <see cref="OcclusionBuffer"/> class with the specified /// buffer size. /// </summary> /// <param name="graphicsService">The graphics service.</param> /// <param name="width">The width of the occlusion buffer.</param> /// <param name="height">The height of the occlusion buffer.</param> /// <param name="bufferSize"> /// The size of the internal triangle buffer (= max number of occluder triangles that can be /// rendered in a single draw call). Needs to be large enough to store the most complex /// occluder. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="graphicsService"/> is <see langword="null"/>. /// </exception> public OcclusionBuffer(IGraphicsService graphicsService, int width, int height, int bufferSize) { if (graphicsService == null) throw new ArgumentNullException("graphicsService"); // For simplicity only accept power-of-two formats. if (!MathHelper.IsPowerOf2(width) && !MathHelper.IsPowerOf2(height)) throw new ArgumentException("Width and height of occlusion buffer expected to be a power of two."); // The current texture atlas layout assumes that width ≥ height. if (width < height) throw new ArgumentException("Width expected to be greater than or equal to the height of the occlusion buffer."); var graphicsDevice = graphicsService.GraphicsDevice; if (bufferSize < 1) throw new ArgumentOutOfRangeException("bufferSize", "The buffer size needs to be creater than 1."); if (bufferSize >= graphicsDevice.GetMaxPrimitivesPerCall()) throw new ArgumentOutOfRangeException("bufferSize", "The buffer size exceeds the max number of primitives supported by the current graphics device."); // ----- RenderBatch handles occluders. // bufferSize is the max number of triangles per draw call. // Vertex buffer size: // - In the worst case n triangles need n * 3 vertices. // - The max size is limited to 65536 because 16-bit indices are used. var vertices = new Vector3F[Math.Min(bufferSize * 3, ushort.MaxValue + 1)]; // Index buffer size: number of triangles * 3 var indices = new ushort[bufferSize * 3]; _renderBatch = new RenderBatch<Vector3F, ushort>( graphicsDevice, VertexPosition.VertexDeclaration, vertices, true, indices, true); _effect = graphicsService.Content.Load<Effect>("DigitalRune/OcclusionCulling"); _parameterClampAabbMinimum = _effect.Parameters["ClampAabbMinimum"]; _parameterClampAabbMaximum = _effect.Parameters["ClampAabbMaximum"]; _parameterCameraViewProj = _effect.Parameters["CameraViewProj"]; _parameterCameraNear = _effect.Parameters["CameraNear"]; _parameterCameraFar = _effect.Parameters["CameraFar"]; _parameterCameraPosition = _effect.Parameters["CameraPosition"]; _parameterNormalizationFactor = _effect.Parameters["NormalizationFactor"]; _parameterLightViewProj = _effect.Parameters["LightViewProj"]; _parameterLightToCamera = _effect.Parameters["LightToCamera"]; _parameterHzbSize = _effect.Parameters["HzbSize"]; _parameterTargetSize = _effect.Parameters["TargetSize"]; _parameterAtlasSize = _effect.Parameters["AtlasSize"]; _parameterTexelOffset = _effect.Parameters["TexelOffset"]; _parameterHalfTexelOffset = _effect.Parameters["HalfTexelOffset"]; _parameterMaxLevel = _effect.Parameters["MaxLevel"]; _parameterHzbTexture = _effect.Parameters["HzbTexture"]; _parameterLightHzbTexture = _effect.Parameters["LightHzb"]; _parameterDebugLevel = _effect.Parameters["DebugLevel"]; _parameterDebugMinimum = _effect.Parameters["DebugMinimum"]; _parameterDebugMaximum = _effect.Parameters["DebugMaximum"]; _techniqueOccluder = _effect.Techniques["Occluder"]; _techniqueDownsample = _effect.Techniques["Downsample"]; _techniqueCopy = _effect.Techniques["Copy"]; _techniqueQuery = _effect.Techniques["Query"]; _techniqueVisualize = _effect.Techniques["Visualize"]; _occlusionProxies = new List<IOcclusionProxy>(); _sceneNodes = new List<SceneNode>(); // Store delegate methods to avoid garbage. _updateOcclusionProxies = UpdateOcclusionProxies; _updateOcclusionProxy = UpdateOcclusionProxy; _splitVolume = new PerspectiveViewVolume(); _orthographicCameraNode = new CameraNode(new Camera(new OrthographicProjection())); _shadowCasters = new List<SceneNode>(); /* // By default, enable multithreading on multi-core systems. #if WP7 || UNITY // Cannot access Environment.ProcessorCount in phone app. (Security issue.) EnableMultithreading = false; #else // Enable multithreading by default if the current system has multiple processors. EnableMultithreading = Environment.ProcessorCount > 1; // Multithreading works but Parallel.For of Xamarin.Android/iOS is very inefficient. if (GlobalSettings.PlatformID == PlatformID.Android || GlobalSettings.PlatformID == PlatformID.iOS) EnableMultithreading = false; #endif */ // Disable multithreading by default. Multithreading causes massive lags in the // XNA version, but the MonoGame version is not affected!? EnableMultithreading = false; // For best performance: Enable progressive shadow caster culling. ProgressiveShadowCasterCulling = true; Statistics = new OcclusionCullingStatistics(); InitializeBuffers(graphicsDevice, width, height); }
public void PerspectiveViewVolumeTest() { var s = new PerspectiveViewVolume(0.4f, 2, 0.1f, 1f); var v0 = s.GetVolume(0.001f, 10); var m = s.GetMesh(0.001f, 10); var s1 = new TriangleMeshShape(m); var v1 = s1.GetVolume(0.0001f, 10); Assert.IsTrue(Numeric.AreEqual(v0, v1, 0.01f * (1 + v0))); // 1% error is allowed. }
//-------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="PerspectiveProjection"/> class. /// </summary> public PerspectiveProjection() { ViewVolume = new PerspectiveViewVolume(); SetFieldOfView(DefaultFieldOfViewY, DefaultAspectRatio, DefaultNear, DefaultFar); }