public void SetState(int index) { if (index < 0 || index >= perso.Perso3dData.Family.states.Count) { return; } stateIndex = index; currentState = index; state = perso.Perso3dData.Family.states[index]; //UpdateViewCollision(controller.viewCollision); // Set animation ushort anim_index = 0; byte bank_index = 0; if (state.anim_ref != null) { anim_index = state.anim_ref.anim_index; bank_index = perso.Perso3dData.Family.animBank; } if (state.anim_ref != null && state.anim_ref.a3d != null) { animationSpeed = state.speed; InitAnimation(state.anim_ref.a3d); UpdateAnimation(); } else { a3d = null; } }
private void SwitchContextToAnimationStateOfIndex(int stateIndex) { State state = family.states[stateIndex]; int animationIndex = state.anim_ref.anim_index; int animationBankIndex = family.animBank; animA3DGeneralForCurrentPersoAnimationState = loader.animationBanks[animationBankIndex].animations[animationIndex]; currentPersoAnimationStateIndex = stateIndex; }
public void SetState(int index) { if (index < 0 || index >= perso.family.states.Length) { return; } stateIndex = index; currentState = index; state = perso.family.states[index]; // Set animation MapLoader l = MapLoader.Loader; ushort anim_index = 0; byte bank_index = 0; if (state.anim_ref != null) { anim_index = state.anim_ref.anim_index; bank_index = perso.family.animBank; } if (state.anim_ref != null && l.animationBanks != null && l.animationBanks.Length > bank_index && l.animationBanks[bank_index] != null && l.animationBanks[bank_index].animations != null && l.animationBanks[bank_index].animations.Length > anim_index && l.animationBanks[bank_index].animations[anim_index] != null) { InitAnimation(l.animationBanks[bank_index].animations[anim_index]); UpdateFrame(currentFrame); } else { a3d = null; } }
protected override void ReadInternal(Reader reader) { if (Settings.s.game == Settings.Game.R2Revolution) { off_a3d = Pointer.Read(reader); reader.ReadUInt32(); off_events = Pointer.Read(reader); reader.ReadUInt32(); reader.ReadUInt32(); reader.ReadUInt32(); num_onlyFrames = reader.ReadUInt16(); speed = reader.ReadByte(); num_channels = reader.ReadByte(); anim_index = reader.ReadUInt16(); num_events = reader.ReadByte(); transition = reader.ReadByte(); } else { if (Settings.s.hasNames) { name = new string(reader.ReadChars(0x50)); } if (Settings.s.engineVersion <= Settings.EngineVersion.TT) { reader.ReadUInt32(); } if (Settings.s.game == Settings.Game.LargoWinch) { off_a3d = Pointer.Read(reader); } num_onlyFrames = reader.ReadUInt16(); speed = reader.ReadByte(); num_channels = reader.ReadByte(); off_events = Pointer.Read(reader); if (Settings.s.engineVersion < Settings.EngineVersion.R3) { x = reader.ReadSingle(); y = reader.ReadSingle(); z = reader.ReadSingle(); } off_morphData = Pointer.Read(reader); // Runtime only? if (Settings.s.engineVersion <= Settings.EngineVersion.TT) { reader.ReadUInt32(); reader.ReadUInt32(); } if (Settings.s.game != Settings.Game.LargoWinch) { anim_index = reader.ReadUInt16(); num_events = reader.ReadByte(); transition = reader.ReadByte(); } else { num_events = reader.ReadByte(); transition = reader.ReadByte(); anim_index = reader.ReadUInt16(); } if (Settings.s.engineVersion == Settings.EngineVersion.R2) { reader.ReadUInt32(); // no idea what this is sadly } if (Settings.s.engineVersion <= Settings.EngineVersion.TT) { off_a3d = Pointer.Read(reader); } } MapLoader l = MapLoader.Loader; if (Settings.s.game == Settings.Game.LargoWinch) { a3dLargo = l.FromOffsetOrRead <AnimA3DLargo>(reader, off_a3d, (a) => { a.num_onlyFrames = num_onlyFrames; a.num_channels = num_channels; }); } else { Pointer.DoAt(ref reader, off_a3d, () => { a3d = l.FromOffsetOrRead <AnimA3DGeneral>(reader, off_a3d, onPreRead: a3d => a3d.readFull = true); }); } }
void InitAnimation(AnimA3DGeneral a3d) { if (a3d != this.a3d || forceAnimUpdate) { forceAnimUpdate = false; DeinitAnimation(); // Init animation this.a3d = a3d; currentFrame = 0; if (a3d != null) { //animationSpeed = a3d.speed; // Init channels & subobjects subObjects = new PhysicalObject[a3d.num_channels][]; channelObjects = new GameObject[a3d.num_channels]; if (a3d.num_morphData > 0) { fullMorphPOs = new Dictionary <ushort, PhysicalObject> [a3d.num_channels]; } currentActivePO = new int[a3d.num_channels]; channelParents = new bool[a3d.num_channels]; for (int i = 0; i < a3d.num_channels; i++) { short id = a3d.channels[a3d.start_channels + i].id; channelObjects[i] = new GameObject("Channel " + id); channelObjects[i].transform.SetParent(perso.gameObject.transform); currentActivePO[i] = -1; AddChannelID(id, i); subObjects[i] = new PhysicalObject[a3d.num_NTTO]; AnimChannel ch = a3d.channels[a3d.start_channels + i]; List <ushort> listOfNTTOforChannel = new List <ushort>(); for (int j = 0; j < a3d.num_onlyFrames; j++) { AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + j]; //print(ch.numOfNTTO + " - " + of.numOfNTTO + " - " + a3d.numOfNTTO.Length); AnimNumOfNTTO numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO]; if (!listOfNTTOforChannel.Contains(numOfNTTO.numOfNTTO)) { listOfNTTOforChannel.Add(numOfNTTO.numOfNTTO); } } for (int k = 0; k < listOfNTTOforChannel.Count; k++) { int j = listOfNTTOforChannel[k] - a3d.start_NTTO; AnimNTTO ntto = a3d.ntto[a3d.start_NTTO + j]; if (ntto.IsInvisibleNTTO) { subObjects[i][j] = new PhysicalObject(); subObjects[i][j].Gao.transform.parent = channelObjects[i].transform; subObjects[i][j].Gao.name = "[" + j + "] Invisible PO"; subObjects[i][j].Gao.SetActive(false); /*GameObject boneVisualisation = new GameObject("Bone vis"); * boneVisualisation.transform.SetParent(subObjects[i][j].Gao.transform); * MeshRenderer mr = boneVisualisation.AddComponent<MeshRenderer>(); * MeshFilter mf = boneVisualisation.AddComponent<MeshFilter>(); * Mesh mesh = Util.CreateBox(0.1f); * mf.mesh = mesh; * boneVisualisation.transform.localScale = Vector3.one / 4f;*/ } else { if (perso.Perso3dData.ObjectList != null && perso.Perso3dData.ObjectList.Count > ntto.object_index) { PhysicalObject o = perso.Perso3dData.ObjectList.entries[ntto.object_index].po; if (o != null) { //if (o.visualSetType == 1) print(name); PhysicalObject c = o.Clone(); subObjects[i][j] = c; subObjects[i][j].Gao.transform.localScale = subObjects[i][j].scaleMultiplier.HasValue ? subObjects[i][j].scaleMultiplier.Value : Vector3.one; c.Gao.transform.parent = channelObjects[i].transform; c.Gao.name = "[" + j + "] " + c.Gao.name; if (Controller.Settings.hasDeformations && c.Bones != null) { hasBones = true; } foreach (VisualSetLOD l in c.visualSet) { if (l.obj != null) { GameObject gao = l.obj.Gao; // TODO: Create gameobjects explicitly? } } c.Gao.SetActive(false); } } } } } if (a3d.num_morphData > 0 && a3d.morphData != null && Controller.Settings.engineVersion < Settings.EngineVersion.R3) { morphDataArray = new AnimMorphData[a3d.num_channels, a3d.num_onlyFrames]; // Iterate over morph data to find the correct channel and keyframe for (int i = 0; i < a3d.num_morphData; i++) { AnimMorphData m = a3d.morphData[a3d.start_morphData + i]; if (m != null) { /*print("F:" + a3d.num_onlyFrames + " - C:" + a3d.num_channels + " - CF" + (a3d.num_onlyFrames * a3d.num_channels) + " - " + * m.channel + " - " + m.frame + " - " + m.morphProgress + " - " + m.objectIndexTo + " - " + m.byte5 + " - " + m.byte6 + " - " + m.byte7);*/ int channelIndex = this.GetChannelByID(m.channel)[0]; if (channelIndex < morphDataArray.GetLength(0) && m.frame < morphDataArray.GetLength(1)) { morphDataArray[channelIndex, m.frame] = m; if (m.morphProgress == 100 && perso.Perso3dData.ObjectList != null && perso.Perso3dData.ObjectList.Count > m.objectIndexTo) { if (fullMorphPOs[channelIndex] == null) { fullMorphPOs[channelIndex] = new Dictionary <ushort, PhysicalObject>(); } if (!fullMorphPOs[channelIndex].ContainsKey(m.objectIndexTo)) { PhysicalObject o = perso.Perso3dData.ObjectList.entries[m.objectIndexTo].po; if (o != null) { PhysicalObject c = o.Clone(); c.Gao.transform.localScale = c.scaleMultiplier.HasValue ? c.scaleMultiplier.Value : Vector3.one; c.Gao.transform.parent = channelObjects[channelIndex].transform; c.Gao.name = "[Morph] " + c.Gao.name; if (Controller.Settings.hasDeformations && c.Bones != null) { hasBones = true; } foreach (VisualSetLOD l in c.visualSet) { if (l.obj != null) { GameObject gao = l.obj.Gao; // TODO: Create gameobjects explicitly? } } c.Gao.SetActive(false); fullMorphPOs[channelIndex][m.objectIndexTo] = c; } } } } } } } else { morphDataArray = null; } // Keep lighting last so that it is applied to all new sub objects /*if (!perso.IsAlways) { * Controller.SectorManager.ApplySectorLighting(sector, gameObject, LightInfo.ObjectLightedFlag.Perso); * } else { * Controller.SectorManager.ApplySectorLighting(sector, gameObject, LightInfo.ObjectLightedFlag.None); * }*/ // TODO: perso lighting } loaded = true; } }
// Update is called once per frame void Update() { if (loaded) { if (hasStates) { if (stateIndex != currentState) { currentState = stateIndex; SetState(currentState); } } if (poListIndex != currentPOList && perso.Perso3dData != null) { if (poListIndex > 0 && poListIndex < perso.Perso3dData.Family.objectLists.Count + 1) { currentPOList = poListIndex; perso.Perso3dData.ObjectList = perso.Perso3dData.Family.objectLists[currentPOList - 1]; } else { poListIndex = 0; currentPOList = 0; perso.Perso3dData.ObjectList = null; } forceAnimUpdate = true; SetState(currentState); } } if (playAnimation) { updateCounter += Time.deltaTime * animationSpeed; // If the camera is not inside a sector, animations will only update 1 out of 2 times (w/ frameskip) to avoid lag uint passedFrames = (uint)Mathf.FloorToInt(updateCounter); updateCounter %= 1; currentFrame += passedFrames; if (a3d != null && currentFrame >= a3d.num_onlyFrames) { if (autoNextState) { AnimA3DGeneral prevAnim = a3d; GotoAutoNextState(); if (a3d == prevAnim) { currentFrame = currentFrame % a3d.num_onlyFrames; UpdateAnimation(); } } else { currentFrame = currentFrame % a3d.num_onlyFrames; UpdateAnimation(); } } else { UpdateAnimation(); } } }
private ChannelInHierarchyInfo GetParentChannelName(short channelId, int animationFrameNumber, AnimA3DGeneral animA3DGeneral) { bool existsAtAll = false; AnimOnlyFrame animOnlyFrame = animA3DGeneral.onlyFrames[animA3DGeneral.start_onlyFrames + animationFrameNumber]; for (int i = animOnlyFrame.start_hierarchies_for_frame; i < animOnlyFrame.start_hierarchies_for_frame + animOnlyFrame.num_hierarchies_for_frame; i++) { AnimHierarchy hierarchy = animA3DGeneral.hierarchies[i]; if (hierarchy.childChannelID == channelId) { return(new ChannelInHierarchyInfo(true, "Channel " + hierarchy.parentChannelID)); } if (hierarchy.childChannelID == channelId || hierarchy.parentChannelID == channelId) { existsAtAll = true; } } return(new ChannelInHierarchyInfo(existsAtAll, null)); }
public AnimA3DGeneralDataManipulationInterface(AnimA3DGeneral animA3DGeneral) { this.animA3DGeneral = animA3DGeneral; }
// A completely separate Read function for the Dreamcast version, since it's so different public static AnimationBank ReadDreamcast(Reader reader, Pointer offset, Pointer off_events_fix, uint num_events_fix) { MapLoader l = MapLoader.Loader; AnimationBank bank = new AnimationBank(offset); bank.a3d_general = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.vectors = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.quaternions = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.hierarchies = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.NTTO = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.onlyFrames = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.channels = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.framesNumOfNTTO = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.framesKFIndex = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.keyframes = new AnimationStack() { off_data = Pointer.Read(reader) }; bank.events = new AnimationStack() { off_data = Pointer.Read(reader), countInFix = num_events_fix }; bank.events.count = bank.events.countInFix + reader.ReadUInt32(); bank.morphData = new AnimationStack() { off_data = Pointer.Read(reader) }; Pointer off_current = Pointer.Current(reader); uint max_a3d_ind = 0, num_vectors = 0, num_quaternions = 0, num_hierarchies = 0, num_NTTO = 0, num_numNTTO = 0, num_channels = 0, num_onlyFrames = 0, num_framesKF = 0, num_keyframes = 0, num_morphData = 0; foreach (State s in l.states) { if (s.anim_ref != null && s.anim_ref.anim_index > max_a3d_ind) { max_a3d_ind = s.anim_ref.anim_index; } } bank.a3d_general.count = max_a3d_ind + 1; bank.animations = l.ReadArray <AnimA3DGeneral>(bank.a3d_general.count, reader, bank.a3d_general.off_data); for (int i = 0; i < bank.a3d_general.count; i++) { AnimA3DGeneral a = bank.animations[i]; if (a.start_vectors + a.num_vectors > num_vectors) { num_vectors = (uint)a.start_vectors + a.num_vectors; } if (a.start_quaternions + a.num_quaternions > num_quaternions) { num_quaternions = (uint)a.start_quaternions + a.num_quaternions; } //if (a.start_hierarchies + a.num_hierarchies > num_hierarchies) num_hierarchies = (uint)a.start_hierarchies + a.num_hierarchies; if (a.start_NTTO + a.num_NTTO > num_NTTO) { num_NTTO = (uint)a.start_NTTO + a.num_NTTO; } if (a.start_onlyFrames + a.num_onlyFrames > num_onlyFrames) { num_onlyFrames = (uint)a.start_onlyFrames + a.num_onlyFrames; } if (a.start_channels + a.num_channels > num_channels) { num_channels = (uint)a.start_channels + a.num_channels; } if (a.start_morphData + a.num_morphData > num_morphData) { num_morphData = (uint)a.start_morphData + a.num_morphData; } } bank.vectors.count = num_vectors; bank.quaternions.count = num_quaternions; bank.NTTO.count = num_NTTO; bank.onlyFrames.count = num_onlyFrames; bank.channels.count = num_channels; bank.morphData.count = num_morphData; bank.global_vectors = l.ReadArray <AnimVector>(bank.vectors.Count(false), reader, bank.vectors.off_data); bank.global_quaternions = l.ReadArray <AnimQuaternion>(bank.quaternions.Count(false), reader, bank.quaternions.off_data); bank.global_NTTO = l.ReadArray <AnimNTTO>(bank.NTTO.Count(false), reader, bank.NTTO.off_data); bank.global_onlyFrames = l.ReadArray <AnimOnlyFrame>(bank.onlyFrames.Count(false), reader, bank.onlyFrames.off_data); bank.global_channels = l.ReadArray <AnimChannel>(bank.channels.Count(false), reader, bank.channels.off_data); AnimEvent[] eventsFix = l.ReadArray <AnimEvent>(num_events_fix, reader, off_events_fix); AnimEvent[] eventsLvl = l.ReadArray <AnimEvent>(bank.events.Count(false) - num_events_fix, reader, bank.events.off_data); bank.global_events = new AnimEvent[bank.events.Count(false)]; Array.Copy(eventsFix, 0, bank.global_events, 0, num_events_fix); Array.Copy(eventsLvl, 0, bank.global_events, num_events_fix, bank.global_events.Length - num_events_fix); bank.global_morphData = l.ReadArray <AnimMorphData>(bank.morphData.Count(false), reader, bank.morphData.off_data); for (int i = 0; i < bank.a3d_general.count; i++) { AnimA3DGeneral a = bank.animations[i]; for (int j = a.start_channels; j < a.start_channels + a.num_channels; j++) { AnimChannel ch = bank.global_channels[j]; if (ch.framesKF + a.num_onlyFrames > num_framesKF) { num_framesKF = (uint)ch.framesKF + a.num_onlyFrames; } for (int k = a.start_onlyFrames; k < a.start_onlyFrames + a.num_onlyFrames; k++) { AnimOnlyFrame of = bank.global_onlyFrames[k]; if (ch.numOfNTTO + of.numOfNTTO + 1 > num_numNTTO) { num_numNTTO = (uint)ch.numOfNTTO + of.numOfNTTO + 1; } } } for (int k = a.start_onlyFrames; k < a.start_onlyFrames + a.num_onlyFrames; k++) { AnimOnlyFrame of = bank.global_onlyFrames[k]; if (of.start_hierarchies_for_frame + of.num_hierarchies_for_frame > num_hierarchies) { num_hierarchies = (uint)of.start_hierarchies_for_frame + of.num_hierarchies_for_frame; } } } bank.hierarchies.count = num_hierarchies; bank.framesNumOfNTTO.count = num_numNTTO; bank.framesKFIndex.count = num_framesKF; bank.global_hierarchies = l.ReadArray <AnimHierarchy>(bank.hierarchies.Count(false), reader, bank.hierarchies.off_data); bank.global_numOfNTTO = l.ReadArray <AnimNumOfNTTO>(bank.framesNumOfNTTO.Count(false), reader, bank.framesNumOfNTTO.off_data); bank.global_framesKFIndex = l.ReadArray <AnimFramesKFIndex>(bank.framesKFIndex.Count(false), reader, bank.framesKFIndex.off_data); for (uint j = 0; j < bank.global_framesKFIndex.Length; j++) { if (bank.global_framesKFIndex[j].kf + 1 > num_keyframes) { num_keyframes = bank.global_framesKFIndex[j].kf + 1; } } bank.keyframes.count = num_keyframes; bank.global_keyframes = l.ReadArray <AnimKeyframe>(bank.keyframes.Count(false), reader, bank.keyframes.off_data); Pointer.Goto(ref reader, off_current); for (uint j = 0; j < bank.animations.Length; j++) { bank.animations[j].vectors = bank.global_vectors; bank.animations[j].quaternions = bank.global_quaternions; bank.animations[j].hierarchies = bank.global_hierarchies; bank.animations[j].ntto = bank.global_NTTO; bank.animations[j].onlyFrames = bank.global_onlyFrames; bank.animations[j].channels = bank.global_channels; bank.animations[j].numOfNTTO = bank.global_numOfNTTO; bank.animations[j].framesKFIndex = bank.global_framesKFIndex; bank.animations[j].keyframes = bank.global_keyframes; bank.animations[j].events = bank.global_events; bank.animations[j].morphData = bank.global_morphData; bank.animations[j].deformations = bank.global_deformations; } return(bank); }
void InitAnimation(AnimA3DGeneral a3d) { if (a3d != this.a3d) { loaded = false; // Destroy currently loaded subobjects if (subObjects != null) { for (int i = 0; i < subObjects.Length; i++) { if (subObjects[i] == null) { continue; } for (int j = 0; j < subObjects[i].Length; j++) { if (subObjects[i][j] != null) { subObjects[i][j].Destroy(); } } } subObjects = null; } if (channelObjects != null) { for (int i = 0; i < channelObjects.Length; i++) { if (channelObjects[i] != null) { Destroy(channelObjects[i]); } } channelObjects = null; } channelIDDictionary.Clear(); // Init animation this.a3d = a3d; currentFrame = 0; if (a3d != null) { // Init channels & subobjects subObjects = new PhysicalObject[a3d.num_channels][]; channelObjects = new GameObject[a3d.num_channels]; for (int i = 0; i < a3d.num_channels; i++) { short id = a3d.channels[a3d.start_channels + i].id; channelObjects[i] = new GameObject("Channel " + id); channelObjects[i].transform.SetParent(perso.Gao.transform); AddChannelID(id, i); subObjects[i] = new PhysicalObject[a3d.num_NTTO]; AnimChannel ch = a3d.channels[a3d.start_channels + i]; List <ushort> listOfNTTOforChannel = new List <ushort>(); for (int j = 0; j < a3d.num_onlyFrames; j++) { AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + j]; AnimNumOfNTTO numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO]; if (!listOfNTTOforChannel.Contains(numOfNTTO.numOfNTTO)) { listOfNTTOforChannel.Add(numOfNTTO.numOfNTTO); } } for (int k = 0; k < listOfNTTOforChannel.Count; k++) { int j = listOfNTTOforChannel[k] - a3d.start_NTTO; AnimNTTO ntto = a3d.ntto[a3d.start_NTTO + j]; if (ntto.IsInvisibleNTTO) { subObjects[i][j] = new PhysicalObject(null); subObjects[i][j].Gao.transform.parent = channelObjects[i].transform; subObjects[i][j].Gao.name = "[" + j + "] Invisible PO"; subObjects[i][j].Gao.SetActive(false); /*GameObject boneVisualisation = new GameObject("Bone vis"); * boneVisualisation.transform.SetParent(subObjects[i][j].Gao.transform); * MeshRenderer mr = boneVisualisation.AddComponent<MeshRenderer>(); * MeshFilter mf = boneVisualisation.AddComponent<MeshFilter>(); * Mesh mesh = Util.CreateBox(0.1f); * mf.mesh = mesh; * boneVisualisation.transform.localScale = Vector3.one / 4f;*/ } else { if (perso.physical_objects != null && perso.physical_objects.Length > ntto.object_index) { PhysicalObject o = perso.physical_objects[ntto.object_index]; if (o != null) { PhysicalObject c = o.Clone(); subObjects[i][j] = c; c.Gao.transform.parent = channelObjects[i].transform; c.Gao.name = "[" + j + "] " + c.Gao.name; c.Gao.SetActive(false); } } } } } } loaded = true; } }
public static AnimationBank[] Read(EndianBinaryReader reader, Pointer offset, uint index, uint num_banks, bool append = false) { MapLoader l = MapLoader.Loader; AnimationBank[] banks = new AnimationBank[num_banks]; for (int i = 0; i < num_banks; i++) { // In R3, each animation bank is of size 0x104 = 13 times a stack description of 5 uint32s. banks[i] = new AnimationBank(Pointer.Current(reader)); banks[i].a3d_general = AnimationStack.Read(reader); banks[i].vectors = AnimationStack.Read(reader); banks[i].quaternions = AnimationStack.Read(reader); banks[i].hierarchies = AnimationStack.Read(reader); banks[i].NTTO = AnimationStack.Read(reader); banks[i].onlyFrames = AnimationStack.Read(reader); banks[i].channels = AnimationStack.Read(reader); banks[i].framesNumOfNTTO = AnimationStack.Read(reader); banks[i].framesKFIndex = AnimationStack.Read(reader); banks[i].keyframes = AnimationStack.Read(reader); banks[i].events = AnimationStack.Read(reader); banks[i].morphData = AnimationStack.Read(reader); if (l.mode != MapLoader.Mode.Rayman2PC) { banks[i].deformations = AnimationStack.Read(reader); } else { banks[i].deformations = null; } banks[i].animations = new AnimA3DGeneral[banks[i].a3d_general.count]; } if (l.mode == MapLoader.Mode.Rayman3PC || (l.mode == MapLoader.Mode.Rayman2PC && !append)) { for (int i = 0; i < num_banks; i++) { if (banks[i].a3d_general.reservedMemory > 0) { banks[i].a3d_general.off_data = Pointer.Read(reader); } if (banks[i].vectors.reservedMemory > 0) { banks[i].vectors.off_data = Pointer.Read(reader); } if (banks[i].quaternions.reservedMemory > 0) { banks[i].quaternions.off_data = Pointer.Read(reader); } if (banks[i].hierarchies.reservedMemory > 0) { banks[i].hierarchies.off_data = Pointer.Read(reader); } if (banks[i].NTTO.reservedMemory > 0) { banks[i].NTTO.off_data = Pointer.Read(reader); } if (banks[i].onlyFrames.reservedMemory > 0) { banks[i].onlyFrames.off_data = Pointer.Read(reader); } if (banks[i].channels.reservedMemory > 0) { banks[i].channels.off_data = Pointer.Read(reader); } if (banks[i].framesNumOfNTTO.reservedMemory > 0) { banks[i].framesNumOfNTTO.off_data = Pointer.Read(reader); } if (banks[i].framesKFIndex.reservedMemory > 0) { banks[i].framesKFIndex.off_data = Pointer.Read(reader); } if (banks[i].keyframes.reservedMemory > 0) { banks[i].keyframes.off_data = Pointer.Read(reader); } if (banks[i].events.reservedMemory > 0) { banks[i].events.off_data = Pointer.Read(reader); } if (banks[i].morphData.reservedMemory > 0) { banks[i].morphData.off_data = Pointer.Read(reader); } if (l.mode != MapLoader.Mode.Rayman2PC && banks[i].deformations.reservedMemory > 0) { banks[i].deformations.off_data = Pointer.Read(reader); } } } Pointer off_current = Pointer.Current(reader); Pointer off_a3d = null; uint num_a3d = (uint)banks.Sum(b => b.a3d_general.count); FileFormat.FileWithPointers kfFile = null; if (index == 0 && l.files_array[MapLoader.Mem.FixKeyFrames] != null) { kfFile = MapLoader.Loader.files_array[MapLoader.Mem.FixKeyFrames]; } if (index > 0 && l.files_array[MapLoader.Mem.LvlKeyFrames] != null) { kfFile = MapLoader.Loader.files_array[MapLoader.Mem.LvlKeyFrames]; } if (kfFile != null && l.mode == MapLoader.Mode.Rayman3GC) { kfFile.GotoHeader(); reader = kfFile.reader; uint[] a3d_sizes = new uint[num_a3d]; for (uint i = 0; i < num_a3d; i++) { a3d_sizes[i] = reader.ReadUInt32(); } off_a3d = Pointer.Current(reader); uint current_anim = 0; for (uint i = 0; i < banks.Length; i++) { uint num_a3d_in_bank = banks[i].a3d_general.count; for (uint j = 0; j < num_a3d_in_bank; j++) { Pointer.Goto(ref reader, off_a3d); // Read animation data here banks[i].animations[j] = AnimA3DGeneral.Read(reader, off_a3d); AnimA3DGeneral a = banks[i].animations[j]; a.vectors = new AnimVector[a.num_vectors]; a.quaternions = new AnimQuaternion[a.num_quaternions]; a.hierarchies = new AnimHierarchy[a.num_hierarchies]; a.ntto = new AnimNTTO[a.num_NTTO]; a.onlyFrames = new AnimOnlyFrame[a.num_onlyFrames]; a.channels = new AnimChannel[a.num_channels]; a.numOfNTTO = new AnimNumOfNTTO[a.num_numNTTO * a.num_channels]; a.framesKFIndex = new AnimFramesKFIndex[a.num_onlyFrames * a.num_channels]; a.keyframes = new AnimKeyframe[a.num_keyframes]; a.events = new AnimEvent[a.num_events]; a.morphData = new AnimMorphData[a.num_morphData]; a.deformations = new AnimDeformation[a.num_deformations]; for (uint k = 0; k < a.vectors.Length; k++) { a.vectors[k] = AnimVector.Read(reader); } for (uint k = 0; k < a.quaternions.Length; k++) { a.quaternions[k] = AnimQuaternion.Read(reader); } for (uint k = 0; k < a.hierarchies.Length; k++) { a.hierarchies[k] = AnimHierarchy.Read(reader); } for (uint k = 0; k < a.ntto.Length; k++) { a.ntto[k] = AnimNTTO.Read(reader); } for (uint k = 0; k < a.onlyFrames.Length; k++) { a.onlyFrames[k] = AnimOnlyFrame.Read(reader); } reader.Align(4); for (uint k = 0; k < a.channels.Length; k++) { a.channels[k] = AnimChannel.Read(reader); } for (uint k = 0; k < a.numOfNTTO.Length; k++) { a.numOfNTTO[k] = AnimNumOfNTTO.Read(reader); } reader.Align(4); for (uint k = 0; k < a.framesKFIndex.Length; k++) { a.framesKFIndex[k] = AnimFramesKFIndex.Read(reader); } for (uint k = 0; k < a.keyframes.Length; k++) { a.keyframes[k] = AnimKeyframe.Read(reader); } reader.Align(4); for (uint k = 0; k < a.events.Length; k++) { a.events[k] = AnimEvent.Read(reader); } for (uint k = 0; k < a.morphData.Length; k++) { a.morphData[k] = AnimMorphData.Read(reader); } reader.Align(4); for (uint k = 0; k < a.deformations.Length; k++) { a.deformations[k] = AnimDeformation.Read(reader); } off_a3d += a3d_sizes[current_anim]; // Check if read correctly Pointer off_postAnim = Pointer.Current(reader); if (off_postAnim != off_a3d) { l.print("Animation block size does not match data size: " + "Current offset: " + off_postAnim + " - Expected offset: " + off_a3d + " - Block start: " + (off_a3d + -(int)(a3d_sizes[current_anim]))); } current_anim++; } } } else if (kfFile == null && (l.mode == MapLoader.Mode.Rayman3PC || l.mode == MapLoader.Mode.Rayman2PC)) { bool readArraysDirectly = l.mode == MapLoader.Mode.Rayman2PC && index == 0; for (uint i = 0; i < banks.Length; i++) { banks[i].animations = new AnimA3DGeneral[banks[i].a3d_general.Count(append)]; banks[i].global_vectors = new AnimVector[banks[i].vectors.Count(append)]; banks[i].global_quaternions = new AnimQuaternion[banks[i].quaternions.Count(append)]; banks[i].global_hierarchies = new AnimHierarchy[banks[i].hierarchies.Count(append)]; banks[i].global_NTTO = new AnimNTTO[banks[i].NTTO.Count(append)]; banks[i].global_onlyFrames = new AnimOnlyFrame[banks[i].onlyFrames.Count(append)]; banks[i].global_channels = new AnimChannel[banks[i].channels.Count(append)]; banks[i].global_numOfNTTO = new AnimNumOfNTTO[banks[i].framesNumOfNTTO.Count(append)]; banks[i].global_framesKFIndex = new AnimFramesKFIndex[banks[i].framesKFIndex.Count(append)]; banks[i].global_keyframes = new AnimKeyframe[banks[i].keyframes.Count(append)]; banks[i].global_events = new AnimEvent[banks[i].events.Count(append)]; banks[i].global_morphData = new AnimMorphData[banks[i].morphData.Count(append)]; if (l.mode != MapLoader.Mode.Rayman2PC) { banks[i].global_deformations = new AnimDeformation[banks[i].deformations.Count(append)]; } if (banks[i].animations.Length > 0) { if (banks[i].a3d_general.off_data != null) { Pointer.Goto(ref reader, banks[i].a3d_general.off_data); } for (uint j = 0; j < banks[i].animations.Length; j++) { banks[i].animations[j] = AnimA3DGeneral.Read(reader, Pointer.Current(reader)); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(56 * banks[i].animations.Length, 4); } } if (banks[i].global_vectors.Length > 0) { if (banks[i].vectors.off_data != null) { Pointer.Goto(ref reader, banks[i].vectors.off_data); } for (uint j = 0; j < banks[i].global_vectors.Length; j++) { banks[i].global_vectors[j] = AnimVector.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(12 * banks[i].global_vectors.Length, 4); } } if (banks[i].global_quaternions.Length > 0) { if (banks[i].quaternions.off_data != null) { Pointer.Goto(ref reader, banks[i].quaternions.off_data); } for (uint j = 0; j < banks[i].global_quaternions.Length; j++) { banks[i].global_quaternions[j] = AnimQuaternion.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(8 * banks[i].global_quaternions.Length, 4); } } if (banks[i].global_hierarchies.Length > 0) { if (banks[i].hierarchies.off_data != null) { Pointer.Goto(ref reader, banks[i].hierarchies.off_data); } for (uint j = 0; j < banks[i].global_hierarchies.Length; j++) { banks[i].global_hierarchies[j] = AnimHierarchy.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(4 * banks[i].global_hierarchies.Length, 4); } } if (banks[i].global_NTTO.Length > 0) { if (banks[i].NTTO.off_data != null) { Pointer.Goto(ref reader, banks[i].NTTO.off_data); } for (uint j = 0; j < banks[i].global_NTTO.Length; j++) { banks[i].global_NTTO[j] = AnimNTTO.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(6 * banks[i].global_NTTO.Length, 4); } } if (banks[i].global_onlyFrames.Length > 0) { if (banks[i].onlyFrames.off_data != null) { Pointer.Goto(ref reader, banks[i].onlyFrames.off_data); } for (uint j = 0; j < banks[i].global_onlyFrames.Length; j++) { banks[i].global_onlyFrames[j] = AnimOnlyFrame.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(10 * banks[i].global_onlyFrames.Length, 4); } } if (banks[i].global_channels.Length > 0) { if (banks[i].channels.off_data != null) { Pointer.Goto(ref reader, banks[i].channels.off_data); } for (uint j = 0; j < banks[i].global_channels.Length; j++) { banks[i].global_channels[j] = AnimChannel.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(16 * banks[i].global_channels.Length, 4); } } if (banks[i].global_numOfNTTO.Length > 0) { if (banks[i].framesNumOfNTTO.off_data != null) { Pointer.Goto(ref reader, banks[i].framesNumOfNTTO.off_data); } for (uint j = 0; j < banks[i].global_numOfNTTO.Length; j++) { banks[i].global_numOfNTTO[j] = AnimNumOfNTTO.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(2 * banks[i].global_numOfNTTO.Length, 4); } } if (banks[i].global_framesKFIndex.Length > 0) { if (banks[i].framesKFIndex.off_data != null) { Pointer.Goto(ref reader, banks[i].framesKFIndex.off_data); } for (uint j = 0; j < banks[i].global_framesKFIndex.Length; j++) { banks[i].global_framesKFIndex[j] = AnimFramesKFIndex.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(4 * banks[i].global_framesKFIndex.Length, 4); } } if (banks[i].global_keyframes.Length > 0) { if (banks[i].keyframes.off_data != null) { Pointer.Goto(ref reader, banks[i].keyframes.off_data); } for (uint j = 0; j < banks[i].global_keyframes.Length; j++) { banks[i].global_keyframes[j] = AnimKeyframe.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(36 * banks[i].global_keyframes.Length, 4); } } if (banks[i].global_events.Length > 0) { if (banks[i].events.off_data != null) { Pointer.Goto(ref reader, banks[i].events.off_data); } for (uint j = 0; j < banks[i].global_events.Length; j++) { banks[i].global_events[j] = AnimEvent.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(12 * banks[i].global_events.Length, 4); } } if (banks[i].global_morphData.Length > 0) { if (banks[i].morphData.off_data != null) { Pointer.Goto(ref reader, banks[i].morphData.off_data); } for (uint j = 0; j < banks[i].global_morphData.Length; j++) { banks[i].global_morphData[j] = AnimMorphData.Read(reader); } if (l.mode == MapLoader.Mode.Rayman2PC) { reader.PreAlign(8 * banks[i].global_morphData.Length, 4); } } if (banks[i].global_deformations != null && banks[i].global_deformations.Length > 0) { if (banks[i].deformations.off_data != null) { Pointer.Goto(ref reader, banks[i].deformations.off_data); } for (uint j = 0; j < banks[i].global_deformations.Length; j++) { banks[i].global_deformations[j] = AnimDeformation.Read(reader); } } if (append) { AnimationBank b = l.animationBanks[index + i]; b.a3d_general = banks[i].a3d_general; b.vectors = banks[i].vectors; b.quaternions = banks[i].quaternions; b.hierarchies = banks[i].hierarchies; b.NTTO = banks[i].NTTO; b.onlyFrames = banks[i].onlyFrames; b.channels = banks[i].channels; b.framesNumOfNTTO = banks[i].framesNumOfNTTO; b.framesKFIndex = banks[i].framesKFIndex; b.keyframes = banks[i].keyframes; b.events = banks[i].events; b.morphData = banks[i].morphData; b.deformations = banks[i].deformations; //Util.AppendArray(ref b.animations, ref banks[i].animations); Util.AppendArrayAndMergeReferences(ref b.global_vectors, ref banks[i].global_vectors, (int)banks[i].vectors.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_quaternions, ref banks[i].global_quaternions, (int)banks[i].quaternions.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_hierarchies, ref banks[i].global_hierarchies, (int)banks[i].hierarchies.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_NTTO, ref banks[i].global_NTTO, (int)banks[i].NTTO.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_onlyFrames, ref banks[i].global_onlyFrames, (int)banks[i].onlyFrames.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_channels, ref banks[i].global_channels, (int)banks[i].channels.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_numOfNTTO, ref banks[i].global_numOfNTTO, (int)banks[i].framesNumOfNTTO.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_framesKFIndex, ref banks[i].global_framesKFIndex, (int)banks[i].framesKFIndex.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_keyframes, ref banks[i].global_keyframes, (int)banks[i].keyframes.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_events, ref banks[i].global_events, (int)banks[i].events.countInFix); Util.AppendArrayAndMergeReferences(ref b.global_morphData, ref banks[i].global_morphData, (int)banks[i].morphData.countInFix); if (banks[i].deformations != null) { Util.AppendArrayAndMergeReferences(ref b.global_deformations, ref banks[i].global_deformations, (int)banks[i].deformations.countInFix); } /*Array.Resize(ref b.animations, b.animations.Length + banks[i].animations.Length); * Array.Resize(ref b.global_vectors, b.global_vectors.Length + banks[i].global_vectors.Length); * Array.Resize(ref b.global_quaternions, b.global_quaternions.Length + banks[i].global_quaternions.Length); * Array.Resize(ref b.global_hierarchies, b.global_hierarchies.Length + banks[i].global_hierarchies.Length); * Array.Resize(ref b.global_NTTO, b.global_NTTO.Length + banks[i].global_NTTO.Length); * Array.Resize(ref b.global_onlyFrames, b.global_onlyFrames.Length + banks[i].global_onlyFrames.Length); * Array.Resize(ref b.global_channels, b.global_channels.Length + banks[i].global_channels.Length); * Array.Resize(ref b.global_numOfNTTO, b.global_numOfNTTO.Length + banks[i].global_numOfNTTO.Length); * Array.Resize(ref b.global_framesKFIndex, b.global_framesKFIndex.Length + banks[i].global_framesKFIndex.Length); * Array.Resize(ref b.global_keyframes, b.global_keyframes.Length + banks[i].global_keyframes.Length); * Array.Resize(ref b.global_events, b.global_events.Length + banks[i].global_events.Length); * Array.Resize(ref b.global_morphData, b.global_morphData.Length + banks[i].global_morphData.Length); * if (banks[i].deformations != null) Array.Resize(ref b.global_deformations, b.global_deformations.Length + banks[i].global_deformations.Length); * Array.Copy(banks[i].global_vectors, 0, b.global_vectors, banks[i].vectors.countInFix, banks[i].global_vectors.Length); * Array.Copy(banks[i].global_quaternions, 0, b.global_quaternions, banks[i].quaternions.countInFix, banks[i].global_quaternions.Length); * Array.Copy(banks[i].global_hierarchies, 0, b.global_hierarchies, banks[i].hierarchies.countInFix, banks[i].global_hierarchies.Length); * Array.Copy(banks[i].global_NTTO, 0, b.global_NTTO, banks[i].NTTO.countInFix, banks[i].global_NTTO.Length); * Array.Copy(banks[i].global_onlyFrames, 0, b.global_onlyFrames, banks[i].onlyFrames.countInFix, banks[i].global_onlyFrames.Length); * Array.Copy(banks[i].global_channels, 0, b.global_channels, banks[i].channels.countInFix, banks[i].global_channels.Length); * Array.Copy(banks[i].global_numOfNTTO, 0, b.global_numOfNTTO, banks[i].framesNumOfNTTO.countInFix, banks[i].global_numOfNTTO.Length); * Array.Copy(banks[i].global_framesKFIndex, 0, b.global_framesKFIndex, banks[i].framesKFIndex.countInFix, banks[i].global_framesKFIndex.Length); * Array.Copy(banks[i].global_keyframes, 0, b.global_keyframes, banks[i].keyframes.countInFix, banks[i].global_keyframes.Length); * Array.Copy(banks[i].global_events, 0, b.global_events, banks[i].events.countInFix, banks[i].global_events.Length); * Array.Copy(banks[i].global_morphData, 0, b.global_morphData, banks[i].morphData.countInFix, banks[i].global_morphData.Length); * if (banks[i].deformations != null) Array.Copy(banks[i].global_deformations, 0, b.global_deformations, banks[i].deformations.countInFix, banks[i].global_deformations.Length);*/ } if (banks[i].animations.Length > 0) { AnimationBank srcBank = append ? l.animationBanks[index + i] : banks[i]; for (uint j = 0; j < banks[i].animations.Length; j++) { banks[i].animations[j].vectors = srcBank.global_vectors; banks[i].animations[j].quaternions = srcBank.global_quaternions; banks[i].animations[j].hierarchies = srcBank.global_hierarchies; banks[i].animations[j].ntto = srcBank.global_NTTO; banks[i].animations[j].onlyFrames = srcBank.global_onlyFrames; banks[i].animations[j].channels = srcBank.global_channels; banks[i].animations[j].numOfNTTO = srcBank.global_numOfNTTO; banks[i].animations[j].framesKFIndex = srcBank.global_framesKFIndex; banks[i].animations[j].keyframes = srcBank.global_keyframes; banks[i].animations[j].events = srcBank.global_events; banks[i].animations[j].morphData = srcBank.global_morphData; banks[i].animations[j].deformations = srcBank.global_deformations; } } if (append) { Util.AppendArrayAndMergeReferences(ref l.animationBanks[index + i].animations, ref banks[i].animations, (int)banks[i].a3d_general.countInFix); } } } Pointer.Goto(ref reader, off_current); return(banks); }
public void ReadData() { if (!dataParsed) { dataParsed = true; if (data != null && data.Length > 0) { //Util.ByteArrayToFile(MapLoader.Loader.gameDataBinFolder + "exported_anims/anim_" + index + ".bin", data); using (MemoryStream ms = new MemoryStream(data)) { using (Reader r = new Reader(ms, Settings.s.IsLittleEndian)) { a3d = new AnimA3DGeneral(r); vectors = new AnimVector[a3d.num_vectors]; quaternions = new AnimQuaternion[a3d.num_quaternions]; hierarchies = new AnimHierarchy[a3d.num_hierarchies]; ntto = new AnimNTTO[a3d.num_NTTO]; onlyFrames = new AnimOnlyFrame[a3d.this_num_onlyFrames - a3d.this_start_onlyFrames]; channels = new AnimChannel[a3d.num_channels]; numOfNTTO = new AnimNumOfNTTO[a3d.num_channels * a3d.num_numNTTO]; keyframes = new AnimKeyframe[a3d.num_keyframes]; events = new AnimEvent[a3d.num_events]; morphData = new AnimMorphData[a3d.num_morphData]; for (int i = 0; i < vectors.Length; i++) { vectors[i] = new AnimVector(r); } for (int i = 0; i < quaternions.Length; i++) { quaternions[i] = new AnimQuaternion(r); } for (int i = 0; i < hierarchies.Length; i++) { hierarchies[i] = new AnimHierarchy(r); } for (int i = 0; i < ntto.Length; i++) { ntto[i] = new AnimNTTO(r); } for (int i = 0; i < onlyFrames.Length; i++) { onlyFrames[i] = new AnimOnlyFrame(r); } for (int i = 0; i < channels.Length; i++) { channels[i] = new AnimChannel(r); } for (int i = 0; i < numOfNTTO.Length; i++) { numOfNTTO[i] = new AnimNumOfNTTO(r); } for (int i = 0; i < keyframes.Length; i++) { keyframes[i] = new AnimKeyframe(r); } r.Align(4); for (int i = 0; i < events.Length; i++) { events[i] = new AnimEvent(r); } for (int i = 0; i < morphData.Length; i++) { morphData[i] = new AnimMorphData(r); } if (r.BaseStream.Position != r.BaseStream.Length) { MapLoader.Loader.print("Animation " + index + ": bad read"); } } } } } }