internal Scene3D( Game game, InputMessageBuffer inputMessageBuffer, Func <Viewport> getViewport, ICameraController cameraController, WorldLighting lighting, int randomSeed, bool isDiagnosticScene = false) : this(game, getViewport, inputMessageBuffer, randomSeed, isDiagnosticScene, null, null) { TeamFactory = new TeamFactory(); WaterAreas = AddDisposable(new WaterAreaCollection()); Lighting = lighting; Roads = AddDisposable(new RoadCollection()); Bridges = Array.Empty <Bridge>(); Waypoints = new WaypointCollection(); Cameras = new CameraCollection(); CameraController = cameraController; }
public ObjectDefinitionView(AssetViewContext context, ObjectDefinition objectDefinition) : base(context) { var gameObjects = new GameObjectCollection(context.Game.ContentManager); _gameObject = gameObjects.Add(objectDefinition); _modelConditionStates = _gameObject.ModelConditionStates.ToList(); _selectedIndex = 0; context.Game.Scene3D = new Scene3D( context.Game, new ArcballCameraController(Vector3.Zero, 200), null, null, null, gameObjects, new WaypointCollection(), new WaypointPathCollection(), WorldLighting.CreateDefault(), Array.Empty <Player>(), Array.Empty <Team>()); }
public void TestShortPropegation() { var repository = new BlockRepository(); repository.RegisterBlockProvider(new GrassBlock()); repository.RegisterBlockProvider(new DirtBlock()); repository.RegisterBlockProvider(new AirBlock()); repository.RegisterBlockProvider(new BedrockBlock()); var world = new TrueCraft.Core.World.World("TEST", new FlatlandGenerator()); world.BlockRepository = repository; var lighter = new WorldLighting(world, repository); world.GetBlockID(Coordinates3D.Zero); // Generate a chunk lighter.InitialLighting(world.GetChunk(Coordinates2D.Zero)); world.SetBlockID(new Coordinates3D(5, 3, 5), 0); // Create area that looks like so: world.SetBlockID(new Coordinates3D(5, 2, 5), 0); // x x Light goes like so: | world.SetBlockID(new Coordinates3D(5, 1, 5), 0); // x x | world.SetBlockID(new Coordinates3D(4, 1, 5), 0); // x -/ lighter.EnqueueOperation(new BoundingBox(new Vector3(5, 2, 5), new Vector3(6, 4, 6)), true); while (lighter.TryLightNext()) // Test lighting { } Console.WriteLine("Testing {0}", new Coordinates3D(5, 3, 5)); Assert.AreEqual(15, world.GetSkyLight(new Coordinates3D(5, 3, 5))); Console.WriteLine("Testing {0}", new Coordinates3D(5, 2, 5)); Assert.AreEqual(15, world.GetSkyLight(new Coordinates3D(5, 2, 5))); Console.WriteLine("Testing {0}", new Coordinates3D(5, 1, 5)); Assert.AreEqual(15, world.GetSkyLight(new Coordinates3D(5, 1, 5))); Console.WriteLine("Testing {0}", new Coordinates3D(4, 1, 5)); Assert.AreEqual(14, world.GetSkyLight(new Coordinates3D(4, 1, 5))); }
public ParticleSystemView(Func <IntPtr, Game> createGame, ParticleSystemDefinition particleSystemDefinition) { CreateGame = h => { var game = createGame(h); var particleSystem = new ParticleSystem( game.ContentManager, particleSystemDefinition, () => ref WorldIdentity); game.Updating += (sender, e) => { particleSystem.Update(e.GameTime); }; game.BuildingRenderList += (sender, e) => { particleSystem.BuildRenderList(e.RenderList, Matrix4x4.Identity); }; game.Scene3D = new Scene3D( game, new ArcballCameraController(Vector3.Zero, 200), null, null, null, new GameObjectCollection(game.ContentManager), new WaypointCollection(), new WaypointPathCollection(), WorldLighting.CreateDefault(), Array.Empty <Player>(), Array.Empty <Team>()); return(game); }; }
void Game_Client_BlockChanged(object sender, BlockChangeEventArgs e) { WorldLighting.EnqueueOperation(new TrueCraft.API.BoundingBox( e.Position, e.Position + Coordinates3D.One), false); WorldLighting.EnqueueOperation(new TrueCraft.API.BoundingBox( e.Position, e.Position + Coordinates3D.One), true); var posA = e.Position; posA.Y = 0; var posB = e.Position; posB.Y = World.Height; posB.X++; posB.Z++; WorldLighting.EnqueueOperation(new TrueCraft.API.BoundingBox(posA, posB), true); WorldLighting.EnqueueOperation(new TrueCraft.API.BoundingBox(posA, posB), false); for (int i = 0; i < 100; i++) { if (!WorldLighting.TryLightNext()) { break; } } }
protected override Scene3D LoadEntry(FileSystemEntry entry, ContentManager contentManager, Game game, LoadOptions loadOptions) { switch (contentManager.SageGame) { case SageGame.Ra3: case SageGame.Ra3Uprising: case SageGame.Cnc4: // TODO break; default: contentManager.IniDataContext.LoadIniFile(@"Data\INI\Terrain.ini"); break; } var mapFile = MapFile.FromFileSystemEntry(entry); var heightMap = new HeightMap(mapFile.HeightMapData); var indexBufferCache = AddDisposable(new TerrainPatchIndexBufferCache(contentManager.GraphicsDevice)); var tileDataTexture = AddDisposable(CreateTileDataTexture( contentManager.GraphicsDevice, mapFile, heightMap)); var cliffDetailsBuffer = AddDisposable(CreateCliffDetails( contentManager.GraphicsDevice, mapFile)); CreateTextures( contentManager, mapFile.BlendTileData, out var textureArray, out var textureDetails); var textureDetailsBuffer = AddDisposable(contentManager.GraphicsDevice.CreateStaticStructuredBuffer(textureDetails)); var terrainMaterial = AddDisposable(new TerrainMaterial(contentManager, contentManager.EffectLibrary.Terrain)); terrainMaterial.SetTileData(tileDataTexture); terrainMaterial.SetCliffDetails(cliffDetailsBuffer); terrainMaterial.SetTextureDetails(textureDetailsBuffer); terrainMaterial.SetTextureArray(textureArray); var terrainPatches = CreatePatches( contentManager.GraphicsDevice, heightMap, mapFile.BlendTileData, terrainMaterial, indexBufferCache); var cloudTextureName = mapFile.EnvironmentData?.CloudTexture ?? "tscloudmed.dds"; var cloudTexture = contentManager.Load <Texture>(Path.Combine("Art", "Textures", cloudTextureName)); var macroTextureName = mapFile.EnvironmentData?.MacroTexture ?? "tsnoiseurb.dds"; var macroTexture = contentManager.Load <Texture>(Path.Combine("Art", "Textures", macroTextureName)); var materialConstantsBuffer = AddDisposable(contentManager.GraphicsDevice.CreateStaticBuffer( new TerrainMaterial.TerrainMaterialConstants { MapBorderWidth = new Vector2(mapFile.HeightMapData.BorderWidth, mapFile.HeightMapData.BorderWidth) * HeightMap.HorizontalScale, MapSize = new Vector2(mapFile.HeightMapData.Width, mapFile.HeightMapData.Height) * HeightMap.HorizontalScale, IsMacroTextureStretched = false // TODO: This must be one of the EnvironmentData unknown values. }, BufferUsage.UniformBuffer)); terrainMaterial.SetMaterialConstants(materialConstantsBuffer); var terrain = new Terrain.Terrain( heightMap, terrainPatches, cloudTexture, macroTexture, contentManager.SolidWhiteTexture); var players = Player.FromMapData(mapFile.SidesList.Players, contentManager).ToArray(); var teams = (mapFile.SidesList.Teams ?? mapFile.Teams.Items) .Select(team => Team.FromMapData(team, players)) .ToArray(); LoadObjects( contentManager, heightMap, mapFile.ObjectsList.Objects, teams, out var waypoints, out var gameObjects); var lighting = new WorldLighting( mapFile.GlobalLighting.LightingConfigurations.ToLightSettingsDictionary(), mapFile.GlobalLighting.Time); var waypointPaths = new WaypointPathCollection(mapFile.WaypointsList.WaypointPaths .Select(path => { var start = waypoints[path.StartWaypointID]; var end = waypoints[path.EndWaypointID]; return(new Settings.WaypointPath(start, end)); })); // TODO: Don't hardcode this. // Perhaps add one ScriptComponent for the neutral player, // and one for the active player. var scriptList = mapFile.GetPlayerScriptsList().ScriptLists[0]; var mapScripts = CreateScripts(scriptList); var cameraController = new RtsCameraController(contentManager) { TerrainPosition = terrain.HeightMap.GetPosition( terrain.HeightMap.Width / 2, terrain.HeightMap.Height / 2) }; contentManager.GraphicsDevice.WaitForIdle(); return(new Scene3D( game, cameraController, mapFile, terrain, mapScripts, gameObjects, waypoints, waypointPaths, lighting, players, teams)); }
public void TestLeavesAndEtc() { var repository = new BlockRepository(); repository.RegisterBlockProvider(new GrassBlock()); repository.RegisterBlockProvider(new DirtBlock()); repository.RegisterBlockProvider(new AirBlock()); repository.RegisterBlockProvider(new BedrockBlock()); repository.RegisterBlockProvider(new LeavesBlock()); var world = new TrueCraft.Core.World.World("TEST", new FlatlandGenerator()); world.BlockRepository = repository; var lighter = new WorldLighting(world, repository); world.GetBlockID(Coordinates3D.Zero); // Generate a chunk for (int y = 1; y <= 16; y++) { var coords = new Coordinates3D(5, y, 5); world.SetBlockID(coords, 0); world.SetBlockID(coords + Coordinates3D.East, DirtBlock.BlockID); world.SetBlockID(coords + Coordinates3D.West, DirtBlock.BlockID); world.SetBlockID(coords + Coordinates3D.North, DirtBlock.BlockID); world.SetBlockID(coords + Coordinates3D.South, DirtBlock.BlockID); } world.GetChunk(Coordinates2D.Zero).UpdateHeightMap(); lighter.InitialLighting(world.GetChunk(Coordinates2D.Zero)); // Test this layout: // xox o == leaves // x x // xox // x x // xox ... for (int y = 1; y <= 16; y++) { if (y % 2 == 1) { world.SetBlockID(new Coordinates3D(5, y, 5), LeavesBlock.BlockID); } } world.GetChunk(Coordinates2D.Zero).UpdateHeightMap(); lighter.EnqueueOperation(new BoundingBox(new Vector3(5, 0, 5), new Vector3(6, 16, 6)), true); while (lighter.TryLightNext()) // Test lighting { } // Output lighting for (int y = 16; y >= 0; y--) { Console.Write(world.GetBlockID(new Coordinates3D(5, y, 5)).ToString("D2")); Console.Write(" " + world.GetSkyLight(new Coordinates3D(5, y, 5)).ToString("D2")); Console.WriteLine(" Y={0}", y); } var expected = new byte[] { 15, // air 13, // leaves 12, // air 10, // leaves 9, // air 7, // leaves 6, // air 4, // leaves 3, // air 1, // leaves 0, // air 0, // leaves }; for (int y = 16, i = 0; y >= 0; y--, i++) { byte ex; if (i < expected.Length) { ex = expected[i]; } else { ex = 0; } Assert.AreEqual(ex, world.GetSkyLight(new Coordinates3D(5, y, 5))); } }
public void TestFarPropegationx2() { var repository = new BlockRepository(); repository.RegisterBlockProvider(new GrassBlock()); repository.RegisterBlockProvider(new DirtBlock()); repository.RegisterBlockProvider(new AirBlock()); repository.RegisterBlockProvider(new BedrockBlock()); var world = new TrueCraft.Core.World.World("TEST", new FlatlandGenerator()); world.BlockRepository = repository; var lighter = new WorldLighting(world, repository); world.GetBlockID(Coordinates3D.Zero); // Generate a chunk lighter.InitialLighting(world.GetChunk(Coordinates2D.Zero)); // Test this layout: // xxx x y=3 // x x y=2 // x x y=1 // xxxxx y=0 // // ^ x,z = 5 for (int y = 1; y <= 3; y++) // Dig hole { world.SetBlockID(new Coordinates3D(5, y, 5), 0); } for (int x = 0; x <= 4; x++) // Dig outwards { world.SetBlockID(new Coordinates3D(x, 2, 5), 0); // Dig a tunnel world.SetBlockID(new Coordinates3D(x, 1, 5), 0); // Dig a tunnel } var watch = new Stopwatch(); watch.Start(); lighter.EnqueueOperation(new BoundingBox(new Vector3(5, 2, 5), new Vector3(6, 4, 6)), true); while (lighter.TryLightNext()) // Test lighting { } watch.Stop(); // Output lighting for (int y = 3; y >= 0; y--) { for (int x = 0; x <= 5; x++) { Console.Write(world.GetBlockID(new Coordinates3D(x, y, 5)).ToString("D2") + " "); } Console.WriteLine(); } Console.WriteLine(); for (int y = 3; y >= 0; y--) { for (int x = 0; x <= 5; x++) { Console.Write(world.GetSkyLight(new Coordinates3D(x, y, 5)).ToString("D2") + " "); } Console.WriteLine(); } Console.WriteLine("Testing {0}", new Coordinates3D(5, 3, 5)); Assert.AreEqual(15, world.GetSkyLight(new Coordinates3D(5, 3, 5))); Console.WriteLine("Testing {0}", new Coordinates3D(5, 2, 5)); Assert.AreEqual(15, world.GetSkyLight(new Coordinates3D(5, 2, 5))); Console.WriteLine("Testing {0}", new Coordinates3D(5, 1, 5)); Assert.AreEqual(15, world.GetSkyLight(new Coordinates3D(5, 1, 5))); byte expected = 15; for (int x = 5; x >= 0; x--) { Console.WriteLine("Testing {0}", new Coordinates3D(x, 2, 5)); Assert.AreEqual(expected, world.GetSkyLight(new Coordinates3D(x, 2, 5))); expected--; } expected = 15; for (int x = 5; x >= 0; x--) { Console.WriteLine("Testing {0}", new Coordinates3D(x, 1, 5)); Assert.AreEqual(expected, world.GetSkyLight(new Coordinates3D(x, 1, 5))); expected--; } Console.WriteLine("{0}ms", watch.ElapsedMilliseconds); }
public W3dView(AssetViewContext context) : base(context) { var game = context.Game; var modelInstance = game.ContentManager .Load <Model>(context.Entry.FilePath) .CreateInstance(game.GraphicsDevice); void onUpdating(object sender, GameUpdatingEventArgs e) => modelInstance.Update(e.GameTime); game.Updating += onUpdating; AddDisposeAction(() => game.Updating -= onUpdating); void onBuildingRenderList(object sender, BuildingRenderListEventArgs e) { modelInstance.SetWorldMatrix(Matrix4x4.Identity); modelInstance.BuildRenderList(e.RenderList, e.Camera); } game.BuildingRenderList += onBuildingRenderList; AddDisposeAction(() => game.BuildingRenderList -= onBuildingRenderList); var enclosingBoundingBox = GetEnclosingBoundingBox(modelInstance); var cameraController = new ArcballCameraController( enclosingBoundingBox.GetCenter(), Vector3.Distance(enclosingBoundingBox.Min, enclosingBoundingBox.Max)); game.Scene3D = new Scene3D( game, cameraController, null, null, Array.Empty <Terrain.Road>(), null, new GameObjectCollection(game.ContentManager), new WaypointCollection(), new WaypointPathCollection(), WorldLighting.CreateDefault(), Array.Empty <Player>(), Array.Empty <Team>()); var animations = new List <AnimationInstance>(modelInstance.AnimationInstances); var w3dFile = W3dFile.FromFileSystemEntry(context.Entry); // If this is a skin file, load "external" animations. var externalAnimations = new List <AnimationInstance>(); if (w3dFile.HLod != null && w3dFile.HLod.Header.Name.EndsWith("_SKN", StringComparison.OrdinalIgnoreCase)) { var namePrefix = w3dFile.HLod.Header.Name.Substring(0, w3dFile.HLod.Header.Name.LastIndexOf('_') + 1); var parentFolder = Path.GetDirectoryName(w3dFile.FilePath); var pathPrefix = Path.Combine(parentFolder, namePrefix); foreach (var animationFileEntry in context.Entry.FileSystem.GetFiles(parentFolder)) { if (!animationFileEntry.FilePath.StartsWith(pathPrefix, StringComparison.OrdinalIgnoreCase)) { continue; } var animationModel = game.ContentManager.Load <Model>(animationFileEntry.FilePath); foreach (var animation in animationModel.Animations) { var externalAnimationInstance = new AnimationInstance(modelInstance, animation); modelInstance.AnimationInstances.Add(externalAnimationInstance); externalAnimations.Add(externalAnimationInstance); } } } _subObjects = new List <W3dItem>(); _subObjects.Add(new W3dModelItem()); foreach (var animation in animations) { _subObjects.Add(new W3dAnimationItem(animation, "Animation")); } foreach (var animation in externalAnimations) { _subObjects.Add(new W3dAnimationItem(animation, "External Animation")); } ActivateItem(_subObjects[0]); }
protected override Scene3D LoadEntry(FileSystemEntry entry, ContentManager contentManager, Game game, LoadOptions loadOptions) { switch (contentManager.SageGame) { case SageGame.Ra3: case SageGame.Ra3Uprising: case SageGame.Cnc4: // TODO break; default: contentManager.IniDataContext.LoadIniFile(@"Data\INI\Terrain.ini"); contentManager.IniDataContext.LoadIniFile(@"Data\INI\Roads.ini"); break; } var mapFile = MapFile.FromFileSystemEntry(entry); var heightMap = new HeightMap(mapFile.HeightMapData); var indexBufferCache = AddDisposable(new TerrainPatchIndexBufferCache(contentManager.GraphicsDevice)); var tileDataTexture = AddDisposable(CreateTileDataTexture( contentManager.GraphicsDevice, mapFile, heightMap)); var cliffDetailsBuffer = AddDisposable(CreateCliffDetails( contentManager.GraphicsDevice, mapFile)); CreateTextures( contentManager, mapFile.BlendTileData, out var textureArray, out var textureDetails); var textureDetailsBuffer = AddDisposable(contentManager.GraphicsDevice.CreateStaticStructuredBuffer(textureDetails)); var terrainPipeline = contentManager.ShaderResources.Terrain.Pipeline; Texture LoadTexture(string name) { var texture = contentManager.Load <Texture>(Path.Combine("Art", "Textures", name), fallbackToPlaceholder: false); if (texture == null) { texture = contentManager.Load <Texture>(Path.Combine("Art", "CompiledTextures", name.Substring(0, 2), name)); } return(texture); } var materialConstantsBuffer = AddDisposable(contentManager.GraphicsDevice.CreateStaticBuffer( new TerrainShaderResources.TerrainMaterialConstants { MapBorderWidth = new Vector2(mapFile.HeightMapData.BorderWidth, mapFile.HeightMapData.BorderWidth) * HeightMap.HorizontalScale, MapSize = new Vector2(mapFile.HeightMapData.Width, mapFile.HeightMapData.Height) * HeightMap.HorizontalScale, IsMacroTextureStretched = false // TODO: This must be one of the EnvironmentData unknown values. }, BufferUsage.UniformBuffer)); var macroTexture = LoadTexture(mapFile.EnvironmentData?.MacroTexture ?? "tsnoiseurb.dds"); var materialResourceSet = AddDisposable(contentManager.ShaderResources.Terrain.CreateMaterialResourceSet( materialConstantsBuffer, tileDataTexture, cliffDetailsBuffer ?? contentManager.GetNullStructuredBuffer(TerrainShaderResources.CliffInfo.Size), textureDetailsBuffer, textureArray, macroTexture)); var terrainPatches = CreatePatches( contentManager.GraphicsDevice, heightMap, mapFile.BlendTileData, indexBufferCache, materialResourceSet); var cloudTexture = LoadTexture(mapFile.EnvironmentData?.CloudTexture ?? "tscloudmed.dds"); cloudTexture.Name = "Cloud texture"; var cloudResourceLayout = AddDisposable(contentManager.GraphicsDevice.ResourceFactory.CreateResourceLayout( new ResourceLayoutDescription( new ResourceLayoutElementDescription("Global_CloudTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment)))); var cloudResourceSet = AddDisposable(contentManager.GraphicsDevice.ResourceFactory.CreateResourceSet( new ResourceSetDescription( cloudResourceLayout, cloudTexture))); cloudResourceSet.Name = "Cloud resource set"; var terrain = new Terrain.Terrain( heightMap, terrainPatches, contentManager.ShaderResources.Terrain.ShaderSet, terrainPipeline, cloudResourceSet); var players = Player.FromMapData(mapFile.SidesList.Players, contentManager).ToArray(); var teams = (mapFile.SidesList.Teams ?? mapFile.Teams.Items) .Select(team => Team.FromMapData(team, players)) .ToArray(); LoadObjects( contentManager, heightMap, mapFile.ObjectsList.Objects, teams, out var waypoints, out var gameObjects, out var roads, out var bridges); var waterAreas = new List <WaterArea>(); if (mapFile.PolygonTriggers != null) { foreach (var polygonTrigger in mapFile.PolygonTriggers.Triggers) { switch (polygonTrigger.TriggerType) { case PolygonTriggerType.Water: case PolygonTriggerType.River: // TODO: Handle this differently. Water texture should be animated "downstream". case PolygonTriggerType.WaterAndRiver: if (WaterArea.TryCreate(contentManager, polygonTrigger, out var waterArea)) { waterAreas.Add(AddDisposable(waterArea)); } break; } } } var lighting = new WorldLighting( mapFile.GlobalLighting.LightingConfigurations.ToLightSettingsDictionary(), mapFile.GlobalLighting.Time); var waypointPaths = new WaypointPathCollection(mapFile.WaypointsList.WaypointPaths .Select(path => { var start = waypoints[path.StartWaypointID]; var end = waypoints[path.EndWaypointID]; return(new Settings.WaypointPath(start, end)); })); // TODO: Don't hardcode this. // Perhaps add one ScriptComponent for the neutral player, // and one for the active player. var scriptList = mapFile.GetPlayerScriptsList().ScriptLists[0]; var mapScripts = CreateScripts(scriptList); var cameraController = new RtsCameraController(contentManager) { TerrainPosition = terrain.HeightMap.GetPosition( terrain.HeightMap.Width / 2, terrain.HeightMap.Height / 2) }; contentManager.GraphicsDevice.WaitForIdle(); return(new Scene3D( game, game.InputMessageBuffer, () => game.Viewport, cameraController, mapFile, terrain, waterAreas.ToArray(), roads, bridges, mapScripts, gameObjects, waypoints, waypointPaths, lighting, players, teams)); }
public W3dView(FileSystemEntry entry, Func <IntPtr, Game> createGame) { _listBox = new ListBox { Width = 250, ItemTextBinding = Binding.Property((W3dItem v) => v.Name) }; _listBox.SelectedValueChanged += OnSelectedValueChanged; Panel1 = _listBox; _listBox.SelectedIndex = 0; Panel2 = new GameControl { CreateGame = h => { var game = createGame(h); var modelInstance = game.ContentManager .Load <Model>(entry.FilePath) .CreateInstance(game.GraphicsDevice); game.Updating += (sender, e) => { modelInstance.Update(e.GameTime); }; game.BuildingRenderList += (sender, e) => { modelInstance.SetWorldMatrix(Matrix4x4.Identity); modelInstance.BuildRenderList(e.RenderList, e.Camera); }; var enclosingBoundingBox = GetEnclosingBoundingBox(modelInstance); var cameraController = new ArcballCameraController( enclosingBoundingBox.GetCenter(), Vector3.Distance(enclosingBoundingBox.Min, enclosingBoundingBox.Max)); game.Scene3D = new Scene3D( game, cameraController, null, null, null, new GameObjectCollection(game.ContentManager), new WaypointCollection(), new WaypointPathCollection(), WorldLighting.CreateDefault()); var animations = new List <AnimationInstance>(modelInstance.AnimationInstances); var w3dFile = W3dFile.FromFileSystemEntry(entry); // If this is a skin file, load "external" animations. var externalAnimations = new List <AnimationInstance>(); if (w3dFile.HLod != null && w3dFile.HLod.Header.Name.EndsWith("_SKN", StringComparison.OrdinalIgnoreCase)) { var namePrefix = w3dFile.HLod.Header.Name.Substring(0, w3dFile.HLod.Header.Name.LastIndexOf('_') + 1); var parentFolder = Path.GetDirectoryName(w3dFile.FilePath); var pathPrefix = Path.Combine(parentFolder, namePrefix); foreach (var animationFileEntry in entry.FileSystem.GetFiles(parentFolder)) { if (!animationFileEntry.FilePath.StartsWith(pathPrefix, StringComparison.OrdinalIgnoreCase)) { continue; } var animationModel = game.ContentManager.Load <Model>(animationFileEntry.FilePath); foreach (var animation in animationModel.Animations) { var externalAnimationInstance = new AnimationInstance(modelInstance, animation); modelInstance.AnimationInstances.Add(externalAnimationInstance); externalAnimations.Add(externalAnimationInstance); } } } var subObjects = new List <W3dItem>(); subObjects.Add(new W3dModelItem()); foreach (var animation in animations) { subObjects.Add(new W3dAnimationItem(animation, "Animation")); } foreach (var animation in externalAnimations) { subObjects.Add(new W3dAnimationItem(animation, "External Animation")); } _listBox.DataStore = subObjects; return(game); } }; }