示例#1
0
        private static EventAction <GameEntityModel> .ExecutionDelegate BuildAddInpulse(Storage.GenericParameter parameter)
        {
            FixedVector3 impulse      = BuildFixedVector3(parameter, 0);
            bool         asPercentage = parameter.SafeBool(0);

            if (asPercentage)
            {
                impulse /= 100;
            }

            return(delegate(GameEntityModel model, List <GameEntityModel>[] subjectModels){
                PhysicPointModel pointModel = StateManager.state.GetModel(model.physicsModelId) as PhysicPointModel;
                if (pointModel == null)
                {
                    return;
                }
                FixedVector3 finalImpulse = impulse;
                if (asPercentage)
                {
                    finalImpulse = pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName];
                    finalImpulse = new FixedVector3(
                        finalImpulse.X * impulse.X,
                        finalImpulse.Y * impulse.Y,
                        finalImpulse.Z * impulse.Z
                        );
                }
                else
                {
                    finalImpulse = impulse;
                }
                pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName] += finalImpulse;
            });
        }
示例#2
0
		// Release event may be accompained by a set animation event and set anchored position.
		// It safely releases at the relative position to parent, taking physics in consideration
		public static void ReleaseAnchoredEntity(GameEntityModel model, GameEntityModel anchoredEntityModel){
			int anchorId = -1;
			for (int i = 0; i < model.anchoredEntities.Count ; ++i){
				if (model.anchoredEntities[i] == anchoredEntityModel.Index){
					anchorId = i;
					break;
				}
			}
			if (anchorId == -1){
				// entity is not grabbed, return
				return;
			}
			anchoredEntityModel.parentEntity = new ModelReference();
			PhysicPointModel pointModel = GameEntityController.GetPointModel(anchoredEntityModel);
			if (pointModel != null){
				pointModel.isActive = true;
				PhysicPointModel parentPointModel = GameEntityController.GetPointModel(model);
				PhysicPointController pointController = pointModel.Controller() as PhysicPointController;
				if (pointController != null && parentPointModel != null){
					// Set position directly
					pointModel.position = parentPointModel.position;
					if (!model.IsFacingRight()) anchoredEntityModel.positionRelativeToParent.X *= -1;
					pointController.SetVelocityAffector(pointModel, PhysicPointController.setPositionffectorName, anchoredEntityModel.positionRelativeToParent);
					anchoredEntityModel.positionRelativeToParent = FixedVector3.Zero;
				}
			}
			model.anchoredEntities[anchorId] = new ModelReference();
		}
示例#3
0
        // Filter hit by hitter entity location
        private static GameEntityModel getHitEntityIfConformingOrientationOptions(HitInformation hit, OrientationOptions orientationOptions, GameEntityModel model)
        {
            GameEntityModel hitterModel = StateManager.state.GetModel(hit.entityId) as GameEntityModel;

            if (orientationOptions == OrientationOptions.any)
            {
                return(hitterModel);
            }

            PhysicPointModel modelPoint  = GameEntityController.GetPointModel(model);
            PhysicPointModel hitterPoint = GameEntityController.GetPointModel(hitterModel);
            bool             isFrontal;

            if (model.IsFacingRight())
            {
                isFrontal = hitterPoint.position.X >= modelPoint.position.X;
            }
            else
            {
                isFrontal = hitterPoint.position.X <= modelPoint.position.X;
            }
            if (isFrontal == (orientationOptions == OrientationOptions.fromFront))
            {
                return(hitterModel);
            }
            return(null);
        }
