예제 #1
0
 private bool ShouldWaitForRunningAnimationsToFinish(ModelConditionState conditionState)
 {
     return(_activeConditionState != null &&
            conditionState.WaitForStateToFinishIfPossible != null &&
            _activeConditionState.TransitionKey == conditionState.WaitForStateToFinishIfPossible &&
            (_activeModelDrawConditionState?.StillActive() ?? false));
 }
예제 #2
0
        internal W3dModelDraw(
            W3dModelDrawModuleData data,
            Drawable drawable,
            GameContext context)
        {
            _data    = data;
            Drawable = drawable;
            _context = context;

            _conditionStates = new List <IConditionState>();

            if (data.DefaultConditionState != null)
            {
                _defaultConditionState = data.DefaultConditionState;
            }

            foreach (var conditionState in data.ConditionStates)
            {
                _conditionStates.Add(conditionState);
            }

            if (_defaultConditionState == null)
            {
                _defaultConditionState = (ModelConditionState)_conditionStates.Find(x => !x.ConditionFlags.AnyBitSet);

                if (_defaultConditionState != null)
                {
                    _conditionStates.Remove(_defaultConditionState);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            _cachedModelDrawConditionStates = new Dictionary <ModelConditionState, W3dModelDrawConditionState>();

            SetActiveConditionState(_defaultConditionState, context.Random);

            _animationStates = new List <IConditionState>();

            if (data.IdleAnimationState != null)
            {
                _idleAnimationState = data.IdleAnimationState;
            }

            foreach (var animationState in data.AnimationStates)
            {
                _animationStates.Add(animationState);
            }

            _generalsTransitionStates = data.GeneralsTransitionStates;
            _bfmeTransitionStates     = data.BfmeTransitionStates;

            _unknownSomething = new List <W3dModelDrawSomething> [3];
            for (var i = 0; i < _unknownSomething.Length; i++)
            {
                _unknownSomething[i] = new List <W3dModelDrawSomething>();
            }
        }
예제 #3
0
        private W3dModelDrawConditionState CreateModelDrawConditionStateInstance(ModelConditionState conditionState, Random random)
        {
            // Load model, fallback to default model.
            var model         = conditionState.Model?.Value;
            var modelInstance = model?.CreateInstance(_context.AssetLoadContext) ?? null;

            if (modelInstance == null)
            {
                return(null);
            }

            var particleSystems = new List <ParticleSystem>();

            foreach (var particleSysBone in conditionState.ParticleSysBones)
            {
                var particleSystemTemplate = particleSysBone.ParticleSystem.Value;
                if (particleSystemTemplate == null)
                {
                    throw new InvalidOperationException();
                }

                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(_context.ParticleSystems.Create(
                                        particleSystemTemplate,
                                        () => ref modelInstance.AbsoluteBoneTransforms[bone.Index]));
            }

            return(new W3dModelDrawConditionState(modelInstance, particleSystems, _context));
        }
예제 #4
0
        public W3dModelDraw(W3dModelDrawModuleData data)
        {
            _data = data;

            _conditionStates = new List <ModelConditionState>();

            if (data.DefaultConditionState != null)
            {
                _defaultConditionState = data.DefaultConditionState;
            }

            foreach (var conditionState in data.ConditionStates)
            {
                _conditionStates.Add(conditionState);
            }

            if (_defaultConditionState == null)
            {
                _defaultConditionState = _conditionStates.Find(x => !x.ConditionFlags.AnyBitSet);

                if (_defaultConditionState != null)
                {
                    _conditionStates.Remove(_defaultConditionState);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
예제 #5
0
        internal static ModelConditionState Parse(IniParser parser, ModelConditionState defaultConditionState)
        {
            var conditionFlags = parser.ParseEnumBitArray <ModelConditionFlag>();

            var result = parser.ParseBlock(FieldParseTable, defaultConditionState?.Clone() ?? new ModelConditionState());

            result.ConditionFlags = conditionFlags;

            return(result);
        }
예제 #6
0
        internal W3dModelDraw(
            W3dModelDrawModuleData data,
            GameObject gameObject,
            GameContext context)
        {
            _data      = data;
            GameObject = gameObject;
            _context   = context;

            _conditionStates = new List <IConditionState>();

            if (data.DefaultConditionState != null)
            {
                _defaultConditionState = data.DefaultConditionState;
            }

            foreach (var conditionState in data.ConditionStates)
            {
                _conditionStates.Add(conditionState);
            }

            if (_defaultConditionState == null)
            {
                _defaultConditionState = (ModelConditionState)_conditionStates.Find(x => !x.ConditionFlags.AnyBitSet);

                if (_defaultConditionState != null)
                {
                    _conditionStates.Remove(_defaultConditionState);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            _cachedModelDrawConditionStates = new Dictionary <ModelConditionState, W3dModelDrawConditionState>();

            SetActiveConditionState(_defaultConditionState, context.Random);

            _animationStates = new List <IConditionState>();

            if (data.IdleAnimationState != null)
            {
                _idleAnimationState = data.IdleAnimationState;
            }

            foreach (var animationState in data.AnimationStates)
            {
                _animationStates.Add(animationState);
            }

            _generalsTransitionStates = data.GeneralsTransitionStates;
            _bfmeTransitionStates     = data.BfmeTransitionStates;
        }
예제 #7
0
        private void SetActiveConditionState(ModelConditionState conditionState)
        {
            if (_activeConditionState == conditionState)
            {
                return;
            }

            Entity.Transform.Children.Clear();

            _activeConditionState = conditionState;

            Entity.AddChild(CreateModelDrawConditionStateEntity(conditionState));
        }
예제 #8
0
        internal W3dModelDraw(
            W3dModelDrawModuleData data,
            GameContext context)
        {
            _data    = data;
            _context = context;

            _conditionStates = new List <ModelConditionState>();

            if (data.DefaultConditionState != null)
            {
                _defaultConditionState = data.DefaultConditionState;
            }

            foreach (var conditionState in data.ConditionStates)
            {
                _conditionStates.Add(conditionState);
            }

            if (_defaultConditionState == null)
            {
                _defaultConditionState = _conditionStates.Find(x => !x.ConditionFlags.AnyBitSet);

                if (_defaultConditionState != null)
                {
                    _conditionStates.Remove(_defaultConditionState);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            _cachedModelDrawConditionStates = new Dictionary <ModelConditionState, W3dModelDrawConditionState>();

            SetActiveConditionState(_defaultConditionState);

            _animationStates = new List <AnimationState>();

            if (data.IdleAnimationState != null)
            {
                _idleAnimationState = data.IdleAnimationState;
            }

            foreach (var animationState in data.AnimationStates)
            {
                _animationStates.Add(animationState);
            }
        }
        private void SetActiveConditionState(ModelConditionState conditionState)
        {
            if (_activeConditionState == conditionState)
            {
                return;
            }

            RemoveAndDispose(ref _activeModelDrawConditionState);

            _activeConditionState = conditionState;

            _activeModelDrawConditionState = AddDisposable(
                CreateModelDrawConditionStateInstance(
                    conditionState));
        }
        public override void UpdateConditionState(BitArray <ModelConditionFlag> flags)
        {
            ModelConditionState bestConditionState = null;
            var bestMatch = int.MinValue;

            // Find best matching ModelConditionState.
            foreach (var conditionState in _conditionStates)
            {
                var match = conditionState.ConditionFlags.And(flags).NumBitsSet;
                if (match > bestMatch)
                {
                    bestConditionState = conditionState;
                    bestMatch          = match;
                }
            }

            if (bestConditionState == null || bestMatch == 0)
            {
                bestConditionState = _defaultConditionState;
            }

            SetActiveConditionState(bestConditionState);

            AnimationState bestAnimationState = null;

            bestMatch = int.MinValue;

            // Find best matching ModelConditionState.
            foreach (var animationState in _animationStates)
            {
                var match = animationState.TypeFlags.And(flags).NumBitsSet;
                if (match > bestMatch)
                {
                    bestAnimationState = animationState;
                    bestMatch          = match;
                }
            }

            if (bestAnimationState == null || bestMatch == 0)
            {
                bestAnimationState = _idleAnimationState;
            }

            SetActiveAnimationState(bestAnimationState);
        }
예제 #11
0
        private void SetActiveConditionState(ModelConditionState conditionState, Random random)
        {
            if (_activeConditionState == conditionState || ShouldWaitForRunningAnimationsToFinish())
            {
                return;
            }

            if (_activeModelDrawConditionState != null)
            {
                _activeModelDrawConditionState.Deactivate();
                RemoveAndDispose(ref _activeModelDrawConditionState);
            }

            var modelDrawConditionState = AddDisposable(CreateModelDrawConditionStateInstance(conditionState, random));

            _activeConditionState          = conditionState;
            _activeModelDrawConditionState = modelDrawConditionState;

            NLog.LogManager.GetCurrentClassLogger().Info($"Set active condition state for {GameObject.Definition.Name}");
        }
예제 #12
0
        private void SetActiveConditionState(ModelConditionState conditionState)
        {
            if (_activeConditionState == conditionState)
            {
                return;
            }

            _activeModelDrawConditionState?.Deactivate();

            if (!_cachedModelDrawConditionStates.TryGetValue(conditionState, out var modelDrawConditionState))
            {
                modelDrawConditionState = AddDisposable(CreateModelDrawConditionStateInstance(conditionState));
                _cachedModelDrawConditionStates.Add(conditionState, modelDrawConditionState);
            }

            _activeConditionState          = conditionState;
            _activeModelDrawConditionState = modelDrawConditionState;

            _activeModelDrawConditionState?.Activate();
        }
예제 #13
0
        private void SetActiveConditionState(ModelConditionState conditionState, Random random)
        {
            if (_activeConditionState == conditionState || ShouldWaitForRunningAnimationsToFinish(conditionState))
            {
                return;
            }

            _activeModelDrawConditionState?.Deactivate();

            if (!_cachedModelDrawConditionStates.TryGetValue(conditionState, out var modelDrawConditionState))
            {
                modelDrawConditionState = AddDisposable(CreateModelDrawConditionStateInstance(conditionState, random));
                _cachedModelDrawConditionStates.Add(conditionState, modelDrawConditionState);
            }

            _activeConditionState          = conditionState;
            _activeModelDrawConditionState = modelDrawConditionState;

            var speedFactor = conditionState.AnimationSpeedFactorRange.GetValue(random);

            _activeModelDrawConditionState?.Activate(speedFactor);
        }
예제 #14
0
        public override void UpdateConditionState(BitArray <ModelConditionFlag> flags)
        {
            ModelConditionState bestConditionState = null;
            var bestMatch = int.MinValue;

            // Find best matching ModelConditionState.
            foreach (var conditionState in _conditionStates)
            {
                var numStateBits        = conditionState.ConditionFlags.NumBitsSet;
                var numIntersectionBits = conditionState.ConditionFlags.CountIntersectionBits(flags);

                // If there's no intersection never select this.
                if (numIntersectionBits == 0)
                {
                    continue;
                }

                if (numIntersectionBits > bestMatch)
                {
                    bestConditionState = conditionState;
                    bestMatch          = numIntersectionBits;
                }
            }

            if (bestConditionState == null || bestMatch == 0)
            {
                bestConditionState = _defaultConditionState;
            }

            SetActiveConditionState(bestConditionState);

            foreach (var weaponMuzzleFlash in bestConditionState.WeaponMuzzleFlashes)
            {
                var visible = flags.Get(ModelConditionFlag.FiringA);
                for (var i = 0; i < _activeModelDrawConditionState.Model.ModelBoneInstances.Length; i++)
                {
                    var bone = _activeModelDrawConditionState.Model.ModelBoneInstances[i];
                    // StartsWith is a bit awkward here, but for instance AVCommance has WeaponMuzzleFlashes = { TurretFX }, and Bones = { TURRETFX01 }
                    if (bone.Name.StartsWith(weaponMuzzleFlash.BoneName.ToUpper()))
                    {
                        _activeModelDrawConditionState.Model.BoneVisibilities[i] = visible;
                    }
                }
            }
            ;

            AnimationState bestAnimationState = null;

            bestMatch = int.MinValue;

            // Find best matching ModelConditionState.
            foreach (var animationState in _animationStates)
            {
                var numStateBits        = animationState.TypeFlags.NumBitsSet;
                var numIntersectionBits = animationState.TypeFlags.CountIntersectionBits(flags);

                // If there's no intersection never select this.
                if (numIntersectionBits != numStateBits)
                {
                    continue;
                }

                if (numIntersectionBits > bestMatch)
                {
                    bestAnimationState = animationState;
                    bestMatch          = numIntersectionBits;
                }
            }

            if (bestAnimationState == null || bestMatch == 0)
            {
                bestAnimationState = _idleAnimationState;
            }

            SetActiveAnimationState(bestAnimationState);
        }
예제 #15
0
        public override void UpdateConditionState(BitArray <ModelConditionFlag> flags)
        {
            ModelConditionState bestConditionState = null;
            var bestMatch = int.MinValue;

            // Find best matching ModelConditionState.
            foreach (var conditionState in _conditionStates)
            {
                var numStateBits        = conditionState.ConditionFlags.NumBitsSet;
                var numIntersectionBits = conditionState.ConditionFlags.CountIntersectionBits(flags);

                // If there's no intersection never select this.
                if (numIntersectionBits != numStateBits)
                {
                    continue;
                }

                if (numIntersectionBits > bestMatch)
                {
                    bestConditionState = conditionState;
                    bestMatch          = numIntersectionBits;
                }
            }

            if (bestConditionState == null || bestMatch == 0)
            {
                bestConditionState = _defaultConditionState;
            }

            SetActiveConditionState(bestConditionState);

            AnimationState bestAnimationState = null;

            bestMatch = int.MinValue;

            // Find best matching ModelConditionState.
            foreach (var animationState in _animationStates)
            {
                var numStateBits        = animationState.TypeFlags.NumBitsSet;
                var numIntersectionBits = animationState.TypeFlags.CountIntersectionBits(flags);

                // If there's no intersection never select this.
                if (numIntersectionBits != numStateBits)
                {
                    continue;
                }

                if (numIntersectionBits > bestMatch)
                {
                    bestAnimationState = animationState;
                    bestMatch          = numIntersectionBits;
                }
            }

            if (bestAnimationState == null || bestMatch == 0)
            {
                bestAnimationState = _idleAnimationState;
            }

            SetActiveAnimationState(bestAnimationState);
        }
예제 #16
0
        private W3dModelDrawConditionState CreateModelDrawConditionStateInstance(ModelConditionState conditionState, Random random)
        {
            // Load model, fallback to default model.
            var model         = conditionState.Model?.Value ?? _defaultConditionState.Model?.Value;
            var modelInstance = model?.CreateInstance(_context.AssetLoadContext) ?? null;

            if (modelInstance == null)
            {
                return(null);
            }

            // TODO: since the ModelDrawConditionStates are cached we should find a way to change the animation afterwards
            var animations = conditionState.ConditionAnimations;

            if (!conditionState.ConditionFlags.Get(ModelConditionFlag.Moving))
            {
                animations.AddRange(conditionState.IdleAnimations);
            }

            if (animations.Count > 0)
            {
                var animation = animations[random.Next(0, animations.Count - 1)]?.Animation.Value;
                if (animation != null)
                {
                    var mode              = conditionState.AnimationMode;
                    var flags             = conditionState.Flags;
                    var animationInstance = new AnimationInstance(modelInstance, animation, mode, flags, GameObject);
                    modelInstance.AnimationInstances.Add(animationInstance);
                }
            }

            var particleSystems = new List <ParticleSystem>();

            foreach (var particleSysBone in conditionState.ParticleSysBones)
            {
                var particleSystemTemplate = particleSysBone.ParticleSystem.Value;
                if (particleSystemTemplate == null)
                {
                    throw new InvalidOperationException();
                }

                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(_context.ParticleSystems.Create(
                                        particleSystemTemplate,
                                        () => ref modelInstance.AbsoluteBoneTransforms[bone.Index]));
            }

            if (conditionState.HideSubObject != null)
            {
                foreach (var hideSubObject in conditionState.HideSubObject)
                {
                    var item = modelInstance.ModelBoneInstances.Select((value, i) => new { i, value }).FirstOrDefault(x => x.value.Name.EndsWith(hideSubObject.ToUpper()));
                    if (item != null)
                    {
                        modelInstance.BoneVisibilities[item.i] = false;
                    }
                }
            }
            if (conditionState.ShowSubObject != null)
            {
                foreach (var showSubObject in conditionState.ShowSubObject)
                {
                    var item = modelInstance.ModelBoneInstances.Select((value, i) => new { i, value }).FirstOrDefault(x => x.value.Name.EndsWith(showSubObject.ToUpper()));
                    if (item != null)
                    {
                        modelInstance.BoneVisibilities[item.i] = true;
                    }
                }
            }

            return(new W3dModelDrawConditionState(modelInstance, particleSystems, _context));
        }
예제 #17
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.Animations
                                     .Concat(conditionState.IdleAnimations)
                                     .LastOrDefault();
                if (firstAnimation != null)
                {
                    var splitName = firstAnimation.Animation.Split('.');

                    var w3dFilePath = Path.Combine("Art", "W3D", splitName[0] + ".W3D");
                    var model       = _contentManager.Load <Model>(w3dFilePath);

                    if (model.Animations.Length == 0)
                    {
                        // TODO: What is the actual algorithm here?
                        w3dFilePath = Path.Combine("Art", "W3D", splitName[1] + ".W3D");
                        model       = _contentManager.Load <Model>(w3dFilePath);
                    }

                    if (model != null)
                    {
                        var animation = model.Animations.FirstOrDefault(x => string.Equals(x.Name, splitName[1], StringComparison.OrdinalIgnoreCase));
                        if (animation != null)
                        {
                            // TODO: Should this ever be null?

                            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.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);
        }
        private W3dModelDrawConditionState CreateModelDrawConditionStateInstance(ModelConditionState conditionState)
        {
            // Load model, fallback to default model.
            var model = conditionState.Model?.Value ?? _defaultConditionState.Model?.Value;

            ModelInstance modelInstance = null;

            if (model != null)
            {
                modelInstance = model.CreateInstance(_loadContext);
            }

            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)
                {
                    var animation = firstAnimation.Animation.Value;

                    if (animation != null)
                    {
                        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 particleSystemTemplate = _loadContext.AssetStore.FXParticleSystemTemplates.GetByName(particleSysBone.ParticleSystem);
                    if (particleSystemTemplate == null)
                    {
                        particleSystemTemplate = _loadContext.AssetStore.ParticleSystemTemplates.GetByName(particleSysBone.ParticleSystem)?.ToFXParticleSystemTemplate();

                        if (particleSystemTemplate == null)
                        {
                            throw new InvalidOperationException("Missing referenced particle system: " + 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(
                                            particleSystemTemplate,
                                            _loadContext,
                                            () => ref modelInstance.AbsoluteBoneTransforms[bone.Index]));
                }
            }

            return(modelInstance != null
               ? new W3dModelDrawConditionState(modelInstance, particleSystems)
               : null);
        }
예제 #19
0
        private Entity CreateModelDrawConditionStateEntity(ModelConditionState conditionState)
        {
            var result = new Entity();

            Entity modelEntity = 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)
                {
                    result.AddChild(modelEntity = model.CreateEntity());
                }
            }

            if (modelEntity != 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.Animations
                                     .Concat(conditionState.IdleAnimations)
                                     .LastOrDefault();
                if (firstAnimation != null)
                {
                    var splitName = firstAnimation.Animation.Split('.');

                    var w3dFilePath = Path.Combine("Art", "W3D", splitName[0] + ".W3D");
                    var model       = ContentManager.Load <Model>(w3dFilePath);

                    if (model.Animations.Length == 0)
                    {
                        // TODO: What is the actual algorithm here?
                        w3dFilePath = Path.Combine("Art", "W3D", splitName[1] + ".W3D");
                        model       = ContentManager.Load <Model>(w3dFilePath);
                    }

                    if (model != null)
                    {
                        var animation = model.Animations.FirstOrDefault(x => string.Equals(x.Name, splitName[1], StringComparison.OrdinalIgnoreCase));
                        if (animation != null)
                        {
                            // TODO: Should this ever be null?

                            var animationComponent = new AnimationComponent
                            {
                                Animation = animation
                            };

                            modelEntity.Components.Add(animationComponent);

                            animationComponent.Play();
                        }
                    }
                }
            }

            if (modelEntity != null)
            {
                foreach (var particleSysBone in conditionState.ParticleSysBones)
                {
                    var particleSystemDefinition = ContentManager.IniDataContext.ParticleSystems.First(x => x.Name == particleSysBone.ParticleSystem);
                    var bone = modelEntity.GetComponent <ModelComponent>().Bones.FirstOrDefault(x => string.Equals(x.Entity.Name, particleSysBone.BoneName, StringComparison.OrdinalIgnoreCase));
                    if (bone == null)
                    {
                        // TODO: Should this ever happen?
                        continue;
                    }

                    var particleSystem = new ParticleSystem(particleSystemDefinition);
                    bone.Entity.Components.Add(particleSystem);
                }
            }

            return(result);
        }
예제 #20
0
        private W3dModelDrawConditionState CreateModelDrawConditionStateInstance(ModelConditionState conditionState)
        {
            // Load model, fallback to default model.
            var model = conditionState.Model?.Value ?? _defaultConditionState.Model?.Value;

            ModelInstance modelInstance = null;

            if (model != null)
            {
                modelInstance = model.CreateInstance(_context.AssetLoadContext);
            }

            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)
                {
                    var animation = firstAnimation.Animation.Value;

                    if (animation != null)
                    {
                        var mode              = conditionState.AnimationMode;
                        var flags             = conditionState.Flags;
                        var animationInstance = new AnimationInstance(modelInstance, animation, mode, flags);
                        modelInstance.AnimationInstances.Add(animationInstance);
                    }
                }
            }

            var particleSystems = new List <ParticleSystem>();

            if (modelInstance != null)
            {
                foreach (var particleSysBone in conditionState.ParticleSysBones)
                {
                    var particleSystemTemplate = particleSysBone.ParticleSystem.Value;
                    if (particleSystemTemplate == null)
                    {
                        throw new InvalidOperationException();
                    }

                    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(_context.ParticleSystems.Create(
                                            particleSystemTemplate,
                                            () => ref modelInstance.AbsoluteBoneTransforms[bone.Index]));
                }
            }

            if (modelInstance != null)
            {
                if (conditionState.HideSubObject != null)
                {
                    foreach (var hideSubObject in conditionState.HideSubObject)
                    {
                        var item = modelInstance.ModelBoneInstances.Select((value, i) => new { i, value }).FirstOrDefault(x => x.value.Name.EndsWith("." + hideSubObject.ToUpper()));
                        if (item != null)
                        {
                            modelInstance.BoneVisibilities[item.i] = false;
                        }
                    }
                }
                if (conditionState.ShowSubObject != null)
                {
                    foreach (var showSubObject in conditionState.ShowSubObject)
                    {
                        var item = modelInstance.ModelBoneInstances.Select((value, i) => new { i, value }).FirstOrDefault(x => x.value.Name.EndsWith("." + showSubObject.ToUpper()));
                        if (item != null)
                        {
                            modelInstance.BoneVisibilities[item.i] = true;
                        }
                    }
                }
            }

            return(modelInstance != null
               ? new W3dModelDrawConditionState(modelInstance, particleSystems, _context)
               : null);
        }
예제 #21
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);
        }
예제 #22
0
 internal static void Parse(IniParser parser, ModelConditionState result)
 {
     parser.ParseBlock(FieldParseTable, result);
 }