Beispiel #1
0
        public SceneDataLoader(string fileName, WWorld world)
        {
            m_world = world;

            if (m_sActorDescriptors == null)
            {
                // Load the Actor Descriptors from disk.
                m_sActorDescriptors = new List <MapActorDescriptor>();
                foreach (var file in Directory.GetFiles("resources/templates/"))
                {
                    MapActorDescriptor descriptor = JsonConvert.DeserializeObject <MapActorDescriptor>(File.ReadAllText(file));
                    m_sActorDescriptors.Add(descriptor);
                }
            }

            m_reader    = new EndianBinaryReader(File.ReadAllBytes(fileName), System.Text.Encoding.ASCII, Endian.Big);
            m_chunkList = new List <ChunkHeader>();
            int chunkCount = m_reader.ReadInt32();

            for (int i = 0; i < chunkCount; i++)
            {
                string      fourCC = m_reader.ReadString(4);
                MapLayer    layer  = ChunkHeader.FourCCToLayer(ref fourCC);
                ChunkHeader chunk  = new ChunkHeader(fourCC, m_reader.ReadInt32(), m_reader.ReadInt32());
                chunk.Layer = layer;

                m_chunkList.Add(chunk);
            }

            var sortedList = m_chunkList.OrderBy(x => x.ChunkOffset);

            m_chunkList = new List <ChunkHeader>(sortedList);
        }
Beispiel #2
0
        public List <WActorNode> GetMapEntities()
        {
            var loadedActors = new List <WActorNode>();

            foreach (var chunk in m_chunkList)
            {
                m_reader.BaseStream.Position = chunk.ChunkOffset;
                MapActorDescriptor template = m_sActorDescriptors.Find(x => x.FourCC == chunk.FourCC);
                if (template == null)
                {
                    Console.WriteLine("Unsupported FourCC: {0}", chunk.FourCC);
                    continue;
                }

                switch (chunk.FourCC)
                {
                // Don't turn these into map actors, as they will be handled elsewhere.
                //case "RTBL":
                case "MECO":
                case "MEMA":
                    break;

                default:
                    for (int i = 0; i < chunk.ElementCount; i++)
                    {
                        var newActor = LoadActorFromChunk(chunk.FourCC, template);
                        newActor.Layer = chunk.Layer;

                        loadedActors.Add(newActor);
                    }
                    break;
                }
            }

            var dict = new Dictionary <string, List <WActorNode> >();

            foreach (var actor in loadedActors)
            {
                if (!dict.ContainsKey(actor.FourCC))
                {
                    dict[actor.FourCC] = new List <WActorNode>();
                }
                dict[actor.FourCC].Add(actor);
            }

            string[] nodes = new[] { "EnvR", "Pale", "Virt", "Colo" };
            foreach (var node in nodes)
            {
                if (dict.ContainsKey(node))
                {
                    Console.WriteLine("{0} Count: {1}", node, dict[node].Count);
                }
            }

            return(loadedActors);
        }
Beispiel #3
0
        public List <WDOMNode> GetMapEntities()
        {
            var loadedActors = new List <WDOMNode>();

            foreach (var chunk in m_chunkList)
            {
                m_reader.BaseStream.Position = chunk.ChunkOffset;
                MapActorDescriptor template = Globals.ActorDescriptors.Find(x => x.FourCC == chunk.FourCC);
                if (template == null)
                {
                    Console.WriteLine("Unsupported FourCC: {0}", chunk.FourCC);
                    continue;
                }

                switch (chunk.FourCC)
                {
                // Don't turn these into map actors, as they will be handled elsewhere.
                //case "RTBL":
                case FourCC.MECO:
                case FourCC.MEMA:
                    break;

                default:
                    for (int i = 0; i < chunk.ElementCount; i++)
                    {
                        Type actorType             = Type.GetType($"WindEditor.{template.ClassName}");
                        SerializableDOMNode entity = (SerializableDOMNode)Activator.CreateInstance(actorType, chunk.FourCC, m_world);
                        entity.Load(m_reader);
                        entity.PostLoad();
                        entity.Layer = chunk.Layer;

                        loadedActors.Add(entity);
                    }
                    break;
                }
            }

            // var dict = new Dictionary<string, List<WDOMNode>>();
            // foreach(var actor in loadedActors)
            // {
            //     if (!dict.ContainsKey(actor.FourCC))
            //         dict[actor.FourCC] = new List<WDOMNode>();
            //     dict[actor.FourCC].Add(actor);
            // }
            //
            // string[] nodes = new[] { "EnvR", "Pale", "Virt", "Colo" };
            // foreach(var node in nodes)
            // {
            //     if (dict.ContainsKey(node))
            //         Console.WriteLine("{0} Count: {1}", node, dict[node].Count);
            //
            // }

            return(loadedActors);
        }