示例#4
0
 public GameEntityModel(
     State state,
     PhysicWorldModel worldModel,
     PhysicPointModel physicsModel,
     AnimationModel animationModel,
     Model inputModel,
     string controllerFactoryId,
     string viewFactoryId,
     int updatingOrder
     ) : base(controllerFactoryId, viewFactoryId, updatingOrder)
 {
     animationModel.ownerId = this.Index;
     physicsModel.ownerId   = this.Index;
     physicsModelId         = state.AddModel(physicsModel);
     worldModel.pointModels.Add(physicsModelId);
     animationModelId = state.AddModel(animationModel);
     if (inputModel != null)
     {
         inputModelId = state.AddModel(inputModel);
     }
     else
     {
         inputModelId = new ModelReference(ModelReference.InvalidModelIndex);
     }
     anchoredEntities = new List <ModelReference>();
     ownedEntities    = new List <ModelReference>();
     customVariables  = new Dictionary <string, int>();
     mIsFacingRight   = true;
 }
示例#5
0
		// Anchor a model to it
		public static void AnchorEntity(GameEntityModel model, GameEntityModel modelToBeAnchored, int anchorId){
			if (IsAnchored(modelToBeAnchored)){
				Debug.LogWarning("Trying to anchor an entity that is already anchored");
				return;
			}
			if (model.parentEntity != null && model.parentEntity == modelToBeAnchored.Index){
				Debug.LogWarning("Cyclic anchoring attempt");
				return;
			}
			if (model.anchoredEntities == null) model.anchoredEntities = new List<ModelReference>(anchorId);
			while (model.anchoredEntities.Count <= anchorId) {
				model.anchoredEntities.Add(null);
			}
			if (model.anchoredEntities[anchorId] != null && model.anchoredEntities[anchorId] != ModelReference.InvalidModelIndex){
				Debug.LogWarning("Trying to anchor an entity to a busy anchor");
				return;
			}
			model.anchoredEntities[anchorId] = modelToBeAnchored.Index;
			modelToBeAnchored.parentEntity = model.Index;
			modelToBeAnchored.positionRelativeToParent = FixedVector3.Zero;
			PhysicPointModel pointModel = GameEntityController.GetPointModel(modelToBeAnchored);
			if (pointModel != null){
				pointModel.isActive = false;
			}
		}
        // Update the input velocity affector multiplying input axis and max input velocity
        private static void UpdateInputVelocityAffector(GameEntityModel model)
        {
            PhysicPointModel pointModel = GetPointModel(model);

            if (pointModel == null)
            {
                return;
            }
            FixedVector3 newInputVel = FixedVector3.Zero;

            if (model.maxInputVelocity.X != 0 || model.maxInputVelocity.Y != 0)
            {
                Model inputModel = GetInputProvider(model);
                if (inputModel == null)
                {
                    return;
                }
                GameEntityInputProvider inputController = inputModel.Controller() as GameEntityInputProvider;
                if (inputController == null)
                {
                    return;
                }
                FixedVector3 axis = inputController.GetInputAxis(inputModel);
                newInputVel = new FixedVector3(axis.X * model.maxInputVelocity.X, axis.Y * model.maxInputVelocity.Y, axis.Z * model.maxInputVelocity.Z);
            }
            pointModel.velocityAffectors[inputVelocityAffector] = newInputVel;
        }
示例#7
0
        // Find collisions between a point model and a set of world planes
        // For each collision found, notify point and plane controllers so that they can react to the collision
        private void CheckCollisionsAgainstPlanes(PhysicWorldModel world, PhysicPointModel pointModel, PhysicPointController pointController, List <PhysicPlaneModel> planes)
        {
            PhysicPlaneController planeController;
            FixedVector3          intersection;

            // Do a few iterations until collisions get stable, or we reach a limit on iterations
            bool collisionsAreStable = false;

            for (int i = 0; i < collisionIterationsCount && !collisionsAreStable; ++i)
            {
                collisionsAreStable = true;
                int numCollisions = 0;
                foreach (PhysicPlaneModel planeModel in planes)
                {
                    if (PhysicPlaneController.CheckIntersection(planeModel, pointModel, out intersection))
                    {
                        ++numCollisions;
                        collisionsAreStable &= pointController.OnCollision(world, pointModel, planeModel, intersection);
                        planeController      = planeModel.Controller() as PhysicPlaneController;
                        collisionsAreStable &= planeController == null || planeController.OnCollision(world, pointModel, planeModel, intersection);
                    }
                }
                //Debug.Log("Collisions: " + numCollisions);
            }
        }
        // Compute the intersection point against a line segment
        public static bool CheckIntersection(PhysicPlaneModel planeModel, PhysicPointModel pointModel, out FixedVector3 intersection)
        {
            // plane may be moving, sum velocity to initial point position
            FixedVector3 pos1 = pointModel.lastPosition;
            FixedVector3 pos2 = pointModel.position;

            pos1 += planeModel.GetVelocity();
            return(CheckIntersection(planeModel, pos1, pos2, pointModel.stepTolerance, out intersection));
        }
