private W3dModelDrawConditionState CreateModelDrawConditionStateInstance(ModelConditionState conditionState) { ModelInstance modelInstance = null; if (!string.Equals(conditionState.Model, "NONE", StringComparison.OrdinalIgnoreCase)) { var w3dFilePath = Path.Combine("Art", "W3D", conditionState.Model + ".W3D"); var model = _contentManager.Load <Model>(w3dFilePath); if (model != null) { modelInstance = model.CreateInstance(_contentManager.GraphicsDevice); } } if (modelInstance != null) { // TODO: Multiple animations. Shouldn't play all of them. I think // we should randomly choose one of them? // And there is also IdleAnimation. var firstAnimation = conditionState.ConditionAnimations .Concat(conditionState.IdleAnimations) .LastOrDefault(); if (firstAnimation != null) { if (!_contentManager.DataContext.Animations.TryGetValue(firstAnimation.Animation, out var animation)) { var splitName = firstAnimation.Animation.Split('.'); var w3dFilePath = Path.Combine("Art", "W3D", splitName[1] + ".W3D"); var w3dEntry = _contentManager.FileSystem.GetFile(w3dFilePath); var w3dFile = W3dFile.FromFileSystemEntry(w3dEntry); var animations = ModelLoader.LoadAnimations(w3dFile, _contentManager); if (animations.Length != 1 || !string.Equals(animations[0].Name, firstAnimation.Animation, StringComparison.OrdinalIgnoreCase)) { throw new NotSupportedException(); } animation = animations[0]; } var animationInstance = new AnimationInstance(modelInstance, animation); modelInstance.AnimationInstances.Add(animationInstance); animationInstance.Play(); } } var particleSystems = new List <ParticleSystem>(); if (modelInstance != null) { foreach (var particleSysBone in conditionState.ParticleSysBones) { var particleSystemDefinition = _contentManager.IniDataContext.ParticleSystems.First(x => x.Name == particleSysBone.ParticleSystem); var bone = modelInstance.Model.BoneHierarchy.Bones.FirstOrDefault(x => string.Equals(x.Name, particleSysBone.BoneName, StringComparison.OrdinalIgnoreCase)); if (bone == null) { // TODO: Should this ever happen? continue; } particleSystems.Add(new ParticleSystem( _contentManager, particleSystemDefinition, () => ref modelInstance.AbsoluteBoneTransforms[bone.Index])); } } return(modelInstance != null ? new W3dModelDrawConditionState(modelInstance, particleSystems) : null); }
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, true, game.CivilianPlayer); } 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.WaterArea>(), Array.Empty <Terrain.Road>(), Array.Empty <Terrain.Bridge>(), 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); var w3dHLod = w3dFile.GetHLod(); // If this is a skin file, load "external" animations. var externalAnimations = new List <AnimationInstance>(); if (w3dHLod != null && w3dHLod.Header.Name.EndsWith("_SKN", StringComparison.OrdinalIgnoreCase)) { var namePrefix = w3dHLod.Header.Name.Substring(0, w3dHLod.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 w3dAnimationFile = W3dFile.FromFileSystemEntry(animationFileEntry); var w3dAnimations = ModelLoader.LoadAnimations(w3dAnimationFile, game.ContentManager); foreach (var w3dAnimation in w3dAnimations) { var externalAnimationInstance = new AnimationInstance(modelInstance, w3dAnimation); 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]); }