// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { var contentManager = _services.GetInstance<ContentManager>(); if (_type == 1) { // A simple cube. RigidBody = new RigidBody(new BoxShape(1, 1, 1)); ModelNode = contentManager.Load<ModelNode>("RustyCube/RustyCube").Clone(); } else if (_type == 2) { // Another simple cube. RigidBody = new RigidBody(new BoxShape(1, 1, 1)); ModelNode = contentManager.Load<ModelNode>("MetalGrateBox/MetalGrateBox").Clone(); } else if (_type == 3) { // A TV-like box. RigidBody = new RigidBody(new BoxShape(1, 0.6f, 0.8f)) { UserData = "TV" }; ModelNode = contentManager.Load<ModelNode>("TVBox/TVBox"); if (ModelNode.Children.OfType<LightNode>().Count() == 0) { // This is the first time the "TVBox" is loaded. // Add a projector light to the model that projects the TV screen. The // TV screen is the emissive part of the TV mesh. var meshNode = ModelNode.Children.OfType<MeshNode>().First(); var material = meshNode.Mesh.Materials.First(m => m.Name == "TestCard"); // Get texture from material. // Note: In XNA the effect parameter type is Texture. In MonoGame it is Texture2D. Texture2D texture; EffectParameterBinding parameterBinding = material["Material"].ParameterBindings["EmissiveTexture"]; if (parameterBinding is EffectParameterBinding<Texture>) texture = (Texture2D)((EffectParameterBinding<Texture>)parameterBinding).Value; else texture = ((EffectParameterBinding<Texture2D>)parameterBinding).Value; var projection = new PerspectiveProjection(); projection.Near = 0.55f; projection.Far = 3.0f; projection.SetFieldOfView(MathHelper.ToRadians(60), 0.76f / 0.56f); var projectorLight = new ProjectorLight(texture, projection); projectorLight.Attenuation = 4; var projectorLightNode = new LightNode(projectorLight); projectorLightNode.LookAt(new Vector3F(0, 0.2f, 0), Vector3F.Zero, Vector3F.UnitZ); // Attach the projector light to the model. ModelNode.Children.Add(projectorLightNode); } ModelNode = ModelNode.Clone(); } else if (_type == 4) { // A "magic" sphere with a colored point light. RigidBody = new RigidBody(new SphereShape(0.25f)); ModelNode = contentManager.Load<ModelNode>("MagicSphere/MagicSphere"); if (ModelNode.Children.OfType<LightNode>().Count() == 0) { // This is the first time the "MagicSphere" is loaded. // Change the size of the sphere. var meshNode = ModelNode.Children.OfType<MeshNode>().First(); meshNode.ScaleLocal = new Vector3F(0.5f); // Disable shadows. (The sphere acts as a light source.) meshNode.CastsShadows = false; // Add a point light. var pointLight = new PointLight { Color = new Vector3F(1, 1, 1), DiffuseIntensity = 4, SpecularIntensity = 4, Range = 3, Attenuation = 1, Texture = contentManager.Load<TextureCube>("MagicSphere/ColorCube"), }; var pointLightNode = new LightNode(pointLight) { // The point light uses shadow mapping to cast an omnidirectional shadow. Shadow = new CubeMapShadow { PreferredSize = 64, } }; ModelNode.Children.Add(pointLightNode); } ModelNode = ModelNode.Clone(); } else if (_type == 5) { // A sphere of glass (or "bubble"). RigidBody = new RigidBody(new SphereShape(0.3f)); ModelNode = contentManager.Load<ModelNode>("Bubble/Bubble").Clone(); ModelNode.GetDescendants().OfType<MeshNode>().First().ScaleLocal = new Vector3F(0.3f); } else if (_type == 6) { // A rusty barrel with multiple levels of detail (LODs). RigidBody = new RigidBody(new CylinderShape(0.35f, 1)); ModelNode = contentManager.Load<ModelNode>("Barrel/Barrel").Clone(); } else { // A cube consisting of a frame and transparent sides. RigidBody = new RigidBody(new BoxShape(1, 1, 1)); ModelNode = contentManager.Load<ModelNode>("GlassBox/GlassBox").Clone(); } SampleHelper.EnablePerPixelLighting(ModelNode); // Set a random pose. var randomPosition = new Vector3F( RandomHelper.Random.NextFloat(-10, 10), RandomHelper.Random.NextFloat(2, 5), RandomHelper.Random.NextFloat(-20, 0)); RigidBody.Pose = new Pose(randomPosition, RandomHelper.Random.NextQuaternionF()); ModelNode.PoseWorld = RigidBody.Pose; // Add rigid body to physics simulation and model to scene. var simulation = _services.GetInstance<Simulation>(); simulation.RigidBodies.Add(RigidBody); var scene = _services.GetInstance<IScene>(); scene.Children.Add(ModelNode); }
public FacialAnimationSample(Microsoft.Xna.Framework.Game game) : base(game) { _graphicsScreen = new DeferredGraphicsScreen(Services) { DrawReticle = false }; GraphicsService.Screens.Insert(0, _graphicsScreen); Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer); Services.Register(typeof(IScene), null, _graphicsScreen.Scene); // Add a game object which adds some GUI controls for the deferred graphics // screen to the Options window. GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services)); // Use a fixed camera. var projection = new PerspectiveProjection(); projection.SetFieldOfView( ConstantsF.PiOver4, GraphicsService.GraphicsDevice.Viewport.AspectRatio, 0.1f, 10); var cameraNode = new CameraNode(new Camera(projection)); cameraNode.LookAt(new Vector3F(0.15f, 0.15f, 0.5f), new Vector3F(0.1f, 0.15f, 0), Vector3F.Up); _graphicsScreen.Scene.Children.Add(cameraNode); _graphicsScreen.ActiveCameraNode = cameraNode; // Lighting setup: var keyLight = new LightNode(new Spotlight { DiffuseIntensity = 0.6f, SpecularIntensity = 0.4f }); keyLight.LookAt(new Vector3F(-2, 2, 2), new Vector3F(), Vector3F.Up); _graphicsScreen.Scene.Children.Add(keyLight); var backLight = new LightNode(new Spotlight { DiffuseIntensity = 0.3f, SpecularIntensity = 0.3f }); backLight.LookAt(new Vector3F(1, 0.5f, -2), new Vector3F(), Vector3F.Up); _graphicsScreen.Scene.Children.Add(backLight); var fillLight = new LightNode(new AmbientLight { HemisphericAttenuation = 1, Intensity = 0.1f }); _graphicsScreen.Scene.Children.Add(fillLight); // The scene does not have a proper background. That's why the exposure is a // bit off. --> Reduce the max exposure. var hdrFilter = _graphicsScreen.PostProcessors.OfType<HdrFilter>().First(); hdrFilter.MaxExposure = 6; // Load the customized "Sintel" model (original: Durian Open Movie Project - http://www.sintel.org/). var model = ContentManager.Load<ModelNode>("Sintel/Sintel-Head").Clone(); model.PoseWorld = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(MathHelper.ToRadians(10)) * Matrix33F.CreateRotationX(-MathHelper.ToRadians(90))); _graphicsScreen.Scene.Children.Add(model); // The model consists of a root node and a mesh node. // ModelNode "Sintel-Head" // MeshNode "Sintel" _sintel = (MeshNode)model.Children[0]; // The model contains two skeletal animations: // - "MOUTH-open" is just a single frame. // - "Test" is a short animation (250 frames). // In the Options window, we will add a slider to move the jaw. // Slider.Value = 0 ... mouth closed (default) _mouthClosedPose = SkeletonPose.Create(_sintel.Mesh.Skeleton); // Slider.Value = 1 ... mouth open (copied from the "MOUTH-open" animation) SkeletonKeyFrameAnimation mouthOpen = _sintel.Mesh.Animations["MOUTH-open"]; _mouthOpenPose = SkeletonPose.Create(_sintel.Mesh.Skeleton); mouthOpen.GetValue(TimeSpan.Zero, ref _mouthOpenPose, ref _mouthOpenPose, ref _mouthOpenPose); // Turn the "Test" animation into an endless loop. _skeletalAnimation = new AnimationClip<SkeletonPose>(_sintel.Mesh.Animations["Test"]) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle }; // Mesh has several morph targets for facial animation, which are imported // automatically via the content pipeline. Unfortunately, the XNA content // pipeline cannot import morph target animations automatically. // In this demo, we will create a morph target animation in code. _morphingAnimation = CreateMorphingAnimation(); CreateGuiControls(); }