示例#9
0
        // Apply a force on the physics velocity affector
        public static FixedFloat GetVerticalImpulse(GameEntityModel model)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel == null)
            {
                return(FixedFloat.Zero);
            }
            return(pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName].Y);
        }
示例#10
0
        public static bool IsHittingFarWall(GameEntityModel model)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel == null)
            {
                return(false);
            }
            return(pointModel.collisionInpact.Z > 0);
        }
示例#11
0
        public static FixedFloat CollisionZForce(GameEntityModel model)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel == null)
            {
                return(FixedFloat.Zero);
            }
            return(FixedFloat.Abs(pointModel.collisionInpact.Z));
        }
示例#12
0
        // ----------------------
        // Ground and Wall checks

        public static bool IsGrounded(GameEntityModel model)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel == null)
            {
                return(false);
            }
            return(PhysicPointController.IsGrounded(pointModel));
        }
示例#13
0
        // Safelly set position relative to self (e.g. vault), taking physics collisions in consideration
        public static void MoveEntity(GameEntityModel model, FixedVector3 relativePosition)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel != null)
            {
                PhysicPointController pointController = pointModel.Controller() as PhysicPointController;
                if (pointController != null)
                {
                    pointController.SetVelocityAffector(pointModel, PhysicPointController.setPositionffectorName, relativePosition);
                }
            }
        }
示例#14
0
		// Anchor a model to it, and optionally move the parent relative to the entity being anchored (e.g. move back a little when grabbing)
		public static void AnchorEntity(GameEntityModel model, GameEntityModel modelToBeAnchored, int anchorId, FixedVector3 deltaPosRelativeToAnched){
			AnchorEntity(model, modelToBeAnchored, anchorId);
			PhysicPointModel pointModel = GameEntityController.GetPointModel(model);
			PhysicPointModel anchoredPointModel = GameEntityController.GetPointModel(modelToBeAnchored);
			if (pointModel != null && anchoredPointModel != null){
				PhysicPointController pointController = pointModel.Controller() as PhysicPointController;
				if (pointController != null){
					if (!model.IsFacingRight()) deltaPosRelativeToAnched.X *= -1;
					FixedVector3 deltaPos = (anchoredPointModel.position + deltaPosRelativeToAnched) - pointModel.position;
					pointController.SetVelocityAffector(pointModel, PhysicPointController.setPositionffectorName, deltaPos);
				}
			}
		}
示例#15
0
        // Set the velocity affector bound to animation velocity control
        public static void SetAnimationVelocity(GameEntityModel model, FixedVector3 velocity)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel == null)
            {
                return;
            }
            if (!model.IsFacingRight())
            {
                velocity.X *= -1;
            }
            pointModel.velocityAffectors[GameEntityController.animVelocityAffector] = velocity;
        }
 protected override void PostUpdate(GameEntityModel model)
 {
     if (nextPauseTimer > 0)
     {
         // Pause physics and animation
         PhysicPointModel pointModel = GetPointModel(model);
         if (pointModel != null)
         {
             pointModel.isActive = false;
             model.pauseTimer    = nextPauseTimer;
         }
         nextPauseTimer = 0;
     }
 }
