void UpdateAnimation() { if (loaded && a3d != null && channelObjects != null & subObjects != null) { if (currentFrame >= a3d.num_onlyFrames) { currentFrame %= a3d.num_onlyFrames; } // First pass: reset TRS for all sub objects for (int i = 0; i < channelParents.Length; i++) { channelParents[i] = false; } AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + currentFrame]; // Create hierarchy for this frame for (int i = of.start_hierarchies_for_frame; i < of.start_hierarchies_for_frame + of.num_hierarchies_for_frame; i++) { AnimHierarchy h = a3d.hierarchies[i]; if (Controller.Settings.engineVersion <= Settings.EngineVersion.TT) { channelObjects[h.childChannelID].transform.SetParent(channelObjects[h.parentChannelID].transform); channelParents[h.childChannelID] = true; } else { if (!channelIDDictionary.ContainsKey(h.childChannelID) || !channelIDDictionary.ContainsKey(h.parentChannelID)) { continue; } List <int> ch_child_list = GetChannelByID(h.childChannelID); List <int> ch_parent_list = GetChannelByID(h.parentChannelID); foreach (int ch_child in ch_child_list) { foreach (int ch_parent in ch_parent_list) { channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform); channelParents[ch_child] = true; } } } //channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform); } // Final pass for (int i = 0; i < a3d.num_channels; i++) { AnimChannel ch = a3d.channels[a3d.start_channels + i]; AnimFramesKFIndex kfi = a3d.framesKFIndex[currentFrame + ch.framesKF]; AnimKeyframe kf = a3d.keyframes[kfi.kf]; AnimVector pos = a3d.vectors[kf.positionVector]; AnimQuaternion qua = a3d.quaternions[kf.quaternion]; AnimVector scl = a3d.vectors[kf.scaleVector]; AnimNumOfNTTO numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO]; AnimNTTO ntto = a3d.ntto[numOfNTTO.numOfNTTO]; //if (ntto.IsBoneNTTO) continue; int poNum = numOfNTTO.numOfNTTO - a3d.start_NTTO; PhysicalObject physicalObject = subObjects[i][poNum]; Vector3 vector = pos.vector; Quaternion quaternion = qua.quaternion; Vector3 scale = scl.vector; int framesSinceKF = (int)currentFrame - (int)kf.frame; AnimKeyframe nextKF = null; int framesDifference; float interpolation; if (kf.IsEndKeyframe) { AnimFramesKFIndex next_kfi = a3d.framesKFIndex[0 + ch.framesKF]; nextKF = a3d.keyframes[next_kfi.kf]; framesDifference = a3d.num_onlyFrames - 1 + (int)nextKF.frame - (int)kf.frame; if (framesDifference == 0) { interpolation = 0; } else { //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor); interpolation = framesSinceKF / (float)framesDifference; } } else { nextKF = a3d.keyframes[kfi.kf + 1]; framesDifference = (int)nextKF.frame - (int)kf.frame; //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor); interpolation = framesSinceKF / (float)framesDifference; } //print(interpolation); //print(a3d.vectors.Length + " - " + nextKF.positionVector); AnimVector pos2 = a3d.vectors[nextKF.positionVector]; AnimQuaternion qua2 = a3d.quaternions[nextKF.quaternion]; AnimVector scl2 = a3d.vectors[nextKF.scaleVector]; vector = Vector3.Lerp(pos.vector, pos2.vector, interpolation); quaternion = Quaternion.Lerp(qua.quaternion, qua2.quaternion, interpolation); scale = Vector3.Lerp(scl.vector, scl2.vector, interpolation); float positionMultiplier = Mathf.Lerp(kf.positionMultiplier, nextKF.positionMultiplier, interpolation); if (poNum != currentActivePO[i]) { if (currentActivePO[i] == -2 && fullMorphPOs != null && fullMorphPOs[i] != null) { foreach (PhysicalObject morphPO in fullMorphPOs[i].Values) { if (morphPO.Gao.activeSelf) { morphPO.Gao.SetActive(false); } } } if (currentActivePO[i] >= 0 && subObjects[i][currentActivePO[i]] != null) { subObjects[i][currentActivePO[i]].Gao.SetActive(false); } currentActivePO[i] = poNum; if (physicalObject != null) { physicalObject.Gao.SetActive(true); } } if (!channelParents[i]) { channelObjects[i].transform.SetParent(perso.gameObject.transform); } channelObjects[i].transform.localPosition = vector * positionMultiplier; channelObjects[i].transform.localRotation = quaternion; channelObjects[i].transform.localScale = scale; if (physicalObject != null && a3d.num_morphData > 0 && morphDataArray != null && i < morphDataArray.GetLength(0) && currentFrame < morphDataArray.GetLength(1)) { AnimMorphData morphData = morphDataArray[i, currentFrame]; if (morphData != null && morphData.morphProgress != 0 && morphData.morphProgress != 100) { PhysicalObject morphToPO = perso.Perso3dData.ObjectList.entries[morphData.objectIndexTo].po; Vector3[] morphVerts = null; for (int j = 0; j < physicalObject.visualSet.Length; j++) { IGeometricObject obj = physicalObject.visualSet[j].obj; if (obj == null || obj as MeshObject == null) { continue; } MeshObject fromM = obj as MeshObject; MeshObject toM = morphToPO.visualSet[j].obj as MeshObject; if (toM == null) { continue; } if (fromM.vertices.Length != toM.vertices.Length) { // For those special cases like the mistake in the Clark cinematic continue; } int numVertices = fromM.vertices.Length; morphVerts = new Vector3[numVertices]; for (int vi = 0; vi < numVertices; vi++) { morphVerts[vi] = Vector3.Lerp(fromM.vertices[vi], toM.vertices[vi], morphData.morphProgressFloat); } for (int k = 0; k < fromM.num_subblocks; k++) { if (fromM.subblocks[k] == null || fromM.subblock_types[k] != 1) { continue; } MeshElement el = (MeshElement)fromM.subblocks[k]; if (el != null) { el.UpdateMeshVertices(morphVerts); } } } } else if (morphData != null && morphData.morphProgress == 100) { physicalObject.Gao.SetActive(false); PhysicalObject c = fullMorphPOs[i][morphData.objectIndexTo]; c.Gao.transform.localScale = c.scaleMultiplier.HasValue ? c.scaleMultiplier.Value : Vector3.one; c.Gao.transform.localPosition = Vector3.zero; c.Gao.transform.localRotation = Quaternion.identity; c.Gao.SetActive(true); currentActivePO[i] = -2; } else { for (int j = 0; j < physicalObject.visualSet.Length; j++) { IGeometricObject obj = physicalObject.visualSet[j].obj; if (obj == null || obj as MeshObject == null) { continue; } MeshObject fromM = obj as MeshObject; for (int k = 0; k < fromM.num_subblocks; k++) { if (fromM.subblocks[k] == null || fromM.subblock_types[k] != 1) { continue; } MeshElement el = (MeshElement)fromM.subblocks[k]; if (el != null) { el.ResetVertices(); } } } } } } if (hasBones) { for (int i = 0; i < a3d.num_channels; i++) { AnimChannel ch = a3d.channels[a3d.start_channels + i]; Transform baseChannelTransform = channelObjects[i].transform; Vector3 invertedScale = new Vector3(1f / baseChannelTransform.localScale.x, 1f / baseChannelTransform.localScale.y, 1f / baseChannelTransform.localScale.z); AnimNumOfNTTO numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO]; AnimNTTO ntto = a3d.ntto[numOfNTTO.numOfNTTO]; PhysicalObject physicalObject = subObjects[i][numOfNTTO.numOfNTTO - a3d.start_NTTO]; if (physicalObject == null) { continue; } DeformSet bones = physicalObject.Bones; // Deformations if (bones != null) { for (int j = 0; j < a3d.num_deformations; j++) { AnimDeformation d = a3d.deformations[a3d.start_deformations + j]; if (d.channel < ch.id) { continue; } if (d.channel > ch.id) { break; } if (!channelIDDictionary.ContainsKey(d.linkChannel)) { continue; } List <int> ind_linkChannel_list = GetChannelByID(d.linkChannel); foreach (int ind_linkChannel in ind_linkChannel_list) { AnimChannel ch_link = a3d.channels[a3d.start_channels + ind_linkChannel]; AnimNumOfNTTO numOfNTTO_link = a3d.numOfNTTO[ch_link.numOfNTTO + of.numOfNTTO]; AnimNTTO ntto_link = a3d.ntto[numOfNTTO_link.numOfNTTO]; PhysicalObject physicalObject_link = subObjects[ind_linkChannel][numOfNTTO_link.numOfNTTO - a3d.start_NTTO]; if (physicalObject_link == null) { continue; } if (bones == null || bones.bones.Length <= d.bone + 1) { continue; } DeformBone bone = bones.r3bones[d.bone + 1]; if (bone != null) { Transform channelTransform = channelObjects[ind_linkChannel].transform; bone.UnityBone.transform.SetParent(channelTransform); bone.UnityBone.localPosition = Vector3.zero; bone.UnityBone.localRotation = Quaternion.identity; bone.UnityBone.localScale = Vector3.one; /*bone.UnityBone.position = channelTransform.position; * bone.UnityBone.rotation = channelTransform.rotation; * //bone.UnityBone.localScale = Vector3.one; * bone.UnityBone.localScale = channelTransform.localScale;*/ } } } } } } //this.currentFrame = (currentFrame + 1) % a3d.num_onlyFrames; } }
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; } }
public void UpdateAnimation() { if (IsLoaded && shAnim != null && animCuts != null && animCuts.Length > 0 && channelObjects != null && subObjects != null) { if (currentFrame >= shAnim.num_frames) { currentFrame %= shAnim.num_frames; } UpdateAnimationCut(); // First pass: reset TRS for all sub objects for (int i = 0; i < channelParents[currentAnimCut].Length; i++) { channelParents[currentAnimCut][i] = false; } ROMAnimation anim = ROMStruct.Loader.romAnims[animCuts[currentAnimCut].index]; uint currentRelativeFrame = currentFrame - anim.a3d.this_start_onlyFrames; AnimOnlyFrame of = anim.onlyFrames[currentRelativeFrame]; // Create hierarchy for this frame for (int i = of.start_hierarchies_for_frame; i < of.start_hierarchies_for_frame + of.num_hierarchies_for_frame; i++) { AnimHierarchy h = anim.hierarchies[i]; if (!channelIDDictionary[currentAnimCut].ContainsKey(h.childChannelID) || !channelIDDictionary[currentAnimCut].ContainsKey(h.parentChannelID)) { continue; } List <int> ch_child_list = GetChannelByID(h.childChannelID); List <int> ch_parent_list = GetChannelByID(h.parentChannelID); foreach (int ch_child in ch_child_list) { foreach (int ch_parent in ch_parent_list) { channelObjects[currentAnimCut][ch_child].transform.SetParent(channelObjects[currentAnimCut][ch_parent].transform); channelParents[currentAnimCut][ch_child] = true; } } //channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform); } // Final pass int currentKFIndex = 0; for (int i = 0; i < anim.channels.Length; i++) { AnimChannel ch = anim.channels[i]; // Select keyframe AnimKeyframe kf = null; int selectedKFindex = 0; for (int k = 0; k < ch.num_keyframes; k++) { if (anim.keyframes[currentKFIndex + k].frame <= currentFrame) { kf = anim.keyframes[currentKFIndex + k]; selectedKFindex = k; } else { break; } } AnimVector pos = anim.vectors[kf.positionVector]; AnimQuaternion qua = anim.quaternions[kf.quaternion]; AnimVector scl = anim.vectors[kf.scaleVector]; AnimNumOfNTTO numOfNTTO = anim.numOfNTTO[(i * anim.a3d.num_numNTTO) + of.numOfNTTO]; AnimNTTO ntto = null; int poNum = -1; GameObject physicalObject = null; if (numOfNTTO.numOfNTTO != 0xFFFF) { poNum = numOfNTTO.numOfNTTO; ntto = anim.ntto[poNum]; physicalObject = subObjects[currentAnimCut][i][poNum]; } Vector3 vector = pos.vector; Quaternion quaternion = qua.quaternion; Vector3 scale = scl.vector; int framesSinceKF = (int)currentFrame - (int)kf.frame; AnimKeyframe nextKF = null; int framesDifference; float interpolation; if (selectedKFindex == ch.num_keyframes - 1) { nextKF = anim.keyframes[currentKFIndex]; framesDifference = anim.a3d.total_num_onlyFrames - 1 + (int)nextKF.frame - (int)kf.frame; if (framesDifference == 0) { interpolation = 0; } else { //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor); interpolation = framesSinceKF / (float)framesDifference; } } else { nextKF = anim.keyframes[currentKFIndex + selectedKFindex + 1]; framesDifference = (int)nextKF.frame - (int)kf.frame; //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor); interpolation = framesSinceKF / (float)framesDifference; } currentKFIndex += ch.num_keyframes; //print(interpolation); //print(a3d.vectors.Length + " - " + nextKF.positionVector); //print(perso.p3dData.family.animBank); AnimVector pos2 = anim.vectors[nextKF.positionVector]; AnimQuaternion qua2 = anim.quaternions[nextKF.quaternion]; AnimVector scl2 = anim.vectors[nextKF.scaleVector]; vector = Vector3.Lerp(pos.vector, pos2.vector, interpolation); quaternion = Quaternion.Lerp(qua.quaternion, qua2.quaternion, interpolation); scale = Vector3.Lerp(scl.vector, scl2.vector, interpolation); //float positionMultiplier = Mathf.Lerp(kf.positionMultiplier, nextKF.positionMultiplier, interpolation); if (poNum != currentActivePO[currentAnimCut][i]) { if (currentActivePO[currentAnimCut][i] == -2 && fullMorphPOs[currentAnimCut] != null && fullMorphPOs[currentAnimCut][i] != null) { foreach (GameObject morphPO in fullMorphPOs[currentAnimCut][i].Values) { if (morphPO.activeSelf) { morphPO.SetActive(false); } } } if (currentActivePO[currentAnimCut][i] >= 0 && subObjects[currentAnimCut][i][currentActivePO[currentAnimCut][i]] != null) { subObjects[currentAnimCut][i][currentActivePO[currentAnimCut][i]].SetActive(false); } currentActivePO[currentAnimCut][i] = poNum; if (physicalObject != null) { physicalObject.SetActive(true); } } if (!channelParents[currentAnimCut][i]) { channelObjects[currentAnimCut][i].transform.SetParent(transform); } channelObjects[currentAnimCut][i].transform.localPosition = vector; // * positionMultiplier; channelObjects[currentAnimCut][i].transform.localRotation = quaternion; channelObjects[currentAnimCut][i].transform.localScale = scale; if (physicalObject != null && anim.a3d.num_morphData > 0 && morphDataArray[currentAnimCut] != null && i < morphDataArray[currentAnimCut].GetLength(0) && currentRelativeFrame < morphDataArray[currentAnimCut].GetLength(1)) { AnimMorphData morphData = morphDataArray[currentAnimCut][i, currentRelativeFrame]; GeometricObject ogPO = perso.p3dData.Value.objectsTable.Value.data.Value.entries[anim.ntto[poNum].object_index].obj.Value.visual.Value; if (morphData != null && morphData.morphProgress != 0 && morphData.morphProgress != 100) { //print("morphing " + physicalObject.name); GeometricObject morphToPO = perso.p3dData.Value.objectsTable.Value.data.Value.entries[morphData.objectIndexTo].obj.Value.visual.Value; ogPO.MorphVertices(physicalObject, morphToPO, morphData.morphProgress / 100f); } else if (morphData != null && morphData.morphProgress == 100) { physicalObject.SetActive(false); GameObject c = fullMorphPOs[currentAnimCut][i][morphData.objectIndexTo]; c.transform.localScale = objectIndexScales.ContainsKey(morphData.objectIndexTo) ? objectIndexScales[morphData.objectIndexTo] : Vector3.one; c.transform.localPosition = Vector3.zero; c.transform.localRotation = Quaternion.identity; c.SetActive(true); currentActivePO[currentAnimCut][i] = -2; } else { ogPO.ResetMorph(physicalObject); } } } } }
void SwitchAnimationCut(int newAnimCut) { if (currentAnimCut != newAnimCut || forceAnimUpdate) { forceAnimUpdate = false; // Init animation this.currentAnimCut = newAnimCut; ROMAnimation anim = ROMStruct.Loader.romAnims[animCuts[currentAnimCut].index]; bool newCut = subObjects[currentAnimCut] == null; if (anim != null && newCut) { //animationSpeed = a3d.speed; // Init channels & subobjects channelObjects[currentAnimCut] = new GameObject[anim.a3d.num_channels]; currentActivePO[currentAnimCut] = new int[anim.a3d.num_channels]; channelParents[currentAnimCut] = new bool[anim.a3d.num_channels]; subObjects[currentAnimCut] = new GameObject[anim.a3d.num_channels][]; if (anim.a3d.num_morphData > 0) { fullMorphPOs[currentAnimCut] = new Dictionary <ushort, GameObject> [anim.a3d.num_channels]; } for (int i = 0; i < anim.a3d.num_channels; i++) { short id = anim.channels[i].id; channelObjects[currentAnimCut][i] = new GameObject($"[Cut {currentAnimCut}] Channel {id}"); channelObjects[currentAnimCut][i].transform.SetParent(transform); currentActivePO[currentAnimCut][i] = -1; AddChannelID(id, i); if (newCut) { subObjects[currentAnimCut][i] = new GameObject[anim.a3d.num_NTTO]; } AnimChannel ch = anim.channels[i]; List <ushort> listOfNTTOforChannel = new List <ushort>(); for (int j = 0; j < anim.onlyFrames.Length; j++) { AnimOnlyFrame of = anim.onlyFrames[j]; //print(ch.numOfNTTO + " - " + of.numOfNTTO + " - " + a3d.numOfNTTO.Length); AnimNumOfNTTO numOfNTTO = anim.numOfNTTO[(i * anim.a3d.num_numNTTO) + of.numOfNTTO]; if (!listOfNTTOforChannel.Contains(numOfNTTO.numOfNTTO) && numOfNTTO.numOfNTTO != 0xFFFF) { listOfNTTOforChannel.Add(numOfNTTO.numOfNTTO); } } if (newCut) { for (int k = 0; k < listOfNTTOforChannel.Count; k++) { int j = listOfNTTOforChannel[k]; AnimNTTO ntto = anim.ntto[j]; if (ntto.IsInvisibleNTTO) { subObjects[currentAnimCut][i][j] = new GameObject(); subObjects[currentAnimCut][i][j].transform.parent = channelObjects[currentAnimCut][i].transform; subObjects[currentAnimCut][i][j].name = "[" + j + "] Invisible NTTO"; subObjects[currentAnimCut][i][j].SetActive(false); } else { if (perso.p3dData.Value.objectsTable.Value != null && perso.p3dData.Value.objectsTable.Value.length > ntto.object_index) { ObjectsTableData.Entry entry = perso.p3dData.Value.objectsTable.Value.data.Value.entries[ntto.object_index]; PhysicalObject o = entry.obj.Value; if (o != null) { //if (o.visualSetType == 1) print(name); GameObject c = o.GetGameObject().gameObject; subObjects[currentAnimCut][i][j] = c; if (entry.scale.HasValue) { objectIndexScales[ntto.object_index] = new Vector3(entry.scale.Value.x, entry.scale.Value.z, entry.scale.Value.y); subObjects[currentAnimCut][i][j].transform.localScale = objectIndexScales[ntto.object_index]; } c.transform.parent = channelObjects[currentAnimCut][i].transform; c.name = "[" + j + "] " + c.name; c.SetActive(false); } } } } } } if (anim.a3d.num_morphData > 0 && anim.morphData != null) { morphDataArray[currentAnimCut] = new AnimMorphData[anim.channels.Length, anim.onlyFrames.Length]; // Iterate over morph data to find the correct channel and keyframe for (int i = 0; i < anim.a3d.num_morphData; i++) { AnimMorphData m = anim.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[currentAnimCut].GetLength(0) && m.frame < morphDataArray[currentAnimCut].GetLength(1)) { morphDataArray[currentAnimCut][channelIndex, m.frame] = m; if (m.morphProgress == 100 && perso.p3dData.Value.objectsTable.Value != null && perso.p3dData.Value.objectsTable.Value.length > m.objectIndexTo) { if (fullMorphPOs[currentAnimCut][channelIndex] == null) { fullMorphPOs[currentAnimCut][channelIndex] = new Dictionary <ushort, GameObject>(); } if (!fullMorphPOs[currentAnimCut][channelIndex].ContainsKey(m.objectIndexTo)) { ObjectsTableData.Entry entry = perso.p3dData.Value.objectsTable.Value.data.Value.entries[m.objectIndexTo]; PhysicalObject o = entry.obj.Value; if (o != null) { //if (o.visualSetType == 1) print(name); GameObject c = o.GetGameObject().gameObject; fullMorphPOs[currentAnimCut][channelIndex][m.objectIndexTo] = c; if (entry.scale.HasValue) { objectIndexScales[m.objectIndexTo] = new Vector3(entry.scale.Value.x, entry.scale.Value.z, entry.scale.Value.y); c.transform.localScale = objectIndexScales[m.objectIndexTo]; } /*subObjects[i][j].transform.localScale = * subObjects[i][j].scaleMultiplier.HasValue ? subObjects[i][j].scaleMultiplier.Value : Vector3.one;*/ c.transform.parent = channelObjects[currentAnimCut][channelIndex].transform; c.name = "[Morph] " + c.name; c.SetActive(false); } } } } } } } else { morphDataArray = null; } // Keep lighting last so that it is applied to all new sub objects if (!IsAlways) { controller.sectorManager.ApplySectorLighting(sector, gameObject, OpenSpace.Visual.LightInfo.ObjectLightedFlag.Perso); } else { controller.sectorManager.ApplySectorLighting(sector, gameObject, OpenSpace.Visual.LightInfo.ObjectLightedFlag.None); } } if (channelObjects != null) { for (int i = 0; i < animCuts.Length; i++) { if (channelObjects[i] != null) { if (currentAnimCut == i) { foreach (GameObject g in channelObjects[i]) { g.SetActive(true); } } else { foreach (GameObject g in channelObjects[i]) { g.SetActive(false); } } } } } IsLoaded = 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"); } } } } } }