Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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]);
        }