示例#17
0
        // Reset X and Z force components on the physics velocity affector
        public static void ResetPlanarImpulse(GameEntityModel model)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel == null)
            {
                return;
            }
            FixedVector3 originalImpulse;

            pointModel.velocityAffectors.TryGetValue(PhysicPointModel.defaultVelocityAffectorName, out originalImpulse);
            pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName] =
                new FixedVector3(0, originalImpulse.Y, 0)
            ;
        }
示例#18
0
        // Apply a force on the physics velocity affector
        public static void AddImpulse(GameEntityModel model, FixedVector3 impulse)
        {
            PhysicPointModel pointModel = GameEntityController.GetPointModel(model);

            if (pointModel == null)
            {
                return;
            }
            if (!model.IsFacingRight())
            {
                impulse.X *= -1;
            }
            pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName] += impulse;
            //			pointModel.velocityAffectors[PhysicPointModel.defaultVelocityAffectorName] += new FixedVector3(0, impulse.Y, 0);
            //			pointModel.velocityAffectors[GameEntityController.animVelocityAffector] += new FixedVector3(impulse.X, 0, impulse.Z);
        }
 // If automatic flip is on, flip automatically if input velocity is going against entity direction
 private static void CheckAutomaticFlip(GameEntityModel model)
 {
     if (model.automaticFlip)
     {
         PhysicPointModel pointModel = GetPointModel(model);
         if (pointModel == null)
         {
             return;
         }
         FixedVector3 inputVelocity = pointModel.velocityAffectors[inputVelocityAffector];
         if (inputVelocity.X != 0 && (inputVelocity.X > 0 != model.IsFacingRight()))
         {
             Flip(model);
         }
     }
 }
        // Face to same direction as hitter is facing
        public static void FaceToHitterDirection(GameEntityModel model, bool oppositeFacing)
        {
            GameEntityController controller = model.Controller() as GameEntityController;
            PhysicPointModel     pointModel = GameEntityController.GetPointModel(model);

            if (pointModel != null && controller.lastHurts.Count > 0)
            {
                HitInformation  info   = controller.lastHurts[0];
                GameEntityModel hitter = StateManager.state.GetModel(info.entityId) as GameEntityModel;
                model.mIsFacingRight = hitter.IsFacingRight();
                if (oppositeFacing)
                {
                    model.mIsFacingRight = !model.IsFacingRight();
                }
            }
        }
 // Get Position used in collision checks
 public static FixedVector3 GetRealPosition(GameEntityModel model)
 {
     if (model.parentEntity == null || model.parentEntity == ModelReference.InvalidModelIndex)
     {
         // Normal position
         PhysicPointModel pointModel = StateManager.state.GetModel(model.physicsModelId) as PhysicPointModel;
         return(pointModel.position);
     }
     else
     {
         // Anchored, use parent position
         GameEntityModel parentModel    = StateManager.state.GetModel(model.parentEntity) as GameEntityModel;
         FixedVector3    parentPosition = GetRealPosition(parentModel);
         return(parentPosition + new FixedVector3((parentModel.IsFacingRight() ? 1 : -1) * model.positionRelativeToParent.X, model.positionRelativeToParent.Y, model.positionRelativeToParent.Z));
     }
 }
示例#22
0
        // pos(2.1, 4.2, 5.3)
        private static EventAction <GameEntityModel> .ExecutionDelegate BuildSetDeltaPosition(Storage.GenericParameter parameter)
        {
            int          relativeSubjectId = parameter.SafeInt(1);
            FixedVector3 deltaPos          = BuildFixedVector3(parameter, 0);

            return(delegate(GameEntityModel model, List <GameEntityModel>[] subjectModels){
                List <GameEntityModel> refSubjects = ConditionUtils <GameEntityModel> .GetNonEmptySubjectOrNil(subjectModels, relativeSubjectId);

                if (refSubjects == null || refSubjects.Count == 0)
                {
                    return;
                }
                // Select one randomly
                GameEntityModel refModel = refSubjects[StateManager.state.Random.NextInt(0, refSubjects.Count - 1)];
                FixedVector3 realDelta;
                if (!refModel.IsFacingRight())
                {
                    deltaPos.X *= -1;
                }
                PhysicPointModel mainPoint = StateManager.state.GetModel(model.physicsModelId) as PhysicPointModel;
                if (mainPoint == null)
                {
                    return;
                }
                if (refModel != model)
                {
                    PhysicPointModel refPoint = StateManager.state.GetModel(refModel.physicsModelId) as PhysicPointModel;
                    if (refPoint == null)
                    {
                        return;
                    }
                    realDelta = (refPoint.position + deltaPos) - mainPoint.position;
                }
                else
                {
                    realDelta = deltaPos;
                }

                PhysicPointController pointController = mainPoint.Controller() as PhysicPointController;
                if (pointController == null)
                {
                    return;
                }
                pointController.SetVelocityAffector(mainPoint, PhysicPointController.setPositionffectorName, realDelta);
            });
        }
