private void Render(RenderContext context) { // Set the current camera node in the render context. This info is used // by the renderers. context.CameraNode = _cameraObject.CameraNode; var device = context.GraphicsService.GraphicsDevice; device.Clear(Color.CornflowerBlue); device.DepthStencilState = DepthStencilState.Default; device.RasterizerState = RasterizerState.CullCounterClockwise; device.BlendState = BlendState.Opaque; // Render the meshes one by one (The next sample, SceneSample, shows how to // do this more efficiently.) // We have to select a render pass. This info is needed by the MeshRenderer // to decide which shaders must be used. context.RenderPass = "******"; foreach (var meshNode in _model.GetSubtree().OfType <MeshNode>()) { _meshRenderer.Render(meshNode, context); } _debugRenderer.Render(context); // Clean up. context.RenderPass = null; context.CameraNode = null; }
public ManualMeshRenderSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService) { RenderCallback = Render, }; GraphicsService.Screens.Insert(0, delegateGraphicsScreen); // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); GameObjectService.Objects.Add(_cameraObject); _scene = new Scene(); SceneSample.InitializeDefaultXnaLights(_scene); // For advanced users: Set this flag if you want to analyze the imported opaque data of // effect bindings. EffectBinding.KeepOpaqueData = true; _model = ContentManager.Load <ModelNode>("Dude/Dude").Clone(); var meshNode = _model.GetSubtree().OfType <MeshNode>().First(); meshNode.ScaleLocal = new Vector3(1, 2, 1); var mesh = meshNode.Mesh; var timeline = new TimelineClip(mesh.Animations.Values.First()) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle, }; AnimationService.StartAnimation(timeline, (IAnimatableProperty)meshNode.SkeletonPose); }
// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { // Load model. var contentManager = _services.GetInstance <ContentManager>(); _modelNode = contentManager.Load <ModelNode>(_assetName).Clone(); // Optional: Create rigid body using the triangle mesh of the model. if (_addRigidBody) { CreateRigidBody(); } _modelNode.ScaleLocal = _scale; _modelNode.PoseLocal = _pose; foreach (var node in _modelNode.GetSubtree()) { node.CastsShadows = _castsShadows; // If models will never move, set the IsStatic flag. This gives the engine // more room for optimizations. Additionally, some effects, like certain // decals, may only affect static geometry. node.IsStatic = true; } // Add model node to scene graph. var scene = _services.GetInstance <IScene>(); scene.Children.Add(_modelNode); }
public SkinnedEffectSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.ClearBackground = true; GraphicsScreen.BackgroundColor = Color.CornflowerBlue; SetCamera(new Vector3F(1, 1, 3), 0.2f, 0); // Create a sky mesh and add an instance of this mesh to the scene. var skyMesh = ProceduralSkyDome.CreateMesh(GraphicsService, ContentManager.Load <Texture2D>("sky")); _sky = new MeshNode(skyMesh); _sky.Name = "Sky"; // Always set a name - very useful for debugging! GraphicsScreen.Scene.Children.Add(_sky); // Load the skinned model. This model is processed using the DigitalRune Model // Processor - not the default XNA model processor! // In the folder that contains dude.fbx, there are several XML files (*.drmdl and *.drmat) // which define the materials of the model. These material description files are // automatically processed by the DigitalRune Model Processor. Please browse // to the content folder and have a look at the *.drmdl and *.drmat files. _dudeModel = ContentManager.Load <ModelNode>("Dude/Dude"); _dudeModel = _dudeModel.Clone(); _dudeModel.PoseWorld = new Pose(Matrix33F.CreateRotationY(ConstantsF.Pi)); GraphicsScreen.Scene.Children.Add(_dudeModel); // The dude model consists of a single mesh. var dudeMeshNode = _dudeModel.GetSubtree().OfType <MeshNode>().First(); var mesh = dudeMeshNode.Mesh; /* * // The dude mesh consists of different materials (head, eyes, torso, ...). * // We could change some of the material properties... * foreach (var material in mesh.Materials) * { * // Get all SkinnedEffectBindings which wrap the XNA SkinnedEffect. * // A material can consist of several effects - one effect for each render pass. * // (Per default there is only one render pass called "Default".) * foreach (var effectBinding in material.EffectBindings.OfType<SkinnedEffectBinding>()) * { * // We could change effect parameters here, for example: * effectBinding.PreferPerPixelLighting = true; * } * } */ // The DigitalRune Model Processor also loads animations. // Start the first animation of the dude and let it loop forever. // (We keep the animation controller to be able to stop the animation in // Dispose() below.) var timeline = new TimelineClip(mesh.Animations.Values.First()) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle, }; _animationController = AnimationService.StartAnimation(timeline, (IAnimatableProperty)dudeMeshNode.SkeletonPose); }
/// <summary> /// Positions the camera so that it sees the whole model and is not to near or to far away. /// </summary> private void ResetCameraPose() { if (ModelNode == null && Document.Model == null) { var lookAtMatrix = Matrix.CreateLookAt(new Vector3(10, 10, 10), new Vector3(0, 1, 0), new Vector3(0, 1, 0)); _cameraNode.PoseWorld = Pose.FromMatrix(lookAtMatrix).Inverse; ModelCenter = new Vector3(0, 1, 0); MoveSpeed = 5; ZoomSpeed = MoveSpeed / 10; return; } // Get combined AABB of scene nodes. Aabb aabb = new Aabb(); if (ModelNode != null) { foreach (var meshNode in ModelNode.GetSubtree().OfType <MeshNode>()) { aabb.Grow(meshNode.Aabb); } } else { Matrix[] boneTransforms = new Matrix[Document.Model.Bones.Count]; Document.Model.CopyAbsoluteBoneTransformsTo(boneTransforms); foreach (var mesh in Document.Model.Meshes) { var sphere = mesh.BoundingSphere; sphere = sphere.Transform(boneTransforms[mesh.ParentBone.Index]); var partCenter = (Vector3)sphere.Center; var partRadius = new Vector3(sphere.Radius); aabb.Grow(new Aabb(partCenter - partRadius, partCenter + partRadius)); } } // Set camera position. var center = aabb.Center; var radius = aabb.Extent.Length / 2; var gamma = _cameraNode.Camera.Projection.FieldOfViewY / 2; var distance = Math.Max((float)(radius / Math.Tan(gamma)) * 0.7f, 1); // * 0.x to move a bit closer otherwise distance is usually to large. _cameraNode.PoseWorld = Pose.FromMatrix( Matrix.CreateLookAt(center + new Vector3(distance), center, Vector3.Up)).Inverse; // Center for camera orbiting. ModelCenter = center; // Make navigation speed relative to model size. MoveSpeed = Math.Max(radius * 4, 1); ZoomSpeed = MoveSpeed / 10; }
private void CreateRigidBody() { var triangleMesh = new TriangleMesh(); foreach (var meshNode in _modelNode.GetSubtree().OfType <MeshNode>()) { // Extract the triangle mesh from the DigitalRune Graphics Mesh instance. var subTriangleMesh = new TriangleMesh(); foreach (var submesh in meshNode.Mesh.Submeshes) { submesh.ToTriangleMesh(subTriangleMesh); } // Apply the transformation of the mesh node. subTriangleMesh.Transform(meshNode.PoseWorld * Matrix.CreateScale(meshNode.ScaleWorld)); // Combine into final triangle mesh. triangleMesh.Add(subTriangleMesh); } // Create a collision shape that uses the mesh. var triangleMeshShape = new TriangleMeshShape(triangleMesh); // Optional: Assign a spatial partitioning scheme to the triangle mesh. (A spatial partition // adds an additional memory overhead, but it improves collision detection speed tremendously!) triangleMeshShape.Partition = new CompressedAabbTree { // The tree is automatically built using a mixed top-down/bottom-up approach. Bottom-up // building is slower but produces better trees. If the tree building takes too long, // we can lower the BottomUpBuildThreshold (default is 128). BottomUpBuildThreshold = 0, }; _rigidBody = new RigidBody(triangleMeshShape, new MassFrame(), null) { Pose = _pose, Scale = _scale, MotionType = MotionType.Static }; // Add rigid body to physics simulation and model to scene. var simulation = _services.GetInstance <Simulation>(); simulation.RigidBodies.Add(_rigidBody); }
// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { // Load model. var contentManager = _services.GetInstance <ContentManager>(); _modelNode = contentManager.Load <ModelNode>("Ground/Ground").Clone(); _modelNode.ScaleLocal = new Vector3(0.5f); foreach (var node in _modelNode.GetSubtree()) { // Disable the CastsShadows flag for ground meshes. No need to render // this model into the shadow map. (This also avoids any shadow acne on // the ground model.) node.CastsShadows = false; // If models will never move, set the IsStatic flag. This gives the engine // more room for optimizations. Additionally, some effects, like certain // decals, may only affect static geometry. node.IsStatic = true; } // Add model node to scene graph. var scene = _services.GetInstance <IScene>(); scene.Children.Add(_modelNode); // Create rigid body. _rigidBody = new RigidBody(new PlaneShape(Vector3.UnitY, 0)) { MotionType = MotionType.Static, }; // Add rigid body to the physics simulation. var simulation = _services.GetInstance <Simulation>(); simulation.RigidBodies.Add(_rigidBody); }
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); } }
private void Render(RenderContext context) { // Set the current camera node in the render context. This info is used // by the renderers. context.CameraNode = _cameraObject.CameraNode; context.Scene = _scene; var device = context.GraphicsService.GraphicsDevice; device.Clear(Color.CornflowerBlue); device.DepthStencilState = DepthStencilState.Default; device.RasterizerState = RasterizerState.CullCounterClockwise; device.BlendState = BlendState.Opaque; context.RenderPass = "******"; foreach (var meshNode in _model.GetSubtree().OfType <MeshNode>()) { context.SceneNode = meshNode; foreach (var submesh in meshNode.Mesh.Submeshes) { var materialIndex = submesh.MaterialIndex; var materialInstance = meshNode.MaterialInstances[materialIndex]; var material = materialInstance.Material; var materialInstanceBinding = materialInstance[context.RenderPass]; var materialBinding = material[context.RenderPass]; var effect = materialBinding.Effect; context.MaterialBinding = materialBinding; context.MaterialInstanceBinding = materialInstanceBinding; // Update and apply global bindings. foreach (var binding in effect.GetParameterBindings()) { if (binding.Description.Hint == EffectParameterHint.Global) { binding.Update(context); binding.Apply(context); } } // Update and apply material bindings. foreach (var binding in materialBinding.ParameterBindings) { binding.Update(context); binding.Apply(context); } // Update and apply local and per-instance bindings. foreach (var binding in materialInstanceBinding.ParameterBindings) { if (binding.Description.Hint != EffectParameterHint.PerPass) { binding.Update(context); binding.Apply(context); } } // Select and apply effect technique. var techniqueBinding = materialInstanceBinding.TechniqueBinding; techniqueBinding.Update(context); var technique = techniqueBinding.GetTechnique(effect, context); effect.CurrentTechnique = technique; // Select and apply effect passes. var passBinding = techniqueBinding.GetPassBinding(technique, context); foreach (var pass in passBinding) { // Update and apply per-pass bindings. foreach (var binding in materialInstanceBinding.ParameterBindings) { if (binding.Description.Hint == EffectParameterHint.PerPass) { binding.Update(context); binding.Apply(context); } } pass.Apply(); submesh.Draw(); } context.MaterialBinding = null; context.MaterialInstanceBinding = null; } } context.SceneNode = null; context.RenderPass = null; // Clean up. context.CameraNode = null; context.Scene = null; }
public MeshNodeSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService) { RenderCallback = Render, }; GraphicsService.Screens.Insert(0, delegateGraphicsScreen); // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); GameObjectService.Objects.Add(_cameraObject); // For advanced users: Set this flag if you want to analyze the imported opaque data of // effect bindings. //EffectBinding.KeepOpaqueData = true; // Load a model. The model is processed using the DigitalRune Model Processor - not // the default XNA model processor! // In the folder that contains tank.fbx, there is an XML file tank.drmdl which defines // properties of the model. These XML files are automatically processed by the // DigitalRune Model Processor. // Each model itself is a tree of scene nodes. The grid model contains one mesh // node. The tank model contains several mesh nodes (turret, cannon, hatch, // wheels, ...). _model = ContentManager.Load <ModelNode>("Tank/tank"); // The XNA ContentManager manages a single instance of each model. We clone // the model, to get a copy that we can modify without changing the original // instance. Cloning is fast because it only duplicates the scene nodes - but // not the mesh and material information. _model = _model.Clone(); // _model is the root of a tree of scene nodes. The mesh nodes are the child // nodes. When we scale or move the _model, we automatically scale and move // all child nodes. _model.ScaleLocal = new Vector3F(0.8f); _model.PoseWorld = new Pose(new Vector3F(0, 0, -2), Matrix33F.CreateRotationY(-0.3f)); // Let's loop through the mesh nodes of the model: foreach (var meshNode in _model.GetSubtree().OfType <MeshNode>()) { // Each MeshNode references a Mesh. Mesh mesh = meshNode.Mesh; // The mesh consists of several submeshes and several materials - usually // one material per submesh, but several submeshes could reference the same // materials. // Let's loop through the materials of this mesh. foreach (var material in mesh.Materials) { // A material is a collection of EffectBindings - one EffectBinding for each // render pass. For example, a complex game uses several render passes, like // a pre-Z pass, a G-buffer pass, a shadow map pass, a deferred material pass, // etc.In simple games there is only one pass which is called "Default". var effectBinding = material["Default"]; // An EffectBinding references an Effect (the XNA Effect class) and it has // "parameter bindings" and "technique bindings". These bindings select the // values for the shader parameters when the mesh node is rendered. // Let's change the binding for the DiffuseColor of the shader to give tank // a red color. effectBinding.Set("DiffuseColor", new Vector4(1, 0.7f, 0.7f, 1)); // The tank uses the default effect binding which is a BasicEffectBinding - this // effect binding uses the XNA BasicEffect. // In this sample we do not define any lights, therefore we disable the lighting // in the shader. ((BasicEffectBinding)effectBinding).LightingEnabled = false; } } _meshRenderer = new MeshRenderer(); var spriteFont = UIContentManager.Load <SpriteFont>("UI Themes/BlendBlue/Default"); _debugRenderer = new DebugRenderer(GraphicsService, spriteFont); }
// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { // Load sandbox model. var contentManager = _services.GetInstance <ContentManager>(); _modelNode = contentManager.Load <ModelNode>("Sandbox/Sandbox").Clone(); foreach (var node in _modelNode.GetSubtree()) { // Disable the CastsShadows flag. The inside of the box should be fully lit. node.CastsShadows = false; // If models will never move, set the IsStatic flag. This gives the engine // more room for optimizations. Additionally, some effects, like certain // decals, may only affect static geometry. node.IsStatic = true; } // Add the "Sandbox" model to the scene. var scene = _services.GetInstance <IScene>(); scene.Children.Add(_modelNode); // Create rigid bodies for the sides of the sandbox. _floorRigidBody = new RigidBody(new PlaneShape(new Vector3(0, 1, 0), 0)) { Name = "Floor", MotionType = MotionType.Static, }; _floorRigidBody.CollisionObject.CollisionGroup = 1; _leftWallRigidBody = new RigidBody(new PlaneShape(new Vector3(1, 0, 0), -10)) { Name = "WallLeft", MotionType = MotionType.Static, }; _leftWallRigidBody.CollisionObject.CollisionGroup = 1; _rightWallRigidBody = new RigidBody(new PlaneShape(new Vector3(-1, 0, 0), -10)) { Name = "WallRight", MotionType = MotionType.Static, }; _rightWallRigidBody.CollisionObject.CollisionGroup = 1; _backWallRigidBody = new RigidBody(new PlaneShape(new Vector3(0, 0, 1), -10)) { Name = "WallBack", MotionType = MotionType.Static, }; _backWallRigidBody.CollisionObject.CollisionGroup = 1; _frontWallRigidBody = new RigidBody(new PlaneShape(new Vector3(0, 0, -1), -10)) { Name = "WallFront", MotionType = MotionType.Static, }; _frontWallRigidBody.CollisionObject.CollisionGroup = 1; // Add rigid bodies to simulation. var simulation = _services.GetInstance <Simulation>(); simulation.RigidBodies.Add(_floorRigidBody); simulation.RigidBodies.Add(_leftWallRigidBody); simulation.RigidBodies.Add(_rightWallRigidBody); simulation.RigidBodies.Add(_backWallRigidBody); simulation.RigidBodies.Add(_frontWallRigidBody); }