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; } }
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; } }