示例#23
0
        // Delegate for when a point is removed, it redirects to the caller delegate
        private void OnPointRemoved(Model model, object context)
        {
            Eppy.Tuple <OnPointModelChanged, object> callbackTuple;
            PhysicPointModel pointModel = model as PhysicPointModel;
            PhysicWorldModel worldModel = context as PhysicWorldModel;

            if (pointModel == null || worldModel == null)
            {
                // Something went wrong!
                return;
            }
            if (removePointCallbacks.TryGetValue(pointModel, out callbackTuple))
            {
                if (callbackTuple.Item1 != null)
                {
                    callbackTuple.Item1(pointModel, callbackTuple.Item2);
                }
                removePointCallbacks.Remove(pointModel);
                worldModel.pointModels.Remove(model.Index);
            }
        }
        // Update automated stuff
        protected override void Update(GameEntityModel model)
        {
            // first update the input velocity
            UpdateInputVelocityAffector(model);

            // if input velocity goes against current direction, flip
            CheckAutomaticFlip(model);

            // Built in pause timer
            if (model.pauseTimer > 0)
            {
                PhysicPointModel pointModel = GetPointModel(model);
                if (pointModel != null)
                {
                    if (--model.pauseTimer == 0 && (model.parentEntity == null || model.parentEntity == ModelReference.InvalidModelIndex))
                    {
                        pointModel.isActive = true;
                    }
                }
            }
        }