Beispiel #4
0
        public WWindEditor()
        {
            // Add the default Editor World.
            m_editorWorlds.Add(new WWorld());

            // Load our global data
            foreach (var file in Directory.GetFiles("resources/templates/"))
            {
                MapActorDescriptor descriptor = JsonConvert.DeserializeObject <MapActorDescriptor>(File.ReadAllText(file));
                Globals.ActorDescriptors.Add(descriptor);
            }
        }
Beispiel #5
0
 public SceneDataExporter()
 {
     if (m_sActorDescriptors == null)
     {
         // Load the Actor Descriptors from disk.
         m_sActorDescriptors = new List <MapActorDescriptor>();
         foreach (var file in Directory.GetFiles("resources/templates/"))
         {
             MapActorDescriptor descriptor = JsonConvert.DeserializeObject <MapActorDescriptor>(File.ReadAllText(file));
             m_sActorDescriptors.Add(descriptor);
         }
     }
 }
        public List <WDOMNode> GetMapEntities()
        {
            var loadedActors = new List <WDOMNode>();

            foreach (var chunk in m_chunkList)
            {
                m_reader.BaseStream.Position = chunk.ChunkOffset;
                MapActorDescriptor template = Globals.ActorDescriptors.Find(x => x.FourCC == chunk.FourCC);
                if (template == null)
                {
                    Console.WriteLine("Unsupported FourCC: {0}", chunk.FourCC);
                    continue;
                }

                switch (chunk.FourCC)
                {
                // Don't turn these into map actors, as they will be handled elsewhere.
                //case "RTBL":
                case FourCC.MECO:
                case FourCC.MEMA:
                    break;

                case FourCC.SCOB:
                case FourCC.SCO0:
                case FourCC.SCO1:
                case FourCC.SCO2:
                case FourCC.SCO3:
                case FourCC.SCO4:
                case FourCC.SCO5:
                case FourCC.SCO6:
                case FourCC.SCO7:
                case FourCC.SCO8:
                case FourCC.SCO9:
                case FourCC.SCOa:
                case FourCC.SCOb:
                case FourCC.TGSC:
                    for (int i = 0; i < chunk.ElementCount; i++)
                    {
                        // We need to read the entity name so we can load the right derived class for it
                        string entity_name = Encoding.ASCII.GetString(m_reader.PeekReadBytes(8)).Trim('\0');

                        Type actorType             = WResourceManager.GetTypeByName(entity_name);
                        SerializableDOMNode entity = (SerializableDOMNode)Activator.CreateInstance(actorType, chunk.FourCC, m_world);

                        entity.Load(m_reader);
                        entity.Layer = chunk.Layer;

                        entity.Transform.LocalScale = new Vector3(m_reader.ReadByte() / 10f, m_reader.ReadByte() / 10f, m_reader.ReadByte() / 10f);
                        int padding = m_reader.ReadByte();

                        loadedActors.Add(entity);
                    }
                    break;

                case FourCC.ACTR:
                case FourCC.ACT0:
                case FourCC.ACT1:
                case FourCC.ACT2:
                case FourCC.ACT3:
                case FourCC.ACT4:
                case FourCC.ACT5:
                case FourCC.ACT6:
                case FourCC.ACT7:
                case FourCC.ACT8:
                case FourCC.ACT9:
                case FourCC.ACTa:
                case FourCC.ACTb:
                case FourCC.TGOB:
                case FourCC.TGDR:
                    for (int i = 0; i < chunk.ElementCount; i++)
                    {
                        // We need to read the entity name so we can load the right derived class for it
                        string entity_name = Encoding.ASCII.GetString(m_reader.PeekReadBytes(8)).Trim('\0');

                        Type actorType             = WResourceManager.GetTypeByName(entity_name);
                        SerializableDOMNode entity = (SerializableDOMNode)Activator.CreateInstance(actorType, chunk.FourCC, m_world);

                        entity.Load(m_reader);
                        entity.Layer = chunk.Layer;

                        loadedActors.Add(entity);
                    }
                    break;

                case FourCC.RTBL:
                    for (int i = 0; i < chunk.ElementCount; i++)
                    {
                        int entry_offset = m_reader.ReadInt32();

                        int next_offset = (int)m_reader.BaseStream.Position;
                        m_reader.BaseStream.Seek(entry_offset, SeekOrigin.Begin);

                        RoomTableEntryNode rtbl_entry = new RoomTableEntryNode(chunk.FourCC, m_world, m_reader);
                        loadedActors.Add(rtbl_entry);

                        m_reader.BaseStream.Seek(next_offset, SeekOrigin.Begin);
                    }

                    break;

                default:
                    for (int i = 0; i < chunk.ElementCount; i++)
                    {
                        Type actorType             = Type.GetType($"WindEditor.{template.ClassName}");
                        SerializableDOMNode entity = (SerializableDOMNode)Activator.CreateInstance(actorType, chunk.FourCC, m_world);
                        entity.Load(m_reader);
                        entity.Layer = chunk.Layer;

                        loadedActors.Add(entity);
                    }
                    break;
                }
            }

            // var dict = new Dictionary<string, List<WDOMNode>>();
            // foreach(var actor in loadedActors)
            // {
            //     if (!dict.ContainsKey(actor.FourCC))
            //         dict[actor.FourCC] = new List<WDOMNode>();
            //     dict[actor.FourCC].Add(actor);
            // }
            //
            // string[] nodes = new[] { "EnvR", "Pale", "Virt", "Colo" };
            // foreach(var node in nodes)
            // {
            //     if (dict.ContainsKey(node))
            //         Console.WriteLine("{0} Count: {1}", node, dict[node].Count);
            //
            // }

            AssignPaths(loadedActors);

            return(loadedActors);
        }
