private void AddAction(GameObject go, DFBlock blockData, DFBlock.RdbObject obj, int modelReference) { // Get model action record and description DFBlock.RdbActionResource action = obj.Resources.ModelResource.ActionResource; string description = blockData.RdbBlock.ModelReferenceList[modelReference].Description; // Check for known action types Vector3 actionRotation = Vector3.zero; Vector3 actionTranslation = Vector3.zero; if ((action.Flags & (int)DFBlock.RdbActionFlags.Rotation) == (int)DFBlock.RdbActionFlags.Rotation) { actionRotation = (GetActionVector(ref action) / BlocksFile.RotationDivisor); } if ((action.Flags & (int)DFBlock.RdbActionFlags.Translation) == (int)DFBlock.RdbActionFlags.Translation) { actionTranslation = GetActionVector(ref action) * MeshReader.GlobalScale; } // A quick hack to fix special-case rotation issues. // Currently unknown if there is data indicating different rotation behaviour or if something else is happening. switch (description) { case "LID": actionRotation = new Vector3(0, 0, -90f); // Coffin lids in Scourg barrow break; case "WHE": actionRotation = new Vector3(0, -360f, 0); // Wheels in Direnni Tower break; } // Create action component DaggerfallAction c = go.AddComponent <DaggerfallAction>(); c.ActionEnabled = true; c.ModelDescription = description; c.ActionRotation = actionRotation; c.ActionTranslation = actionTranslation; c.ActionSoundID = obj.Resources.ModelResource.SoundId; // Set duration in seconds // Not sure what timescale native value represents // Using 1/20 of native value in seconds c.ActionDuration = (float)action.Duration / 20f; c.ActionFlags = action.Flags; // Create action links ActionLink link; link.gameObject = go; link.nextKey = GetActionKey(groupIndex, action.NextObjectIndex); link.prevKey = GetActionKey(groupIndex, action.PreviousObjectIndex); actionLinkDict.Add(GetActionKey(groupIndex, obj.Index), link); // Add sound AddActionAudioSource(go, (uint)c.ActionSoundID); return; }
/// <summary> /// Check is model has action record. /// </summary> private static bool HasAction(DFBlock.RdbObject obj) { DFBlock.RdbActionResource action = obj.Resources.ModelResource.ActionResource; if (action.Flags != 0) { return(true); } return(false); }
private static bool HasAction(DFBlock blockData, DFBlock.RdbObject obj, int modelReference) { // Allow for known action types DFBlock.RdbActionResource action = obj.Resources.ModelResource.ActionResource; if (action.Flags != 0) { return(true); } return(false); }
/// <summary> /// Constructs a Vector3 from magnitude and direction in RDB action resource. /// </summary> private static Vector3 GetActionVector(ref DFBlock.RdbActionResource resource) { Vector3 vector = Vector3.zero; float magnitude = resource.Magnitude; switch (resource.Axis) { case DFBlock.RdbActionAxes.NegativeX: vector.x = -magnitude; break; case DFBlock.RdbActionAxes.NegativeY: vector.y = -magnitude; break; case DFBlock.RdbActionAxes.NegativeZ: vector.z = -magnitude; break; case DFBlock.RdbActionAxes.PositiveX: vector.x = magnitude; break; case DFBlock.RdbActionAxes.PositiveY: vector.y = magnitude; break; case DFBlock.RdbActionAxes.PositiveZ: vector.z = magnitude; break; default: magnitude = 0f; break; } return(vector); }
/// <summary> /// Prepares an action record for use. /// </summary> /// <param name="action">DFBlock.RdbActionResource</param> /// <param name="modelNode">ModelNode</param> /// <param name="description">Description of model.</param> /// <param name="groupIndex">RDB group index.</param> /// <param name="modelIndex">RDB model index.</param> private void CreateModelAction(DFBlock.RdbActionResource action, ModelNode modelNode, string description, int groupIndex, int modelIndex) { // Store description in action node modelNode.Action.ModelDescription = description; // Handle special case actions. These are models like doors, which // do not have an action record, or the coffin lids in Scourg Barrow, // which do not use their action data at all. switch (description) { case "DOR": // Door case "DDR": // Double-door action.ActionType = DFBlock.RdbActionType.Rotation; action.Axis = DFBlock.RdbActionAxes.PositiveY; action.Magnitude = 512; action.Duration = 60; break; case "WHE": // Wheel action.Axis = DFBlock.RdbActionAxes.PositiveY; action.Magnitude = 2000; action.Duration = 67; break; case "LID": // Coffin lid in Scourg Barrow action.Axis = DFBlock.RdbActionAxes.NegativeZ; action.Magnitude = 512; action.Duration = 80; break; default: // Let everything else be handled as per action record break; } // Create action record for this model from Daggerfall's action record. // Only rotation and translation are supported at this time. switch (action.ActionType) { case DFBlock.RdbActionType.None: modelNode.Action.Enabled = false; return; case DFBlock.RdbActionType.Rotation: modelNode.Action.Rotation = GetActionVector(ref action); modelNode.Action.Rotation.X = -MathHelper.ToRadians(modelNode.Action.Rotation.X / rotationDivisor); modelNode.Action.Rotation.Y = MathHelper.ToRadians(modelNode.Action.Rotation.Y / rotationDivisor); modelNode.Action.Rotation.Z = MathHelper.ToRadians(modelNode.Action.Rotation.Z / rotationDivisor); break; case DFBlock.RdbActionType.Translation: modelNode.Action.Translation = GetActionVector(ref action); break; default: // Unsupported action type modelNode.Action.Enabled = false; return; } // Set duration. // Not really sure of the correct unit - definitely not milliseconds. // Using n/60ths of a second for now, which seems pretty close. modelNode.Action.Duration = (long)(1000f * (action.Duration / 60f)); // Enable action modelNode.Action.Enabled = true; // Create action links ActionLink link; link.node = modelNode; link.nextKey = GetActionKey(groupIndex, action.NextObjectIndex); link.prevKey = GetActionKey(groupIndex, action.PreviousObjectIndex); actionLinkDict.Add(GetActionKey(groupIndex, modelIndex), link); }