示例#25
0
		// Release event may be accompained by a set animation event and set anchored position.
		// It safely releases at the relative position to parent, taking physics in consideration
		public static void ReleaseAnchoredEntity(GameEntityModel model, int anchorId){
			if (model.anchoredEntities == null || model.anchoredEntities.Count <= anchorId) return;
			GameEntityModel anchoredEntityModel = StateManager.state.GetModel(model.anchoredEntities[anchorId]) as GameEntityModel;
			if (anchoredEntityModel != null){
				anchoredEntityModel.parentEntity = new ModelReference();
				PhysicPointModel pointModel = GameEntityController.GetPointModel(anchoredEntityModel);
				if (pointModel != null){
					pointModel.isActive = true;
					PhysicPointModel parentPointModel = GameEntityController.GetPointModel(model);
					PhysicPointController pointController = pointModel.Controller() as PhysicPointController;
					if (pointController != null && parentPointModel != null){
						// Set position directly
						pointModel.position = parentPointModel.position;
						if (!model.IsFacingRight()) anchoredEntityModel.positionRelativeToParent.X *= -1;
						pointController.SetVelocityAffector(pointModel, PhysicPointController.setPositionffectorName, anchoredEntityModel.positionRelativeToParent);
						anchoredEntityModel.positionRelativeToParent = FixedVector3.Zero;
					}
				}
			}
			model.anchoredEntities[anchorId] = new ModelReference();
		}
        // Velocity
        private static EventCondition <GameEntityModel> .EvaluationDelegate BuildVelocity(Storage.GenericParameter parameter, out int keyFrame, Storage.CharacterAnimation animation)
        {
            keyFrame = InvalidKeyframe;
            // Read orientation, operator, numerator subject, numerator var, number, module
            Orientation orientation = (Orientation)parameter.SafeInt(1);

            ConditionUtils <GameEntityModel> .ComparisonOperation comparisonOperator = (ConditionUtils <GameEntityModel> .ComparisonOperation)parameter.SafeInt(2);
            int        numeratorSubjectId      = parameter.SafeInt(3);
            string     numeratorSubjectVarName = parameter.SafeString(0);
            FixedFloat staticComparisonValue   = parameter.SafeFloat(0);
            bool       useModule = parameter.SafeBool(1);

            // return delegate
            return(delegate(GameEntityModel mainModel, List <GameEntityModel>[] subjectModels){
                PhysicPointModel pointModel = StateManager.state.GetModel(mainModel.physicsModelId) as PhysicPointModel;
                if (pointModel == null)
                {
                    return false;
                }
                FixedFloat velocityValue = getOrientedAxisValue(pointModel.GetVelocity(), orientation, useModule);
                return CompareWithNumerator(mainModel, numeratorSubjectId, numeratorSubjectVarName, velocityValue, staticComparisonValue, comparisonOperator, subjectModels);
            });
        }
        public static bool IsHurtFrontal(GameEntityModel model, bool frontal)
        {
            GameEntityController controller = model.Controller() as GameEntityController;

            if (controller.lastHurts.Count == 0)
            {
                return(false);
            }
            GameEntityModel  hitter      = StateManager.state.GetModel(controller.lastHurts[0].entityId) as GameEntityModel;
            PhysicPointModel modelPoint  = GameEntityController.GetPointModel(model);
            PhysicPointModel hitterPoint = GameEntityController.GetPointModel(hitter);
            bool             isFrontal;

            if (model.IsFacingRight())
            {
                isFrontal = hitterPoint.position.X >= modelPoint.position.X;
            }
            else
            {
                isFrontal = hitterPoint.position.X <= modelPoint.position.X;
            }
            return(isFrontal == frontal);
        }
示例#28
0
        private static EventAction <GameEntityModel> .ExecutionDelegate BuildSetVelocity(Storage.GenericParameter parameter)
        {
            int          mask     = parameter.SafeInt(1);
            FixedVector3 velocity = BuildFixedVector3(parameter, 0);
            bool         hasX     = mask == 0 || mask == 3 || mask == 4 || mask == 6;
            bool         hasY     = mask == 1 || mask == 3 || mask == 5 || mask == 6;
            bool         hasZ     = mask == 2 || mask == 4 || mask == 5 || mask == 6;

            return(delegate(GameEntityModel model, List <GameEntityModel>[] subjectModels){
                PhysicPointModel pointModel = StateManager.state.GetModel(model.physicsModelId) as PhysicPointModel;
                if (pointModel == null)
                {
                    return;
                }
                FixedVector3 originalVelocity = pointModel.GetVelocity();
                FixedVector3 finalVelocity = new FixedVector3(
                    hasX ? velocity.X : originalVelocity.X,
                    hasY ? velocity.Y : originalVelocity.Y,
                    hasZ ? velocity.Z : originalVelocity.Z
                    );
                pointModel.velocityAffectors[GameEntityController.animVelocityAffector] = finalVelocity;
            });
        }
示例#29
0
 // Remove a Physic Point from the world
 public void RemovePoint(PhysicWorldModel world, PhysicPointModel pointModel, OnPointModelChanged callback = null, object context = null)
 {
     removePointCallbacks[pointModel] = new Eppy.Tuple <OnPointModelChanged, object>(callback, context);
     StateManager.state.RemoveModel(pointModel, OnPointRemoved, world);
 }
示例#30
0
 // This will take effect on next frame only
 private void ApplyGravityToPoint(PhysicWorldModel world, PhysicPointModel pointModel, PhysicPointController pointController)
 {
     pointController.AddVelocityAffector(pointModel, PhysicPointModel.defaultVelocityAffectorName, world.gravity);
 }