Beispiel #7
0
        public void ExportToStream(EndianBinaryWriter writer, WScene scene)
        {
            // Build a dictionary which lists unique FourCC's and a list of all relevant actors.
            var actorCategories = new Dictionary <string, List <WActorNode> >();

            foreach (var child in scene)
            {
                WActorNode actor = child as WActorNode;
                if (actor != null)
                {
                    string fixedFourCC = ChunkHeader.LayerToFourCC(actor.FourCC, actor.Layer);

                    if (!actorCategories.ContainsKey(fixedFourCC))
                    {
                        actorCategories[fixedFourCC] = new List <WActorNode>();
                    }

                    actorCategories[fixedFourCC].Add(actor);
                }
            }

            // Create a chunk header for each one.
            var chunkHeaders = new List <ChunkHeader>();

            foreach (var kvp in actorCategories)
            {
                ChunkHeader header = new ChunkHeader();
                header.FourCC       = kvp.Key;
                header.ElementCount = kvp.Value.Count;

                chunkHeaders.Add(header);
            }

            long chunkStart = writer.BaseStream.Position;

            // Write the Header
            writer.Write(chunkHeaders.Count);
            for (int i = 0; i < chunkHeaders.Count; i++)
            {
                writer.Write((int)0); // Dummy Placeholder values for the Chunk Header.
                writer.Write((int)0);
                writer.Write((int)0);
            }

            // For each chunk, write the data for that chunk. Before writing the data, get the current offset and update the header.
            List <WActorNode>[] dictionaryData = new List <WActorNode> [actorCategories.Count];
            actorCategories.Values.CopyTo(dictionaryData, 0);

            for (int i = 0; i < chunkHeaders.Count; i++)
            {
                ChunkHeader header = chunkHeaders[i];
                chunkHeaders[i] = new ChunkHeader(header.FourCC, header.ElementCount, (int)(writer.BaseStream.Position - chunkStart));

                List <WActorNode> actors = dictionaryData[i];
                foreach (var actor in actors)
                {
                    MapActorDescriptor template = m_sActorDescriptors.Find(x => x.FourCC == actor.FourCC);
                    if (template == null)
                    {
                        Console.WriteLine("Unsupported FourCC (\"{0}\") for exporting!", actor.FourCC);
                        continue;
                    }

                    WriteActorToChunk(actor, template, writer);
                }
            }

            // Now that we've written every actor to file we can go back and re-write the headers now that we know their offsets.
            writer.BaseStream.Position = chunkStart + 0x4; // 0x4 is the offset to the Chunk Headers
            foreach (var header in chunkHeaders)
            {
                writer.WriteFixedString(header.FourCC, 4); // FourCC
                writer.Write(header.ElementCount);         // Number of Entries
                writer.Write(header.ChunkOffset);          // Offset from start of file.
            }

            // Seek to the end of the file, and then pad us to 32-byte alignment.
            writer.BaseStream.Seek(0, SeekOrigin.End);
            int delta = WMath.Pad32Delta(writer.BaseStream.Position);

            for (int i = 0; i < delta; i++)
            {
                writer.Write((byte)0xFF);
            }
        }
