public VisualMaterial Clone() { VisualMaterial vm = (VisualMaterial)MemberwiseClone(); vm.textures = new List <VisualMaterialTexture>(textures); vm.animTextures = new List <AnimatedTexture>(animTextures); vm.Reset(); return(vm); }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { VisualMaterial vmt = (VisualMaterial)value; string hash = HashUtils.MD5Hash(vmt.ToJSON()); VisualMaterialReference reference = new VisualMaterialReference() { Hash = hash }; var jt = JToken.FromObject(reference); jt.WriteTo(writer); }
public static VisualMaterial FromOffsetOrRead(Pointer offset, Reader reader) { if (offset == null) { return(null); } VisualMaterial vm = FromOffset(offset); if (vm == null) { Pointer.DoAt(ref reader, offset, () => { vm = VisualMaterial.Read(reader, offset); MapLoader.Loader.visualMaterials.Add(vm); }); } return(vm); }
public static VisualMaterial Read(Reader reader, Pointer offset) { MapLoader l = MapLoader.Loader; VisualMaterial m = new VisualMaterial(offset); // Material struct = 0x188 //l.print("Material @ " + offset); m.flags = reader.ReadUInt32(); // After this: 0x4 if (Settings.s.game != Settings.Game.R2Revolution && Settings.s.game != Settings.Game.LargoWinch) { if (Settings.s.platform == Settings.Platform.DC) { reader.ReadUInt32(); } m.ambientCoef = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); m.diffuseCoef = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); m.specularCoef = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); m.color = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); // 0x44 } else if (Settings.s.game == Settings.Game.R2Revolution) { // Fill in light info for Revolution m.ambientCoef = new Vector4(0, 0, 0, 1f); m.diffuseCoef = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); //m.diffuseCoef = new Vector4(1, 1, 1, 1); reader.ReadInt32(); // current refresh number for scrolling/animated textures m.off_animTextures_first = Pointer.Read(reader); m.off_animTextures_current = Pointer.Read(reader); reader.ReadInt32(); m.num_animTextures = reader.ReadUInt16(); reader.ReadUInt16(); // 0x70 } else if (Settings.s.game == Settings.Game.LargoWinch) { m.ambientCoef = new Vector4(0, 0, 0, 1f); m.color = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); // 0x44 m.diffuseCoef = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); //m.ambientCoef = m.diffuseCoef; reader.ReadInt32(); // current refresh number for scrolling/animated textures m.off_animTextures_first = Pointer.Read(reader); m.off_animTextures_current = Pointer.Read(reader); reader.ReadInt32(); m.num_animTextures = reader.ReadUInt16(); reader.ReadUInt16(); } if (Settings.s.game == Settings.Game.LargoWinch) { m.num_textures = 1; VisualMaterialTexture t = new VisualMaterialTexture(); t.offset = Pointer.Current(reader); t.off_texture = Pointer.Read(reader); // 0x4c t.texture = TextureInfo.FromOffset(t.off_texture); t.textureOp = reader.ReadByte(); t.shadingMode = reader.ReadByte(); t.uvFunction = reader.ReadByte(); t.scrollByte = reader.ReadByte(); t.scrollX = reader.ReadSingle(); t.scrollY = reader.ReadSingle(); reader.ReadSingle(); new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); m.textures.Add(t); } else if (Settings.s.game == Settings.Game.R2Revolution) { m.num_textures = 1; VisualMaterialTexture t = new VisualMaterialTexture(); t.offset = Pointer.Current(reader); t.off_texture = Pointer.Read(reader); // 0x4c t.texture = TextureInfo.FromOffset(t.off_texture); t.scrollMode = reader.ReadUInt32(); t.scrollX = reader.ReadSingle(); t.scrollY = reader.ReadSingle(); t.currentScrollX = reader.ReadSingle(); t.currentScrollY = reader.ReadSingle(); m.textures.Add(t); /*reader.ReadInt32(); // current refresh number for scrolling/animated textures, 0x64 * m.off_animTextures_first = Pointer.Read(reader); // 0x68 * m.off_animTextures_current = Pointer.Read(reader); // 0x6c * m.num_animTextures = reader.ReadUInt16(); * reader.ReadUInt16(); // 0x70 * reader.ReadUInt32(); * reader.ReadByte(); * reader.ReadByte(); * m.properties = reader.ReadByte(); * reader.ReadByte(); * reader.ReadUInt32(); * reader.ReadUInt32();*/ } else if (Settings.s.engineVersion < Settings.EngineVersion.R3) { m.num_textures = 1; reader.ReadUInt32(); // 0x48 VisualMaterialTexture t = new VisualMaterialTexture(); t.offset = Pointer.Current(reader); t.off_texture = Pointer.Read(reader); // 0x4c t.texture = TextureInfo.FromOffset(t.off_texture); if (Settings.s.game == Settings.Game.TT) { /*m.off_animTextures_first = Pointer.Read(reader); // 0x68 * m.off_animTextures_current = Pointer.Read(reader); // 0x6c * m.num_animTextures = reader.ReadUInt16();*/ Pointer.Read(reader); // detail texture t.currentScrollX = reader.ReadSingle(); t.currentScrollY = reader.ReadSingle(); t.scrollX = reader.ReadSingle(); // 0x58 t.scrollY = reader.ReadSingle(); // 0x5c t.scrollMode = reader.ReadUInt32(); //0x60 m.textures.Add(t); reader.ReadInt32(); // current refresh number for scrolling/animated textures, 0x64 } else { if (Settings.s.platform == Settings.Platform.DC) { // For some reason there's a huge gap here reader.ReadBytes(0xD0); } t.currentScrollX = reader.ReadSingle(); t.currentScrollY = reader.ReadSingle(); t.scrollX = reader.ReadSingle(); // 0x58 t.scrollY = reader.ReadSingle(); // 0x5c t.scrollMode = reader.ReadUInt32(); //0x60 m.textures.Add(t); reader.ReadInt32(); // current refresh number for scrolling/animated textures, 0x64 m.off_animTextures_first = Pointer.Read(reader); // 0x68 m.off_animTextures_current = Pointer.Read(reader); // 0x6c m.num_animTextures = reader.ReadUInt16(); reader.ReadUInt16(); // 0x70 } reader.ReadUInt32(); // 0x74 m.properties = reader.ReadByte(); // whole byte for texture scroll lock in R2, no bitmasks reader.ReadByte(); reader.ReadByte(); // padding, not in DC reader.ReadByte(); // padding, not in DC } else // EngineVersion >= R3 { reader.ReadUInt32(); // current refresh number for scrolling/animated textures, 0x48 if (Settings.s.game == Settings.Game.Dinosaur) { reader.ReadBytes(0x1C); } m.off_animTextures_first = Pointer.Read(reader); m.off_animTextures_current = Pointer.Read(reader); m.num_animTextures = reader.ReadUInt16(); reader.ReadUInt16(); reader.ReadUInt32(); reader.ReadByte(); reader.ReadByte(); m.properties = reader.ReadByte(); reader.ReadByte(); reader.ReadUInt32(); reader.ReadUInt32(); /* m.num_textures = */ reader.ReadUInt32(); for (int i = 0; i < 4; i++) { VisualMaterialTexture t = new VisualMaterialTexture(); t.offset = Pointer.Current(reader); t.off_texture = Pointer.Read(reader); if (t.off_texture == null) { break; } /*if (Settings.s.game == Settings.Game.Dinosaur) { * Pointer.DoAt(ref reader, t.off_texture, () => { * Pointer off_tex = Pointer.Read(reader); * t.texture = TextureInfo.FromOffset(off_tex); * }); * } else {*/ t.texture = TextureInfo.FromOffset(t.off_texture); //} t.textureOp = reader.ReadByte(); t.shadingMode = reader.ReadByte(); t.uvFunction = reader.ReadByte(); t.scrollByte = reader.ReadByte(); if (Settings.s.game == Settings.Game.Dinosaur) { t.properties = reader.ReadInt32(); new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); t.currentScrollX = reader.ReadSingle(); t.currentScrollY = reader.ReadSingle(); t.scrollX = reader.ReadSingle(); t.scrollY = reader.ReadSingle(); new Vector2(reader.ReadSingle(), reader.ReadSingle()); new Vector2(reader.ReadSingle(), reader.ReadSingle()); new Vector2(reader.ReadSingle(), reader.ReadSingle()); new Vector2(reader.ReadSingle(), reader.ReadSingle()); new Vector2(reader.ReadSingle(), reader.ReadSingle()); } else { t.properties = reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt32(); t.scrollX = reader.ReadSingle(); t.scrollY = reader.ReadSingle(); t.rotateSpeed = reader.ReadSingle(); t.rotateDirection = reader.ReadSingle(); reader.ReadInt32(); reader.ReadInt32(); t.currentScrollX = reader.ReadSingle(); t.currentScrollY = reader.ReadSingle(); reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt32(); t.blendIndex = reader.ReadUInt32(); } m.textures.Add(t); } m.num_textures = (uint)m.textures.Count; } if (m.num_animTextures > 0 && m.off_animTextures_first != null) { Pointer off_currentAnimTexture = m.off_animTextures_first; Pointer.Goto(ref reader, m.off_animTextures_first); for (int i = 0; i < m.num_animTextures; i++) { if (off_currentAnimTexture == m.off_animTextures_current) { m.currentAnimTexture = i; } Pointer off_animTexture = Pointer.Read(reader); float time = reader.ReadSingle(); m.animTextures.Add(new AnimatedTexture(off_animTexture, time)); Pointer off_nextAnimTexture = Pointer.Read(reader); if (off_nextAnimTexture != null) { off_currentAnimTexture = off_nextAnimTexture; Pointer.Goto(ref reader, off_nextAnimTexture); } } } return(m); }
public static SpriteElement Read(EndianBinaryReader reader, Pointer offset, MeshObject m) { MapLoader l = MapLoader.Loader; SpriteElement s = new SpriteElement(offset, m); s.name = "Sprite @ pos " + offset; s.off_sprites = Pointer.Read(reader); s.num_sprites = reader.ReadUInt16(); reader.ReadInt16(); // -1 reader.ReadUInt32(); reader.ReadUInt32(); if (s.off_sprites != null) { Pointer.Goto(ref reader, s.off_sprites); s.sprites = new IndexedSprite[s.num_sprites]; for (uint i = 0; i < s.num_sprites; i++) { s.sprites[i] = new IndexedSprite(); s.sprites[i].off_info = Pointer.Read(reader); s.sprites[i].size = new Vector2(reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].constraint = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].uv1 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].uv2 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].centerPoint = reader.ReadUInt16(); reader.ReadUInt16(); if (l.mode == MapLoader.Mode.Rayman2PC) { reader.ReadUInt32(); } if (s.sprites[i].off_info != null) { Pointer off_current = Pointer.Goto(ref reader, s.sprites[i].off_info); reader.ReadUInt32(); Pointer.Read(reader); Pointer.Read(reader); Pointer off_info_uv1 = Pointer.Read(reader); Pointer off_info_uv2 = Pointer.Read(reader); s.sprites[i].off_material_pointer = Pointer.Read(reader); Pointer.Goto(ref reader, off_current); if (off_info_uv1 != null) { off_current = Pointer.Goto(ref reader, off_info_uv1); s.sprites[i].info_uv1 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); Pointer.Goto(ref reader, off_current); } if (off_info_uv2 != null) { off_current = Pointer.Goto(ref reader, off_info_uv2); s.sprites[i].info_uv2 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); Pointer.Goto(ref reader, off_current); } if (s.sprites[i].off_material_pointer != null) { off_current = Pointer.Goto(ref reader, s.sprites[i].off_material_pointer); s.sprites[i].off_material = Pointer.Read(reader); if (l.mode == MapLoader.Mode.Rayman2PC && s.sprites[i].off_material != null) { Pointer.Goto(ref reader, s.sprites[i].off_material); s.sprites[i].off_material = Pointer.Read(reader); } if (s.sprites[i].off_material != null) { Pointer.Goto(ref reader, s.sprites[i].off_material); s.sprites[i].r3mat = VisualMaterial.FromOffset(s.sprites[i].off_material, createIfNull: true); } else { s.sprites[i].r3mat = null; } Pointer.Goto(ref reader, off_current); } } } } return(s); }
public static GeometricObjectElementSprites Read(Reader reader, Pointer offset, GeometricObject m) { MapLoader l = MapLoader.Loader; GeometricObjectElementSprites s = new GeometricObjectElementSprites(offset, m); s.name = "Sprite @ pos " + offset; //l.print(s.name); if (Settings.s.engineVersion > Settings.EngineVersion.Montreal) { if (Settings.s.platform == Settings.Platform.DC) { s.off_sprites = offset; s.num_sprites = 1; } else { s.off_sprites = Pointer.Read(reader); s.num_sprites = reader.ReadUInt16(); reader.ReadInt16(); // -1 if (Settings.s.game != Settings.Game.R2Revolution) { reader.ReadUInt32(); if (Settings.s.game != Settings.Game.LargoWinch) { reader.ReadUInt32(); } } } } else { s.num_sprites = (ushort)reader.ReadUInt32(); s.off_sprites = Pointer.Read(reader); reader.ReadUInt32(); } if (Settings.s.game == Settings.Game.R2Revolution) { Pointer.DoAt(ref reader, s.off_sprites, () => { s.sprites = new IndexedSprite[s.num_sprites]; for (uint i = 0; i < s.num_sprites; i++) { s.sprites[i] = new IndexedSprite(); uint type = reader.ReadUInt32(); s.sprites[i].info_scale = new Vector2(reader.ReadSingle(), reader.ReadSingle()); if (type == 0x20) { // Light cookie sprite uint index = reader.ReadUInt32(); R2PS2Loader ps2l = MapLoader.Loader as R2PS2Loader; s.sprites[i].visualMaterial = ps2l.lightCookieMaterial.Clone(); s.sprites[i].visualMaterial.diffuseCoef = ps2l.lightCookieColors[index]; } else { s.sprites[i].off_material = Pointer.Read(reader); if (s.sprites[i].off_material != null) { s.sprites[i].visualMaterial = VisualMaterial.FromOffsetOrRead(s.sprites[0].off_material, reader); } } } }); } else if (Settings.s.platform == Settings.Platform.DC) { s.sprites = new IndexedSprite[1]; s.sprites[0] = new IndexedSprite(); s.sprites[0].off_material = Pointer.Read(reader); if (s.sprites[0].off_material != null) { s.sprites[0].visualMaterial = VisualMaterial.FromOffsetOrRead(s.sprites[0].off_material, reader); } s.sprites[0].info_scale = new Vector2(reader.ReadSingle(), reader.ReadSingle()); reader.ReadUInt16(); s.sprites[0].centerPoint = reader.ReadUInt16(); reader.ReadUInt16(); reader.ReadUInt16(); reader.ReadUInt16(); reader.ReadUInt16(); } else { if (s.off_sprites != null) { Pointer.Goto(ref reader, s.off_sprites); s.sprites = new IndexedSprite[s.num_sprites]; for (uint i = 0; i < s.num_sprites; i++) { s.sprites[i] = new IndexedSprite(); if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal) { reader.ReadUInt32(); } s.sprites[i].off_info = Pointer.Read(reader); s.sprites[i].size = new Vector2(reader.ReadSingle(), reader.ReadSingle()); if (Settings.s.engineVersion > Settings.EngineVersion.Montreal) { if (Settings.s.game != Settings.Game.LargoWinch) { s.sprites[i].constraint = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].uv1 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].uv2 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } s.sprites[i].centerPoint = reader.ReadUInt16(); reader.ReadUInt16(); if (Settings.s.engineVersion < Settings.EngineVersion.R3) { reader.ReadUInt32(); } } if (s.sprites[i].off_info != null) { Pointer off_current = Pointer.Goto(ref reader, s.sprites[i].off_info); reader.ReadUInt32(); Pointer.Read(reader); Pointer.Read(reader); Pointer off_info_scale = Pointer.Read(reader); Pointer off_info_unknown = Pointer.Read(reader); s.sprites[i].off_material_pointer = Pointer.Read(reader); Pointer.Goto(ref reader, off_current); Pointer.DoAt(ref reader, off_info_scale, () => { s.sprites[i].info_scale = new Vector2(reader.ReadSingle(), reader.ReadSingle()); }); Pointer.DoAt(ref reader, off_info_unknown, () => { s.sprites[i].info_unknown = new Vector2(reader.ReadSingle(), reader.ReadSingle()); }); if (s.sprites[i].off_material_pointer != null) { off_current = Pointer.Goto(ref reader, s.sprites[i].off_material_pointer); s.sprites[i].off_material = Pointer.Read(reader); if (s.sprites[i].off_material != null) { if (Settings.s.engineVersion < Settings.EngineVersion.R3) { s.sprites[i].gameMaterial = GameMaterial.FromOffsetOrRead(s.sprites[i].off_material, reader); s.sprites[i].visualMaterial = s.sprites[i].gameMaterial.visualMaterial; } else { s.sprites[i].visualMaterial = VisualMaterial.FromOffsetOrRead(s.sprites[i].off_material, reader); } } Pointer.Goto(ref reader, off_current); } } } } } return(s); }
public static MeshElement Read(EndianBinaryReader reader, Pointer offset, MeshObject m) { MapLoader l = MapLoader.Loader; MeshElement sm = new MeshElement(offset, m); sm.name = "Submesh @ pos " + offset; sm.backfaceCulling = !l.forceDisplayBackfaces; sm.off_material = Pointer.Read(reader); if (l.mode != MapLoader.Mode.Rayman2PC) { sm.r3mat = VisualMaterial.FromOffset(sm.off_material); } else { Pointer off_current = Pointer.Goto(ref reader, sm.off_material); sm.off_material = Pointer.Read(reader); if (sm.off_material != null) { Pointer.Goto(ref reader, sm.off_material); sm.r3mat = VisualMaterial.FromOffset(sm.off_material, createIfNull: true); } else { sm.r3mat = null; } Pointer.Goto(ref reader, off_current); } if (sm.r3mat != null) { sm.backfaceCulling = ((sm.r3mat.flags & VisualMaterial.flags_backfaceCulling) != 0) && !l.forceDisplayBackfaces; } sm.num_disconnected_triangles_spe = reader.ReadUInt16(); sm.num_uvs = reader.ReadUInt16(); if (l.mode != MapLoader.Mode.Rayman2PC) { sm.num_uvMaps = reader.ReadUInt16(); reader.ReadUInt16(); } sm.off_disconnected_triangles_spe = Pointer.Read(reader); // 1 entry = 3 shorts. Max: num_vertices if (l.mode == MapLoader.Mode.Rayman3GC) { reader.ReadUInt32(); } sm.off_mapping_uvs_spe = Pointer.Read(reader); // 1 entry = 3 shorts. Max: num_weights sm.off_weights_spe = Pointer.Read(reader); // 1 entry = 3 floats sm.off_uvs = Pointer.Read(reader); // 1 entry = 2 floats if (l.mode != MapLoader.Mode.Rayman2PC) { reader.ReadUInt32(); reader.ReadUInt32(); } sm.off_vertex_indices = Pointer.Read(reader); sm.num_vertex_indices = reader.ReadUInt16(); reader.ReadInt16(); reader.ReadUInt32(); if (l.mode != MapLoader.Mode.Rayman2PC) { reader.ReadUInt16(); sm.num_mapping_entries = reader.ReadUInt16(); // num_shorts sm.off_mapping_vertices = Pointer.Read(reader); // shorts_offset1 (1st array of size num_shorts, max_num_vertices) sm.off_mapping_uvs = Pointer.Read(reader); // shorts_offset2 (2nd array of size num_shorts, max: num_weights) sm.num_connected_vertices = reader.ReadUInt16(); // num_shorts2 sm.num_disconnected_triangles = reader.ReadUInt16(); sm.off_connected_vertices = Pointer.Read(reader); // shorts2_offset (array of size num_shorts2) sm.off_disconnected_triangles = Pointer.Read(reader); if (l.mode == MapLoader.Mode.Rayman3GC) { sm.name = new string(reader.ReadChars(0x34)).TrimEnd('\0'); } } else { // Defaults for Rayman 2 sm.num_uvMaps = 1; sm.num_mapping_entries = 0; sm.off_mapping_vertices = null; sm.off_mapping_uvs = null; sm.num_connected_vertices = 0; sm.num_disconnected_triangles = 0; sm.off_connected_vertices = null; sm.off_disconnected_triangles = null; } // Read mapping tables sm.mapping_uvs = new int[sm.num_uvMaps][]; if (sm.num_mapping_entries > 0) { Pointer.Goto(ref reader, sm.off_mapping_vertices); //print("Mapping offset: " + String.Format("0x{0:X}", fs.Position)); sm.mapping_vertices = new int[sm.num_mapping_entries]; for (int j = 0; j < sm.num_mapping_entries; j++) { sm.mapping_vertices[j] = reader.ReadInt16(); } Pointer.Goto(ref reader, sm.off_mapping_uvs); for (int j = 0; j < sm.num_uvMaps; j++) { sm.mapping_uvs[j] = new int[sm.num_mapping_entries]; } for (int j = 0; j < sm.num_mapping_entries; j++) { for (int um = 0; um < sm.num_uvMaps; um++) { sm.mapping_uvs[um][j] = reader.ReadInt16(); } } } if (sm.num_disconnected_triangles_spe > 0) { Pointer.Goto(ref reader, sm.off_mapping_uvs_spe); sm.mapping_uvs_spe = new int[sm.num_uvMaps][]; for (int j = 0; j < sm.num_uvMaps; j++) { sm.mapping_uvs_spe[j] = new int[sm.num_disconnected_triangles_spe * 3]; } // Why is uv maps here the outer loop instead of inner like the other thing? for (int um = 0; um < sm.num_uvMaps; um++) { for (int j = 0; j < sm.num_disconnected_triangles_spe * 3; j++) { sm.mapping_uvs_spe[um][j] = reader.ReadInt16(); } } } // Read UVs Pointer.Goto(ref reader, sm.off_uvs); sm.uvs = new Vector2[sm.num_uvs]; for (int j = 0; j < sm.num_uvs; j++) { sm.uvs[j] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } // Read triangle data Pointer.Goto(ref reader, sm.off_connected_vertices); //print("Creating triangles from connected vertices at " + String.Format("0x{0:X}", fs.Position)); sm.connected_vertices = new int[sm.num_connected_vertices]; for (int j = 0; j < sm.num_connected_vertices; j++) { sm.connected_vertices[j] = reader.ReadInt16(); } Pointer.Goto(ref reader, sm.off_disconnected_triangles); sm.disconnected_triangles = new int[sm.num_disconnected_triangles * 3]; //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position)); for (int j = 0; j < sm.num_disconnected_triangles; j++) { sm.disconnected_triangles[(j * 3) + 0] = reader.ReadInt16(); sm.disconnected_triangles[(j * 3) + 1] = reader.ReadInt16(); sm.disconnected_triangles[(j * 3) + 2] = reader.ReadInt16(); } if (sm.num_disconnected_triangles_spe > 0) { Pointer.Goto(ref reader, sm.off_disconnected_triangles_spe); sm.disconnected_triangles_spe = new int[sm.num_disconnected_triangles_spe * 3]; //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position)); for (int j = 0; j < sm.num_disconnected_triangles_spe; j++) { sm.disconnected_triangles_spe[(j * 3) + 0] = reader.ReadInt16(); sm.disconnected_triangles_spe[(j * 3) + 1] = reader.ReadInt16(); sm.disconnected_triangles_spe[(j * 3) + 2] = reader.ReadInt16(); } } return(sm); }
public void AddLightmap(Texture2D lightmap, Vector2[] lightmapUVs) { this.lightmap = lightmap; this.lightmapUVs = lightmapUVs; // Bad hack Array.Resize(ref uvs, num_uvs + lightmapUVs.Length); if (OPT_mapping_uvs != null) { Array.Resize(ref OPT_mapping_uvs, num_uvMaps + 1); OPT_mapping_uvs[OPT_mapping_uvs.Length - 1] = Enumerable.Range(num_uvs, lightmapUVs.Length).ToArray(); } if (Settings.s.game == Settings.Game.LargoWinch) { if (mapping_uvs != null && mapping_lightmap != null) { Array.Resize(ref mapping_uvs, num_uvMaps + 1); mapping_uvs[mapping_uvs.Length - 1] = new int[num_triangles * 3]; for (int i = 0; i < num_triangles * 3; i++) { int search = triangles[i]; int lightmapUV = Array.IndexOf(mapping_lightmap, search); if (lightmapUV != -1) { mapping_uvs[mapping_uvs.Length - 1][i] = num_uvs + lightmapUV; } else { MapLoader.Loader.print("not found"); mapping_uvs[mapping_uvs.Length - 1][i] = mapping_uvs[mapping_uvs.Length - 2][i]; } //mapping_uvs_spe[mapping_uvs_spe.Length - 1][i] = num_uvs + disconnected_triangles_spe[i]; } //Enumerable.Range(num_uvs, lightmapUVs.Length).ToArray(); } } Array.Copy(lightmapUVs, 0, uvs, num_uvs, lightmapUVs.Length); /*for (int j = 0; j < lightmapUVs.Length; j++) { * uvs[num_uvs + j] = lightmapuv; * }*/ num_uvs += (ushort)lightmapUVs.Length; num_uvMaps++; if (visualMaterial != null) { visualMaterial = visualMaterial.Clone(); visualMaterial.num_textures += 1; visualMaterial.textures.Add(new VisualMaterialTexture() { texture = new TextureInfo(null) { width = (ushort)lightmap.width, height = (ushort)lightmap.height, Texture = lightmap }, textureOp = 50, uvFunction = 1 }); } }
public static GeometricObjectElementTriangles Read(Reader reader, Pointer offset, GeometricObject geo) { MapLoader l = MapLoader.Loader; GeometricObjectElementTriangles sm = new GeometricObjectElementTriangles(offset, geo); sm.name = "Submesh @ pos " + offset; //l.print(sm.name); sm.backfaceCulling = !l.forceDisplayBackfaces; sm.off_material = Pointer.Read(reader); if (Settings.s.game == Settings.Game.LargoWinch) { //sm.visualMaterial = VisualMaterial.FromOffset(sm.off_material); sm.visualMaterial = VisualMaterial.FromOffsetOrRead(sm.off_material, reader); } else if (Settings.s.engineVersion == Settings.EngineVersion.R3 || Settings.s.game == Settings.Game.R2Revolution) { sm.visualMaterial = VisualMaterial.FromOffset(sm.off_material); } else { sm.gameMaterial = GameMaterial.FromOffsetOrRead(sm.off_material, reader); sm.visualMaterial = sm.gameMaterial.visualMaterial; } sm.visualMaterialOG = sm.visualMaterial; /*if (sm.visualMaterial != null && sm.visualMaterial.textures.Count > 0 && sm.visualMaterial.textures[0].off_texture != null) { * sm.name += " - VisMatTex:" + sm.visualMaterial.textures[0].offset + " - TexInfo:" + sm.visualMaterial.textures[0].off_texture; * }*/ if (sm.visualMaterial != null) { sm.backfaceCulling = ((sm.visualMaterial.flags & VisualMaterial.flags_backfaceCulling) != 0) && !l.forceDisplayBackfaces; } sm.num_triangles = reader.ReadUInt16(); if (Settings.s.game == Settings.Game.R2Revolution) { sm.lightmap_index = reader.ReadInt16(); sm.off_triangles = Pointer.Read(reader); } else { sm.num_uvs = reader.ReadUInt16(); if (Settings.s.engineVersion == Settings.EngineVersion.R3) { sm.num_uvMaps = reader.ReadUInt16(); sm.lightmap_index = reader.ReadInt16(); } sm.off_triangles = Pointer.Read(reader); // 1 entry = 3 shorts. Max: num_vertices if (Settings.s.mode == Settings.Mode.Rayman3GC) { reader.ReadUInt32(); } sm.off_mapping_uvs = Pointer.Read(reader); // 1 entry = 3 shorts. Max: num_weights sm.off_normals = Pointer.Read(reader); // 1 entry = 3 floats sm.off_uvs = Pointer.Read(reader); // 1 entry = 2 floats if (Settings.s.game == Settings.Game.LargoWinch) { sm.off_mapping_lightmap = Pointer.Read(reader); sm.num_mapping_lightmap = reader.ReadUInt16(); reader.ReadUInt16(); } else if (Settings.s.engineVersion == Settings.EngineVersion.R3) { reader.ReadUInt32(); reader.ReadUInt32(); } else if (Settings.s.engineVersion == Settings.EngineVersion.Montreal) { reader.ReadUInt32(); } if (Settings.s.game != Settings.Game.TTSE) { sm.off_vertex_indices = Pointer.Read(reader); sm.num_vertex_indices = reader.ReadUInt16(); sm.parallelBox = reader.ReadUInt16(); reader.ReadUInt32(); } } if (Settings.s.engineVersion == Settings.EngineVersion.R3) { if (Settings.s.game != Settings.Game.Dinosaur && Settings.s.game != Settings.Game.LargoWinch && Settings.s.mode != Settings.Mode.RaymanArenaGCDemo) { sm.isVisibleInPortal = reader.ReadByte(); reader.ReadByte(); sm.OPT_num_mapping_entries = reader.ReadUInt16(); // num_shorts sm.OPT_off_mapping_vertices = Pointer.Read(reader); // shorts_offset1 (1st array of size num_shorts, max_num_vertices) sm.OPT_off_mapping_uvs = Pointer.Read(reader); // shorts_offset2 (2nd array of size num_shorts, max: num_weights) sm.OPT_num_triangleStrip = reader.ReadUInt16(); // num_shorts2 sm.OPT_num_disconnectedTriangles = reader.ReadUInt16(); sm.OPT_off_triangleStrip = Pointer.Read(reader); // shorts2_offset (array of size num_shorts2) sm.OPT_off_disconnectedTriangles = Pointer.Read(reader); if (Settings.s.hasNames) { sm.name += reader.ReadString(0x34); } } else { sm.OPT_num_mapping_entries = 0; sm.OPT_off_mapping_vertices = null; sm.OPT_off_mapping_uvs = null; sm.OPT_num_triangleStrip = 0; sm.OPT_num_disconnectedTriangles = 0; sm.OPT_off_triangleStrip = null; sm.OPT_off_disconnectedTriangles = null; sm.isVisibleInPortal = 1; if (Settings.s.mode == Settings.Mode.RaymanArenaGCDemo) { sm.isVisibleInPortal = reader.ReadByte(); reader.ReadByte(); sm.OPT_num_mapping_entries = reader.ReadUInt16(); // num_shorts } } } else { // Defaults for Rayman 2, no optimized mesh feature sm.num_uvMaps = 1; sm.OPT_num_mapping_entries = 0; sm.OPT_off_mapping_vertices = null; sm.OPT_off_mapping_uvs = null; sm.OPT_num_triangleStrip = 0; sm.OPT_num_disconnectedTriangles = 0; sm.OPT_off_triangleStrip = null; sm.OPT_off_disconnectedTriangles = null; sm.isVisibleInPortal = 1; } // Read mapping tables sm.OPT_mapping_uvs = new int[sm.num_uvMaps][]; if (sm.OPT_num_mapping_entries > 0) { Pointer.Goto(ref reader, sm.OPT_off_mapping_vertices); //print("Mapping offset: " + String.Format("0x{0:X}", fs.Position)); sm.OPT_mapping_vertices = new int[sm.OPT_num_mapping_entries]; for (int j = 0; j < sm.OPT_num_mapping_entries; j++) { sm.OPT_mapping_vertices[j] = reader.ReadInt16(); } Pointer.Goto(ref reader, sm.OPT_off_mapping_uvs); for (int j = 0; j < sm.num_uvMaps; j++) { sm.OPT_mapping_uvs[j] = new int[sm.OPT_num_mapping_entries]; } for (int j = 0; j < sm.OPT_num_mapping_entries; j++) { for (int um = 0; um < sm.num_uvMaps; um++) { sm.OPT_mapping_uvs[um][j] = reader.ReadInt16(); } } } if (sm.num_triangles > 0) { Pointer.Goto(ref reader, sm.off_mapping_uvs); sm.mapping_uvs = new int[sm.num_uvMaps][]; for (int j = 0; j < sm.num_uvMaps; j++) { sm.mapping_uvs[j] = new int[sm.num_triangles * 3]; } // Why is uv maps here the outer loop instead of inner like the other thing? for (int um = 0; um < sm.num_uvMaps; um++) { for (int j = 0; j < sm.num_triangles * 3; j++) { sm.mapping_uvs[um][j] = reader.ReadInt16(); } } } // Read UVs Pointer.DoAt(ref reader, sm.off_uvs, () => { sm.uvs = new Vector2[sm.num_uvs]; for (int j = 0; j < sm.num_uvs; j++) { sm.uvs[j] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } }); // Read triangle data Pointer.DoAt(ref reader, sm.OPT_off_triangleStrip, () => { sm.OPT_triangleStrip = new int[sm.OPT_num_triangleStrip]; for (int j = 0; j < sm.OPT_num_triangleStrip; j++) { sm.OPT_triangleStrip[j] = reader.ReadInt16(); } }); Pointer.DoAt(ref reader, sm.OPT_off_disconnectedTriangles, () => { sm.OPT_disconnectedTriangles = new int[sm.OPT_num_disconnectedTriangles * 3]; //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position)); for (int j = 0; j < sm.OPT_num_disconnectedTriangles; j++) { sm.OPT_disconnectedTriangles[(j * 3) + 0] = reader.ReadInt16(); sm.OPT_disconnectedTriangles[(j * 3) + 1] = reader.ReadInt16(); sm.OPT_disconnectedTriangles[(j * 3) + 2] = reader.ReadInt16(); } }); if (sm.num_triangles > 0) { Pointer.Goto(ref reader, sm.off_triangles); sm.triangles = new int[sm.num_triangles * 3]; //print("Loading disconnected triangles at " + String.Format("0x{0:X}", fs.Position)); for (int j = 0; j < sm.num_triangles; j++) { sm.triangles[(j * 3) + 0] = reader.ReadInt16(); sm.triangles[(j * 3) + 1] = reader.ReadInt16(); sm.triangles[(j * 3) + 2] = reader.ReadInt16(); } if (sm.off_normals != null) { Pointer.Goto(ref reader, sm.off_normals); sm.normals = new Vector3[sm.num_triangles]; for (int j = 0; j < sm.num_triangles; j++) { float x = reader.ReadSingle(); float z = reader.ReadSingle(); float y = reader.ReadSingle(); sm.normals[j] = new Vector3(x, y, z); } } } if (Settings.s.game == Settings.Game.LargoWinch && sm.lightmap_index != -1) { LWLoader lwl = MapLoader.Loader as LWLoader; if (lwl.lms != null && sm.lightmap_index >= 0 && sm.lightmap_index < lwl.lms.Count) { /*if (sm.lightmap_index < l.off_lightmapUV.Length - 1) { * int amount = ((int)l.off_lightmapUV[sm.lightmap_index + 1].offset - (int)l.off_lightmapUV[sm.lightmap_index].offset); * amount = amount / 8; * l.print(offset + " - UVs: " + amount + " - " + sm.mesh.num_vertices + " - " + sm.num_mapping_entries + " - " + sm.num_uvs + " - " + sm.num_disconnected_triangles_spe + " - " + sm.num_mapping_lightmap); * }*/ Vector2[] lightmapUVs = new Vector2[sm.num_mapping_lightmap]; Pointer.DoAt(ref reader, sm.off_mapping_lightmap, () => { sm.mapping_lightmap = new int[sm.num_mapping_lightmap]; for (int i = 0; i < sm.num_mapping_lightmap; i++) { sm.mapping_lightmap[i] = reader.ReadInt16(); } }); Pointer.DoAt(ref reader, l.off_lightmapUV[sm.lightmap_index], () => { for (int j = 0; j < lightmapUVs.Length; j++) { lightmapUVs[j] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } }); sm.AddLightmap(lwl.GetLightmap(sm.lightmap_index), lightmapUVs); } } return(sm); }