private static void enqueueDestroyActions(IStoryAction <UintT> storyAction, CM.DomainAction domainAction, CM.Animation effectingAnimation, FireBoltActionList aaq, string parentActionId, bool implicitActorInstantiation) { foreach (CM.DestroyAction da in domainAction.DestroyActions) { float startTick = 0; string actorName = null; foreach (CM.DomainActionParameter domainActionParameter in domainAction.Params) { if (domainActionParameter.Name == da.ActorNameParamName) { if (!getActionParameterValue(storyAction, domainActionParameter, out actorName) || (implicitActorInstantiation && !actorWillBeInstantiated(actorName))) { break; } } } startTick = getStartTick(storyAction, da, effectingAnimation); if (Destroy.ValidForConstruction(actorName)) { aaq.Add(new Destroy(startTick, actorName) { ParentActionId = parentActionId }); } } }
private static void enqueueAttachActions(IStoryAction <UintT> storyAction, CM.DomainAction domainAction, CM.Animation effectingAnimation, FireBoltActionList aaq, string parentActionId, bool implicitActorInstantiation) { foreach (CM.AttachAction aa in domainAction.AttachActions) { float startTick = 0; string actorName = null; string parentName = null; bool attach = false; foreach (CM.DomainActionParameter domainActionParameter in domainAction.Params) { if (domainActionParameter.Name == aa.ActorNameParamName) { getActionParameterValue(storyAction, domainActionParameter, out actorName); //TODO fail gracefully if we don't find actor param value } else if (domainActionParameter.Name == aa.ParentParamName) { getActionParameterValue(storyAction, domainActionParameter, out parentName); //TODO fail gracefully if we don't find parent param value } } attach = aa.Attach; startTick = getStartTick(storyAction, aa, effectingAnimation); if ((!implicitActorInstantiation || actorWillBeInstantiated(actorName)) && Create.ValidForConstruction(actorName, parentName)) { aaq.Add(new Attach(startTick, actorName, parentName, attach) { ParentActionId = parentActionId }); } } }
//private static void buildInitialState(FireBoltActionList aaq) //TODO actor model defaulting a la create actions //{ // var interval = new UintT(new UintV(0), new UintV(1)); // var initialPositions = from sentence in story.Sentences // where sentence is Predicate // let p = (Predicate)sentence // where p.Temporal && // p.Name == "at" && // p.Time is UintT && // p.Terms[0] is IConstant && // p.Terms[1] is IConstant<Coordinate2D> && // story.IntervalSet.IncludesOrMeetsStartOf<UintV, UintT>((UintT)p.Time, interval) // select new { Actor = p.Terms[0].Name, Location = (p.Terms[1] as IConstant<Coordinate2D>).Value }; // Extensions.Log("building init state creation actions"); // foreach (var initPos in initialPositions) // { // Extensions.Log(initPos.Actor + ", " + initPos.Location.ToString()); // CM.Actor actor; // if (!cm.TryGetActor(initPos.Actor,out actor)) // { // Extensions.Log("actor [" + initPos.Actor + "] not found in cinematic model."); // continue; // } // string modelFileName = actor.Model; // if (string.IsNullOrEmpty(modelFileName)) // { // Extensions.Log("model name for actor[" + initPos.Actor + "] not found in cinematic model."); // continue; // } // aaq.Add(new Create(0, initPos.Actor, modelFileName, initPos.Location.ToVector3())); // } //} private static void createActors(FireBoltActionList aaq) { var actorNames = (story.ObjectSets[Impulse.v_1_336.Xml.Story.ObjectsSetName] as IFiniteObjectSet).Items.Select(c => c.Name).ToList(); Extensions.Log("building object set based creation actions"); foreach (var actorName in actorNames) { if (!actorActuallyDoesStuff(actorName)) { //Extensions.Log("not instantiating actor[{0}] as he does nothing in this impulse", actorName); continue; } CinematicModelMetaData metaData = new CinematicModelMetaData(); if (!getActorMetaData(actorName, out metaData)) { Extensions.Log("cannot auto-create actor[{0}]", actorName); continue; } Extensions.Log("building object set based create for actor[{0}]", actorName); Create create = new Create(0, actorName, metaData.ModelName, new Vector3(-10000, 0, -10000), metaData, null, true); aaq.Add(create); implicitActorInstantiations.Add(actorName, true); } }
private static void enqueueRotateActions(IStoryAction <UintT> storyAction, CM.DomainAction domainAction, CM.Animation effectingAnimation, FireBoltActionList aaq, string parentActionId, bool implicitActorInstantiation) { foreach (CM.RotateAction ra in domainAction.RotateActions) { float startTick = 0; float endTick = 0; string actorName = null; float? targetDegrees = null; Vector2?targetPoint = null; foreach (CM.DomainActionParameter domainActionParameter in domainAction.Params) { if (domainActionParameter.Name == ra.ActorNameParamName) { if (!getActionParameterValue(storyAction, domainActionParameter, out actorName) || (implicitActorInstantiation && !actorWillBeInstantiated(actorName))) { break; } } else if (domainActionParameter.Name == ra.DestinationParamName) { IActionProperty targetOrientation; if (storyAction.TryGetProperty(domainActionParameter.Name, out targetOrientation)) { if (targetOrientation.Value.Value is float) { targetDegrees = (float)targetOrientation.Value.Value; if (targetOrientation.Range.Name == "x+degrees") { targetDegrees = targetDegrees.Value.convertSourceEngineToUnityRotation(); } } else if (targetOrientation.Value.Value is Coordinate2D) { targetPoint = new Vector2((float)((Coordinate2D)targetOrientation.Value.Value).X, (float)((Coordinate2D)targetOrientation.Value.Value).Y); } } else { Debug.LogError("orientation not set for stepId[" + storyAction.Name + "]"); } } } startTick = getStartTick(storyAction, ra, effectingAnimation); endTick = getEndTick(storyAction, ra, effectingAnimation, startTick); var targetRotation = new Vector3Nullable(null, targetDegrees, null); if (Rotate.ValidForConstruction(actorName, targetRotation, targetPoint)) { aaq.Add(new Rotate(startTick, endTick, actorName, targetRotation, targetPoint) { ParentActionId = parentActionId }); } } }
/// <summary> /// /// </summary> /// <param name="storyPlanPath">path to the story plan to load</param> /// <param name="cinematicModelPath">path to the cinematic model to load</param> /// <returns></returns> public static FireBoltActionList CreateStoryActions(Story <UintV, UintT, IIntervalSet <UintV, UintT> > story, CM.CinematicModel cm, bool implicitActorCreation) { ActorActionFactory.cm = cm; FireBoltActionList aaq = new FireBoltActionList(); ActorActionFactory.story = story; orderedObjectSets = story.ObjectSetGraph.ReverseTopologicalSort().ToArray(); //orderedActionTypes = story.ActionTypeGraph.ReverseTopologicalSort().ToArray(); implicitActorInstantiations = new Dictionary <string, bool>(); //buildInitialState(aaq); if (implicitActorCreation) { createActors(aaq); } //generate FireBolt actions for the steps foreach (IStoryAction <UintT> storyAction in story.Actions.Values) { CM.DomainAction domainAction = getStoryDomainAction(storyAction); if (domainAction == null) { continue; } CM.Animation effectingAnimation = getEffectingAnimation(storyAction, domainAction); enqueueCreateActions(storyAction, domainAction, effectingAnimation, aaq, storyAction.Name); enqueueAnimateActions(storyAction, domainAction, effectingAnimation, aaq, storyAction.Name, implicitActorCreation); enqueueDestroyActions(storyAction, domainAction, effectingAnimation, aaq, storyAction.Name, implicitActorCreation); enqueuetranslateActions(storyAction, domainAction, effectingAnimation, aaq, storyAction.Name, implicitActorCreation); enqueueRotateActions(storyAction, domainAction, effectingAnimation, aaq, storyAction.Name, implicitActorCreation); enqueueAttachActions(storyAction, domainAction, effectingAnimation, aaq, storyAction.Name, implicitActorCreation); } return(aaq); }
private static void enqueueCreateActions(IStoryAction <UintT> storyAction, CM.DomainAction domainAction, CM.Animation effectingAnimation, FireBoltActionList aaq, string parentActionId) { foreach (CM.CreateAction ca in domainAction.CreateActions) { float startTick = 0; string actorName = null; Vector3 destination = new Vector3(); Vector3?orientation = null; float targetDegrees; CinematicModelMetaData metaData = new CinematicModelMetaData(); foreach (CM.DomainActionParameter domainActionParameter in domainAction.Params) { if (domainActionParameter.Name == ca.ActorNameParamName) { if (getActionParameterValue(storyAction, domainActionParameter, out actorName))//actorName is defined, we can look up a model { if (!getActorMetaData(actorName, out metaData)) { break; //we failed to find the actor within the hierarchy } } } else if (domainActionParameter.Name == ca.OriginParamName) { IActionProperty coord; if (storyAction.TryGetProperty(domainActionParameter.Name, out coord)) { if (coord.Value.Value is Coordinate2D) { destination = ((Coordinate2D)coord.Value.Value).ToVector3(cm.DomainDistancePerEngineDistanceX, cm.DomainDistancePerEngineDistanceY, cm.DomainDistancePerEngineDistanceZ); } else if (coord.Value.Value is Coordinate3D) { destination = ((Coordinate3D)coord.Value.Value).ToVector3(cm.DomainDistancePerEngineDistanceX, cm.DomainDistancePerEngineDistanceY, cm.DomainDistancePerEngineDistanceZ); } } else { Debug.LogError("origin not set for stepId[" + storyAction.Name + "]"); } } else if (domainActionParameter.Name == ca.OrientationParamName) { IActionProperty orientationProperty; if (storyAction.TryGetProperty(domainActionParameter.Name, out orientationProperty) && tryConvertOrientation(orientationProperty, out targetDegrees)) { orientation = new Vector3(0, targetDegrees, 0); } else { Debug.LogError("origin not set for stepId[" + storyAction.Name + "]"); } } } startTick = getStartTick(storyAction, ca, effectingAnimation); if (Create.ValidForConstruction(actorName, metaData.ModelName)) { aaq.Add(new Create(startTick, actorName, metaData.ModelName, destination, metaData, orientation) { ParentActionId = parentActionId }); } } }
private static void enqueueAnimateActions(IStoryAction <UintT> storyAction, CM.DomainAction domainAction, CM.Animation effectingAnimation, FireBoltActionList aaq, string parentActionId, bool implicitActorInstantiation) { foreach (CM.AnimateAction animateAction in domainAction.AnimateActions) { string actorName = null; string abstractActorName = null; float startTick = 0; float endTick = 0; CM.AnimationMapping animMapping = null; CM.AnimationMapping stateMapping = null; CM.Animation animation = null; CM.Animation stateAnimation = new CM.Animation(); string endName = !string.IsNullOrEmpty(animateAction.End) ? animateAction.End : string.Empty; string animateActionName = animateAction.Name; //PURPOSE: if domain action parameter is the name of an animateAction for that domain action as defined in the cinematic model, //then use the parameter value as the animateAction name. // Used when a domain action has a variable for accepting an action to play, handy for spawn actions that require an initial state foreach (CM.DomainActionParameter domainActionParameter in domainAction.Params) { //endName = string.Empty; //The endName should not be string.Empty if the below propety is never true. // Extensions.Log("beforeset: " + animateAction.Name + " " + domainActionParameter.Name); if (domainActionParameter.Name.Equals(animateAction.Name)) { getActionParameterValue(storyAction, domainActionParameter, out animateActionName); endName = animateActionName; break; } } foreach (CM.DomainActionParameter domainActionParameter in domainAction.Params) { if (domainActionParameter.Name == animateAction.ActorNameParamName) { if (getActionParameterValue(storyAction, domainActionParameter, out actorName) && (!implicitActorInstantiation || actorWillBeInstantiated(actorName))) { //abstractActorName = actorName; if (!getAbstractActorName(actorName, out abstractActorName)) { //can't figure out what this actor name is supposed to be. don't try to animate it. break; } else { //this forces all levels of hierarchy to implement all animations if we want them played //we can't partially look up levels above for some things //iterate back and forth between finding matching hierarchical parents and looking for mappings to alleviate if (!getAnimationMapping(abstractActorName, animateActionName, out animMapping)) { Extensions.Log("cinematic model animation instance undefined for actor[" + abstractActorName + "] animateAction[" + animateActionName + "]"); break; } } //we have a valid mapping, let's use it to find an animation for this actor animation = cm.FindAnimation(animMapping.AnimationName); if (animation == null) { Extensions.Log("animation name [{0}] undefined", animMapping.AnimationName); break; } //end name is optional, we don't have to do this for the animation to be valid if (!string.IsNullOrEmpty(endName)) { getAnimationMapping(abstractActorName, endName, out stateMapping); if (!(stateMapping == null)) { stateAnimation = cm.FindAnimation(stateMapping.AnimationName); if (stateAnimation == null) { Extensions.Log("state animation name [{0}] undefined", stateMapping.AnimationName); break; } } } } } } startTick = getStartTick(storyAction, animateAction, effectingAnimation); endTick = getEndTick(storyAction, animateAction, effectingAnimation, startTick); if (AnimateMecanim.ValidForConstruction(actorName, animation)) { // Extensions.Log("actor: " + actorName + " animMappingName: " + animMapping.AnimationName + " animateActionName: " + animMapping.AnimateActionName + " loop: " + animMapping.LoopAnimation); aaq.Add(new AnimateMecanim(startTick, endTick, actorName, animation.FileName, animMapping.LoopAnimation, stateAnimation.FileName) { ParentActionId = parentActionId }); } } }
private static void enqueuetranslateActions(IStoryAction <UintT> storyAction, CM.DomainAction domainAction, CM.Animation effectingAnimation, FireBoltActionList aaq, string parentActionId, bool implicitActorInstantiation) { foreach (CM.TranslateAction ta in domainAction.TranslateActions) { float startTick = 0; float endTick = 0; string actorName = null; Vector3Nullable destination = new Vector3Nullable(null, null, null); Vector3 origin = Vector3.zero; foreach (CM.DomainActionParameter domainActionParameter in domainAction.Params) { if (domainActionParameter.Name == ta.OriginParamName) { IActionProperty coord; if (storyAction.TryGetProperty(domainActionParameter.Name, out coord)) { if (coord.Value.Value is Coordinate2D) { origin = ((Coordinate2D)coord.Value.Value).ToVector3(cm.DomainDistancePerEngineDistanceX, cm.DomainDistancePerEngineDistanceY, cm.DomainDistancePerEngineDistanceZ); } else if (coord.Value.Value is Coordinate3D) { origin = ((Coordinate3D)coord.Value.Value).ToVector3(cm.DomainDistancePerEngineDistanceX, cm.DomainDistancePerEngineDistanceY, cm.DomainDistancePerEngineDistanceZ); } } else { Debug.LogError("origin not set for stepId[" + storyAction.Name + "]"); } } else if (domainActionParameter.Name == ta.DestinationParamName) { IActionProperty coord; if (storyAction.TryGetProperty(domainActionParameter.Name, out coord)) { if (coord.Value.Value is Coordinate2D) { destination = ((Coordinate2D)coord.Value.Value).ToVector3Nullable(cm.DomainDistancePerEngineDistanceX, cm.DomainDistancePerEngineDistanceY, cm.DomainDistancePerEngineDistanceZ); } else if (coord.Value.Value is Coordinate3D) { destination = ((Coordinate3D)coord.Value.Value).ToVector3Nullable(cm.DomainDistancePerEngineDistanceX, cm.DomainDistancePerEngineDistanceY, cm.DomainDistancePerEngineDistanceZ); } } else { Debug.LogError("destination not set for stepId[" + storyAction.Name + "]"); } } else if (domainActionParameter.Name == ta.ActorNameParamName) { if (!getActionParameterValue(storyAction, domainActionParameter, out actorName) || (implicitActorInstantiation && !actorWillBeInstantiated(actorName))) { break; } } } startTick = getStartTick(storyAction, ta, effectingAnimation); endTick = getEndTick(storyAction, ta, effectingAnimation, startTick); if (Translate.ValidForConstruction(actorName)) { aaq.Add(new Translate(startTick, endTick, actorName, origin, destination) { ParentActionId = parentActionId }); } } }
public static void CreateActions(Story <UintV, UintT, IIntervalSet <UintV, UintT> > story, CM.CinematicModel cinematicModel, string cameraPlanPath, out CameraActionList cameraActionList, out FireBoltActionList discourseActionList) { cameraActionList = new CameraActionList(); discourseActionList = new FireBoltActionList(); CameraPlan cameraPlan = Oshmirto.Parser.Parse(cameraPlanPath); if (cinematicModel.MillisPerTick != 1) { scaleTime(cinematicModel.MillisPerTick, cameraPlan); } uint currentDiscourseTime = 0; float previousStoryTimeOffset = 0; foreach (Block block in cameraPlan.Blocks) { float blockStartTime = Single.MaxValue; float blockEndTime = Single.MinValue; foreach (var fragment in block.ShotFragments) { uint fragmentStartTime = currentDiscourseTime;//removing increment. cameras always execute after discourse actions currentDiscourseTime++; uint fragmentEndTime = fragmentStartTime + fragment.Duration; if (fragmentStartTime < blockStartTime) //assumes same time scale for discourse and story { blockStartTime = fragmentStartTime; } if (fragmentEndTime > blockEndTime) { blockEndTime = fragmentEndTime; } cameraActionList.Add(new ShotFragmentInit(fragmentStartTime, cameraRig, fragment.Anchor, fragment.Height, fragment.Pan, fragment.Lens, fragment.FStop, fragment.Framings, fragment.Direction, fragment.Angle, fragment.FocusPosition)); var movementStartTime = fragmentStartTime + 1; //force moves to sort after inits RotateRelative rotateWith = null; //collect all the relative rotations together for the camera so we can avoid representational nightmares Rotate rotateTo = null; //similarly collect absolute rotations...eventually we should cross check and/or merge this stuff foreach (var movement in fragment.CameraMovements) { switch (movement.Type) { case CameraMovementType.Dolly: switch (movement.Directive) { case (CameraMovementDirective.With): cameraActionList.Add(new TranslateRelative(movement.Subject, movementStartTime, fragmentEndTime, cameraRig, false, true, false)); break; case (CameraMovementDirective.To): Vector2 destination; if (movement.Subject.TryParsePlanarCoords(out destination)) { cameraActionList.Add(new Translate(movementStartTime, fragmentEndTime, cameraRig, null, new Vector3Nullable(destination.x, null, destination.y))); } break; } break; case CameraMovementType.Crane: switch (movement.Directive) { case CameraMovementDirective.With: break; case CameraMovementDirective.To: cameraActionList.Add(new Translate(movementStartTime, fragmentEndTime, cameraRig, null, new Vector3Nullable(null, float.Parse(movement.Subject), null))); break; } break; case CameraMovementType.Pan: switch (movement.Directive) { case CameraMovementDirective.With: if (rotateWith != null) { rotateWith.AppendAxis(movement.Subject, cameraRig, true, false); } else { rotateWith = new RotateRelative(movement.Subject, movementStartTime, fragmentEndTime, cameraRig, true, false); } break; case CameraMovementDirective.To: if (rotateTo != null) { rotateTo.AppendAxisY(float.Parse(movement.Subject)); } else { rotateTo = new Rotate(movementStartTime, fragmentEndTime, cameraRig, new Vector3Nullable(null, float.Parse(movement.Subject), null), null); } break; } break; case CameraMovementType.Tilt: switch (movement.Directive) { case CameraMovementDirective.With: // will this co-execute with pan-with? not currently if (rotateWith != null) { rotateWith.AppendAxis(movement.Subject, cameraRig, false, true); } else { rotateWith = new RotateRelative(movement.Subject, movementStartTime, fragmentEndTime, cameraRig, false, true); } break; case CameraMovementDirective.To: if (rotateTo != null) { rotateTo.AppendAxisX(float.Parse(movement.Subject)); } else { rotateTo = new Rotate(movementStartTime, fragmentEndTime, cameraRig, new Vector3Nullable(float.Parse(movement.Subject), null, null), null); } break; } break; case CameraMovementType.Focus: switch (movement.Directive) { case CameraMovementDirective.With: cameraActionList.Add(new Focus(movementStartTime, fragmentEndTime, cameraName, movement.Subject, true)); break; } break; } } if (rotateWith != null) { cameraActionList.Add(rotateWith); } if (rotateTo != null) { cameraActionList.Add(rotateTo); } // Shake it off if (fragment.Shake > float.Epsilon) { cameraActionList.Add(new Shake(movementStartTime, fragmentEndTime, cameraName, fragment.Shake)); } currentDiscourseTime = fragmentEndTime + 1; //set fragments to end and next to start on next tick } if (block.StoryTime.HasValue) { float currentStoryTimeOffset = block.StoryTime.Value - blockStartTime; discourseActionList.Add(new SetStoryTime(currentStoryTimeOffset, previousStoryTimeOffset, blockStartTime, blockEndTime)); previousStoryTimeOffset = block.StoryTime.Value; } } cameraActionList.EndDiscourseTime = currentDiscourseTime; }