Beispiel #8
0
        private void WriteActorToChunk(WActorNode actor, MapActorDescriptor template, EndianBinaryWriter writer)
        {
            // Just convert their rotation to Euler Angles now instead of doing it in parts later.
            Vector3 eulerRot = actor.Transform.Rotation.ToEulerAngles();

            foreach (var field in template.Fields)
            {
                IPropertyValue propValue = actor.Properties.Find(x => x.Name == field.FieldName);
                if (field.FieldName == "Position")
                {
                    propValue = new TVector3PropertyValue(actor.Transform.Position, "Position");
                }
                else if (field.FieldName == "X Rotation")
                {
                    short xRotShort = WMath.RotationFloatToShort(eulerRot.X);
                    propValue = new TShortPropertyValue(xRotShort, "X Rotation");
                }
                else if (field.FieldName == "Y Rotation")
                {
                    short yRotShort = WMath.RotationFloatToShort(eulerRot.Y);
                    propValue = new TShortPropertyValue(yRotShort, "Y Rotation");
                }
                else if (field.FieldName == "Z Rotation")
                {
                    short zRotShort = WMath.RotationFloatToShort(eulerRot.Z);
                    propValue = new TShortPropertyValue(zRotShort, "Z Rotation");
                }
                else if (field.FieldName == "X Scale")
                {
                    float xScale = actor.Transform.LocalScale.X;
                    propValue = new TBytePropertyValue((byte)(xScale * 10), "X Scale");
                }
                else if (field.FieldName == "Y Scale")
                {
                    float yScale = actor.Transform.LocalScale.Y;
                    propValue = new TBytePropertyValue((byte)(yScale * 10), "Y Scale");
                }
                else if (field.FieldName == "Z Scale")
                {
                    float zScale = actor.Transform.LocalScale.Z;
                    propValue = new TBytePropertyValue((byte)(zScale * 10), "Z Scale");
                }

                switch (field.FieldType)
                {
                case PropertyValueType.Byte:
                    writer.Write((byte)propValue.GetValue()); break;

                case PropertyValueType.Bool:
                    writer.Write((bool)propValue.GetValue()); break;

                case PropertyValueType.Short:
                    writer.Write((short)propValue.GetValue()); break;

                case PropertyValueType.Int:
                    writer.Write((int)propValue.GetValue()); break;

                case PropertyValueType.Float:
                    writer.Write((float)propValue.GetValue()); break;

                case PropertyValueType.String:
                    writer.Write(System.Text.Encoding.ASCII.GetBytes((string)propValue.GetValue())); break;

                case PropertyValueType.FixedLengthString:
                    string fixedLenStr = (string)propValue.GetValue();
                    for (int i = 0; i < field.Length; i++)
                    {
                        writer.Write(i < fixedLenStr.Length ? (byte)fixedLenStr[i] : (byte)0);
                    }
                    //writer.WriteFixedString((string)propValue.GetValue(), (int)field.Length); break;
                    break;

                case PropertyValueType.Vector2:
                    Vector2 vec2Val = (Vector2)propValue.GetValue();
                    writer.Write(vec2Val.X);
                    writer.Write(vec2Val.Y);
                    break;

                case PropertyValueType.Vector3:
                    Vector3 vec3Val = (Vector3)propValue.GetValue();
                    writer.Write(vec3Val.X);
                    writer.Write(vec3Val.Y);
                    writer.Write(vec3Val.Z);
                    break;

                case PropertyValueType.XRotation:
                case PropertyValueType.YRotation:
                case PropertyValueType.ZRotation:
                    writer.Write((short)propValue.GetValue()); break;

                case PropertyValueType.Color24:
                    WLinearColor color24 = (WLinearColor)propValue.GetValue();
                    writer.Write((byte)color24.R);
                    writer.Write((byte)color24.G);
                    writer.Write((byte)color24.B);
                    break;

                case PropertyValueType.Color32:
                    WLinearColor color32 = (WLinearColor)propValue.GetValue();
                    writer.Write((byte)color32.R);
                    writer.Write((byte)color32.G);
                    writer.Write((byte)color32.B);
                    writer.Write((byte)color32.A);
                    break;

                default:
                    Console.WriteLine("Unsupported PropertyValueType: {0}", field.FieldType);
                    break;
                }
            }
        }
Beispiel #9
0
        public void CreateEntity(string fourCC)
        {
            if (m_world.Map == null || m_world.Map.FocusedScene == null)
            {
                return;
            }

            var actorDescriptors = new List <MapActorDescriptor>();

            foreach (var file in Directory.GetFiles("resources/templates/"))
            {
                MapActorDescriptor descriptor = JsonConvert.DeserializeObject <MapActorDescriptor>(File.ReadAllText(file));
                actorDescriptors.Add(descriptor);
            }

            MapActorDescriptor entityDescriptor = actorDescriptors.Find(x => string.Compare(x.FourCC, fourCC, true) == 0);

            if (entityDescriptor == null)
            {
                Console.WriteLine("Attempted to spawn unsupported FourCC: {0}", fourCC);
                return;
            }

            List <IPropertyValue> actorProperties = new List <IPropertyValue>();

            foreach (var field in entityDescriptor.Fields)
            {
                switch (field.FieldName)
                {
                case "Position":
                case "X Rotation":
                case "Y Rotation":
                case "Z Rotation":
                case "X Scale":
                case "Y Scale":
                case "Z Scale":
                    continue;
                }

                IPropertyValue propValue = null;
                switch (field.FieldType)
                {
                case PropertyValueType.Byte:
                    propValue = new TBytePropertyValue(0, field.FieldName);
                    break;

                case PropertyValueType.Bool:
                    propValue = new TBoolPropertyValue(false, field.FieldName);
                    break;

                case PropertyValueType.Short:
                    propValue = new TShortPropertyValue(0, field.FieldName);
                    break;

                case PropertyValueType.Int:
                    propValue = new TIntPropertyValue(0, field.FieldName);
                    break;

                case PropertyValueType.Float:
                    propValue = new TFloatPropertyValue(0f, field.FieldName);
                    break;

                case PropertyValueType.FixedLengthString:
                case PropertyValueType.String:
                    propValue = new TStringPropertyValue("", field.FieldName);
                    break;

                case PropertyValueType.Vector2:
                    propValue = new TVector2PropertyValue(new OpenTK.Vector2(0f, 0f), field.FieldName);
                    break;

                case PropertyValueType.Vector3:
                    propValue = new TVector3PropertyValue(new OpenTK.Vector3(0f, 0f, 0f), field.FieldName);
                    break;

                case PropertyValueType.XRotation:
                case PropertyValueType.YRotation:
                case PropertyValueType.ZRotation:
                    propValue = new TShortPropertyValue(0, field.FieldName);
                    break;

                case PropertyValueType.Color24:
                    propValue = new TLinearColorPropertyValue(new WLinearColor(1f, 1f, 1f), field.FieldName);
                    break;

                case PropertyValueType.Color32:
                    propValue = new TLinearColorPropertyValue(new WLinearColor(1f, 1f, 1f, 1f), field.FieldName);
                    break;

                default:
                    Console.WriteLine("Unsupported PropertyValueType: {0}", field.FieldType);
                    break;
                }

                propValue.SetUndoStack(m_world.UndoStack);
                actorProperties.Add(propValue);
            }

            var newActor = new WActorNode(fourCC, m_world);

            newActor.Transform.Position = new OpenTK.Vector3(0, 200, 0);

            newActor.SetParent(m_world.Map.FocusedScene);
            newActor.Properties.AddRange(actorProperties);
            newActor.PostFinishedLoad();

            ModifySelection(SelectionType.Add, newActor, true);
        }
Beispiel #10
0
        public static Type GetTypeFromEnum(FourCC value)
        {
            MapActorDescriptor template = Globals.ActorDescriptors.Find(x => x.FourCC == value);

            return(Type.GetType($"WindEditor.{template.ClassName}"));
        }
Beispiel #11
0
        public List <EnvironmentLighting> GetLightingData()
        {
            // Bah...
            var loadedActors = new List <WActorNode>();

            foreach (var chunk in m_chunkList)
            {
                m_reader.BaseStream.Position = chunk.ChunkOffset;
                MapActorDescriptor template = m_sActorDescriptors.Find(x => x.FourCC == chunk.FourCC);
                if (template == null)
                {
                    Console.WriteLine("Unsupported FourCC: {0}", chunk.FourCC);
                    continue;
                }

                switch (chunk.FourCC)
                {
                // We're only going to re-load the lighting-based actors...
                case "EnvR":
                case "Colo":
                case "Pale":
                case "Virt":
                    for (int i = 0; i < chunk.ElementCount; i++)
                    {
                        var newActor = LoadActorFromChunk(chunk.FourCC, template);
                        newActor.Layer = chunk.Layer;

                        loadedActors.Add(newActor);
                    }
                    break;
                }
            }

            var dict = new Dictionary <string, List <WActorNode> >();

            foreach (var actor in loadedActors)
            {
                if (!dict.ContainsKey(actor.FourCC))
                {
                    dict[actor.FourCC] = new List <WActorNode>();
                }
                dict[actor.FourCC].Add(actor);
            }

            // Load Skybox Lighting Data
            var virtList = new List <LightingSkyboxColors>();
            var paleList = new List <LightingPalette>();
            var coloList = new List <LightingTimePreset>();

            if (dict.ContainsKey("virt") && dict.ContainsKey("pale") && dict.ContainsKey("Colo"))
            {
                foreach (var virt in dict["Virt"])
                {
                    WLinearColor unknown1, unknown2, unknown3, unknown4, horizonCloud, centerCloud, sky, falseSea, horizon;

                    virt.TryGetValue("Unknown 1", out unknown1);
                    virt.TryGetValue("Unknown 2", out unknown2);
                    virt.TryGetValue("Unknown 3", out unknown3);
                    virt.TryGetValue("Unknown 4", out unknown4);
                    virt.TryGetValue("Horizon Cloud Color", out horizonCloud);
                    virt.TryGetValue("Center Cloud Color", out centerCloud);
                    virt.TryGetValue("Sky Color", out sky);
                    virt.TryGetValue("False Sea Color", out falseSea);
                    virt.TryGetValue("Horizon Color", out horizon);

                    LightingSkyboxColors virtEntry = new LightingSkyboxColors
                    {
                        Unknown1     = unknown1,
                        Unknown2     = unknown2,
                        Unknown3     = unknown3,
                        Unknown4     = unknown4,
                        HorizonCloud = horizonCloud,
                        CenterCloud  = centerCloud,
                        Sky          = sky,
                        FalseSea     = falseSea,
                        Horizon      = horizon
                    };

                    virtList.Add(virtEntry);
                }

                foreach (var pale in dict["Pale"])
                {
                    WLinearColor shadow, actorAmbient, roomLight, roomAmbient, wave, ocean, unknown1, unknown2, doorway, unknown3, fog;
                    byte         virtIndex; float fogFarPlane, fogNearPlane;
                    pale.TryGetValue("Shadow Color", out shadow);
                    pale.TryGetValue("Actor Ambient Color", out actorAmbient);
                    pale.TryGetValue("Room Light Color", out roomLight);
                    pale.TryGetValue("Room Ambient Color", out roomAmbient);
                    pale.TryGetValue("Wave Color", out wave);
                    pale.TryGetValue("Ocean Color", out ocean);
                    pale.TryGetValue("Unknown White 1", out unknown1);
                    pale.TryGetValue("Unknown White 2", out unknown2);
                    pale.TryGetValue("Door Backfill", out doorway);
                    pale.TryGetValue("Unknown 3", out unknown3);
                    pale.TryGetValue("Fog Color", out fog);
                    pale.TryGetValue("Skybox Color Index", out virtIndex);
                    pale.TryGetValue("Fog Far Plane", out fogFarPlane);
                    pale.TryGetValue("Fog Near Plane", out fogNearPlane);

                    LightingPalette lightPalette = new LightingPalette
                    {
                        Shadow        = shadow,
                        ActorAmbient  = actorAmbient,
                        RoomLight     = roomLight,
                        RoomAmbient   = roomAmbient,
                        WaveColor     = wave,
                        OceanColor    = ocean,
                        UnknownWhite1 = unknown1,
                        UnknownWhite2 = unknown2,
                        Doorway       = doorway,
                        UnknownColor3 = unknown3,
                        Skybox        = virtList[virtIndex],
                        Fog           = fog,
                        FogNearPlane  = fogNearPlane,
                        FogFarPlane   = fogFarPlane,
                    };

                    paleList.Add(lightPalette);
                }

                foreach (var colo in dict["Colo"])
                {
                    byte[] setA = new byte[6];
                    byte[] setB = new byte[6];

                    colo.TryGetValue("Dawn A", out setA[0]);
                    colo.TryGetValue("Morning A", out setA[1]);
                    colo.TryGetValue("Noon A", out setA[2]);
                    colo.TryGetValue("Afternoon A", out setA[3]);
                    colo.TryGetValue("Dusk A", out setA[4]);
                    colo.TryGetValue("Night A", out setA[5]);

                    colo.TryGetValue("Dawn B", out setB[0]);
                    colo.TryGetValue("Morning B", out setB[1]);
                    colo.TryGetValue("Noon B", out setB[2]);
                    colo.TryGetValue("Afternoon B", out setB[3]);
                    colo.TryGetValue("Dusk B", out setB[4]);
                    colo.TryGetValue("Night B", out setB[5]);

                    LightingTimePreset timePreset = new LightingTimePreset();
                    for (int i = 0; i < 6; i++)
                    {
                        timePreset.TimePresetA[i] = paleList[setA[i]];
                    }

                    //for (int i = 0; i < 6; i++)
                    //timePreset.TimePresetB[i] = paleList[setB[i]];
                    coloList.Add(timePreset);
                }
            }


            var envrList = new List <EnvironmentLighting>();

            if (paleList.Count > 0 && coloList.Count > 0)
            {
                foreach (var envr in dict["EnvR"])
                {
                    byte[] setA = new byte[4];
                    byte[] setB = new byte[4];

                    envr.TryGetValue("Clear Color A", out setA[0]);
                    envr.TryGetValue("Raining Color A", out setA[1]);
                    envr.TryGetValue("Snowing A", out setA[2]);
                    envr.TryGetValue("Unknown A", out setA[3]);

                    envr.TryGetValue("Clear Color B", out setB[0]);
                    envr.TryGetValue("Raining Color B", out setB[1]);
                    envr.TryGetValue("Snowing B", out setB[2]);
                    envr.TryGetValue("Unknown B", out setB[3]);

                    EnvironmentLighting envrPreset = new EnvironmentLighting();
                    for (int i = 0; i < 4; i++)
                    {
                        envrPreset.WeatherA[i] = coloList[setA[i]];
                    }

                    for (int i = 0; i < 4; i++)
                    {
                        envrPreset.WeatherB[i] = coloList[setB[i]];
                    }
                    envrList.Add(envrPreset);
                }
            }

            return(envrList);
        }
Beispiel #12
0
        private WActorNode LoadActorFromChunk(string fourCC, MapActorDescriptor template)
        {
            var newActor = new WActorNode(fourCC, m_world);
            List <IPropertyValue> actorProperties = new List <IPropertyValue>();

            foreach (var field in template.Fields)
            {
                IPropertyValue propValue = null;

                switch (field.FieldType)
                {
                case PropertyValueType.Byte:
                    propValue = new TBytePropertyValue(m_reader.ReadByte(), field.FieldName);
                    break;

                case PropertyValueType.Bool:
                    propValue = new TBoolPropertyValue(m_reader.ReadBoolean(), field.FieldName);
                    break;

                case PropertyValueType.Short:
                    propValue = new TShortPropertyValue(m_reader.ReadInt16(), field.FieldName);
                    break;

                case PropertyValueType.Int:
                    propValue = new TIntPropertyValue(m_reader.ReadInt32(), field.FieldName);
                    break;

                case PropertyValueType.Float:
                    propValue = new TFloatPropertyValue(m_reader.ReadSingle(), field.FieldName);
                    break;

                case PropertyValueType.FixedLengthString:
                case PropertyValueType.String:
                    string stringVal = (field.Length == 0) ? m_reader.ReadStringUntil('\0') : m_reader.ReadString(field.Length);
                    stringVal = stringVal.Trim(new[] { '\0' });
                    propValue = new TStringPropertyValue(stringVal, field.FieldName);
                    break;

                case PropertyValueType.Vector2:
                    propValue = new TVector2PropertyValue(new OpenTK.Vector2(m_reader.ReadSingle(), m_reader.ReadSingle()), field.FieldName);
                    break;

                case PropertyValueType.Vector3:
                    propValue = new TVector3PropertyValue(new OpenTK.Vector3(m_reader.ReadSingle(), m_reader.ReadSingle(), m_reader.ReadSingle()), field.FieldName);
                    break;

                case PropertyValueType.XRotation:
                case PropertyValueType.YRotation:
                case PropertyValueType.ZRotation:
                    propValue = new TShortPropertyValue(m_reader.ReadInt16(), field.FieldName);
                    break;

                case PropertyValueType.Color24:
                    propValue = new TLinearColorPropertyValue(new WLinearColor(m_reader.ReadByte() / 255f, m_reader.ReadByte() / 255f, m_reader.ReadByte() / 255f), field.FieldName);
                    break;

                case PropertyValueType.Color32:
                    propValue = new TLinearColorPropertyValue(new WLinearColor(m_reader.ReadByte() / 255f, m_reader.ReadByte() / 255f, m_reader.ReadByte() / 255f, m_reader.ReadByte() / 255f), field.FieldName);
                    break;

                default:
                    Console.WriteLine("Unsupported PropertyValueType: {0}", field.FieldType);
                    break;
                }

                propValue.SetUndoStack(m_world.UndoStack);
                actorProperties.Add(propValue);
            }

            // Now that we have loaded all properties out of it, we need to post-process them.
            IPropertyValue positionProperty = actorProperties.Find(x => x.Name == "Position");
            IPropertyValue xRotProperty     = actorProperties.Find(x => x.Name == "X Rotation");
            IPropertyValue yRotProperty     = actorProperties.Find(x => x.Name == "Y Rotation");
            IPropertyValue zRotProperty     = actorProperties.Find(x => x.Name == "Z Rotation");
            IPropertyValue xScaleProperty   = actorProperties.Find(x => x.Name == "X Scale");
            IPropertyValue yScaleProperty   = actorProperties.Find(x => x.Name == "Y Scale");
            IPropertyValue zScaleProperty   = actorProperties.Find(x => x.Name == "Z Scale");

            // Remove these properties from the actor so they don't get added to the UI.
            actorProperties.Remove(positionProperty);
            actorProperties.Remove(xRotProperty);
            actorProperties.Remove(yRotProperty);
            actorProperties.Remove(zRotProperty);
            actorProperties.Remove(xScaleProperty);
            actorProperties.Remove(yScaleProperty);
            actorProperties.Remove(zScaleProperty);

            if (positionProperty != null)
            {
                newActor.Transform.Position = (Vector3)positionProperty.GetValue();
            }

            float xRot = 0, yRot = 0, zRot = 0;

            if (xRotProperty != null)
            {
                xRot = WMath.RotationShortToFloat((short)xRotProperty.GetValue());
            }
            if (yRotProperty != null)
            {
                yRot = WMath.RotationShortToFloat((short)yRotProperty.GetValue());
            }
            if (zRotProperty != null)
            {
                zRot = WMath.RotationShortToFloat((short)zRotProperty.GetValue());
            }

            // Build rotation with ZYX order.
            Quaternion xRotQ = Quaternion.FromAxisAngle(new Vector3(1, 0, 0), WMath.DegreesToRadians(xRot));
            Quaternion yRotQ = Quaternion.FromAxisAngle(new Vector3(0, 1, 0), WMath.DegreesToRadians(yRot));
            Quaternion zRotQ = Quaternion.FromAxisAngle(new Vector3(0, 0, 1), WMath.DegreesToRadians(zRot));

            newActor.Transform.Rotation = zRotQ * yRotQ * xRotQ;

            float xScale = 1, yScale = 1, zScale = 1;

            if (xScaleProperty != null)
            {
                xScale = ((byte)xScaleProperty.GetValue()) / 10f;
            }
            if (yScaleProperty != null)
            {
                yScale = ((byte)yScaleProperty.GetValue()) / 10f;
            }
            if (zScaleProperty != null)
            {
                zScale = ((byte)zScaleProperty.GetValue()) / 10f;
            }

            newActor.Transform.LocalScale = new Vector3(xScale, yScale, zScale);

            newActor.Properties.AddRange(actorProperties);
            newActor.PostFinishedLoad();
            return(newActor);
        }
Beispiel #13
0
        public void ExportToStream(EndianBinaryWriter writer, WScene scene)
        {
            // Build a dictionary which lists unique FourCC's and a list of all relevant actors.
            var actorCategories = new Dictionary <FourCC, List <SerializableDOMNode> >();

            foreach (var child in scene)
            {
                var groupNode = child as WDOMGroupNode;
                if (groupNode == null)
                {
                    continue;
                }

                // If this is an ACTR, SCOB, or TRES group node, we have to dig into it to get the layers.
                if (groupNode.FourCC == FourCC.ACTR || groupNode.FourCC == FourCC.SCOB || groupNode.FourCC == FourCC.TRES)
                {
                    foreach (var layer in groupNode.Children)
                    {
                        foreach (var obj in layer.Children)
                        {
                            var actor = obj as SerializableDOMNode;

                            if (actor != null)
                            {
                                AddObjectToDictionary(actor, actorCategories);
                            }
                        }
                    }
                }
                else
                {
                    foreach (var obj in groupNode.Children)
                    {
                        var actor = obj as SerializableDOMNode;

                        if (actor != null)
                        {
                            AddObjectToDictionary(actor, actorCategories);
                        }
                    }
                }
            }

            // Create a chunk header for each one.
            var chunkHeaders = new List <ChunkHeader>();

            foreach (var kvp in actorCategories)
            {
                ChunkHeader header = new ChunkHeader();
                header.FourCC       = kvp.Key;
                header.ElementCount = kvp.Value.Count;

                chunkHeaders.Add(header);
            }

            long chunkStart = writer.BaseStream.Position;

            // Write the Header
            writer.Write(chunkHeaders.Count);
            for (int i = 0; i < chunkHeaders.Count; i++)
            {
                writer.Write((int)0); // Dummy Placeholder values for the Chunk Header.
                writer.Write((int)0);
                writer.Write((int)0);
            }

            // For each chunk, write the data for that chunk. Before writing the data, get the current offset and update the header.
            List <SerializableDOMNode>[] dictionaryData = new List <SerializableDOMNode> [actorCategories.Count];
            actorCategories.Values.CopyTo(dictionaryData, 0);

            for (int i = 0; i < chunkHeaders.Count; i++)
            {
                ChunkHeader header = chunkHeaders[i];
                chunkHeaders[i] = new ChunkHeader(header.FourCC, header.ElementCount, (int)(writer.BaseStream.Position - chunkStart));

                List <SerializableDOMNode> actors = dictionaryData[i];
                foreach (var actor in actors)
                {
                    MapActorDescriptor template = Globals.ActorDescriptors.Find(x => x.FourCC == actor.FourCC);
                    if (template == null)
                    {
                        Console.WriteLine("Unsupported FourCC (\"{0}\") for exporting!", actor.FourCC);
                        continue;
                    }

                    actor.PreSave();

                    actor.Save(writer);
                    //WriteActorToChunk(actor, template, writer);
                }
            }

            // Now that we've written every actor to file we can go back and re-write the headers now that we know their offsets.
            writer.BaseStream.Position = chunkStart + 0x4; // 0x4 is the offset to the Chunk Headers
            foreach (var header in chunkHeaders)
            {
                writer.WriteFixedString(FourCCConversion.GetStringFromEnum(header.FourCC), 4); // FourCC
                writer.Write(header.ElementCount);                                             // Number of Entries
                writer.Write(header.ChunkOffset);                                              // Offset from start of file.
            }

            // Seek to the end of the file, and then pad us to 32-byte alignment.
            writer.BaseStream.Seek(0, SeekOrigin.End);
            int delta = WMath.Pad32Delta(writer.BaseStream.Position);

            for (int i = 0; i < delta; i++)
            {
                writer.Write(0xFF);
            }
        }