Пример #1
0
        /// <summary>
        /// Add misc block flats.
        /// Batching is conditionally supported.
        /// </summary>
        public static void AddMiscBlockFlats(
            ref DFBlock blockData,
            Transform flatsParent,
            DaggerfallBillboardBatch animalsBillboardBatch = null,
            TextureAtlasBuilder miscBillboardsAtlas        = null,
            DaggerfallBillboardBatch miscBillboardsBatch   = null)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return;
            }

            // Add block flats
            foreach (DFBlock.RmbBlockFlatObjectRecord obj in blockData.RmbBlock.MiscFlatObjectRecords)
            {
                // Ignore lights as they are handled by AddLights()
                if (obj.TextureArchive == TextureReader.LightsTextureArchive)
                {
                    continue;
                }

                // Calculate position
                Vector3 billboardPosition = new Vector3(
                    obj.XPos,
                    -obj.YPos + blockFlatsOffsetY,
                    obj.ZPos + BlocksFile.RMBDimension) * MeshReader.GlobalScale;

                // Import custom 3d gameobject instead of flat
                if (MeshReplacement.ImportCustomFlatGameobject(obj.TextureArchive, obj.TextureRecord, billboardPosition, flatsParent) != null)
                {
                    continue;
                }

                // Use misc billboard atlas where available
                if (miscBillboardsAtlas != null && miscBillboardsBatch != null)
                {
                    TextureAtlasBuilder.AtlasItem item = miscBillboardsAtlas.GetAtlasItem(obj.TextureArchive, obj.TextureRecord);
                    if (item.key != -1)
                    {
                        miscBillboardsBatch.AddItem(item.rect, item.textureItem.size, item.textureItem.scale, billboardPosition);
                        continue;
                    }
                }

                // Add to batch where available
                if (obj.TextureArchive == TextureReader.AnimalsTextureArchive && animalsBillboardBatch != null)
                {
                    animalsBillboardBatch.AddItem(obj.TextureRecord, billboardPosition);
                    continue;
                }

                // Add standalone billboard gameobject
                GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(obj.TextureArchive, obj.TextureRecord, flatsParent);
                go.transform.position = billboardPosition;
                AlignBillboardToBase(go);
            }
        }
Пример #2
0
        /// <summary>
        /// TEMP: Creates super-atlas populated with all archives in array.
        /// Currently does not support animated textures, normal map, or emission map.
        /// TODO: Integrate this feature fully with material system.
        /// </summary>
        /// <param name="archives">Archive array.</param>
        /// <param name="borderSize">Number of pixels border to add around image.</param>
        /// <param name="dilate">Blend texture into surrounding empty pixels. Requires border.</param>
        /// <param name="maxAtlasSize">Maximum atlas size.</param>
        /// <param name="alphaTextureFormat">Alpha TextureFormat.</param>
        /// <param name="nonAlphaFormat">Non-alpha TextureFormat.</param>
        /// <returns>TextureAtlasBuilder.</returns>
        public TextureAtlasBuilder CreateTextureAtlasBuilder(
            int[] archives,
            int borderSize   = 0,
            bool dilate      = false,
            int maxAtlasSize = 2048,
            SupportedAlphaTextureFormats alphaTextureFormat = SupportedAlphaTextureFormats.RGBA32,
            SupportedNonAlphaTextureFormats nonAlphaFormat  = SupportedNonAlphaTextureFormats.RGB24)
        {
            // Iterate archives
            TextureFile         textureFile = new TextureFile();
            TextureAtlasBuilder builder     = new TextureAtlasBuilder();
            GetTextureSettings  settings    = TextureReader.CreateTextureSettings(0, 0, 0, 0, borderSize, dilate, maxAtlasSize);

            settings.stayReadable = true;
            for (int i = 0; i < archives.Length; i++)
            {
                // Load texture file
                settings.archive = archives[i];
                textureFile.Load(Path.Combine(Arena2Path, TextureFile.IndexToFileName(settings.archive)), FileUsage.UseMemory, true);

                // Add all records for this archive - single frame only
                for (int record = 0; record < textureFile.RecordCount; record++)
                {
                    settings.record = record;
                    GetTextureResults results = GetTexture2D(settings, alphaTextureFormat, nonAlphaFormat);
                    DFSize            size    = textureFile.GetSize(record);
                    DFSize            scale   = textureFile.GetScale(record);
                    builder.AddTextureItem(
                        results.albedoMap,
                        settings.archive,
                        settings.record,
                        0, 1,
                        new Vector2(size.Width, size.Height),
                        new Vector2(scale.Width, scale.Height));
                }
            }

            // Apply the builder
            builder.Rebuild(borderSize);

            return(builder);
        }
Пример #3
0
        /// <summary>
        /// Layout RMB block gamne object from name only.
        /// This will be missing information like building data and should only be used standalone.
        /// </summary>
        public static GameObject CreateRMBBlockGameObject(
            string blockName,
            int layoutX,
            int layoutY,
            bool addGroundPlane          = true,
            DaggerfallRMBBlock cloneFrom = null,
            DaggerfallBillboardBatch natureBillboardBatch  = null,
            DaggerfallBillboardBatch lightsBillboardBatch  = null,
            DaggerfallBillboardBatch animalsBillboardBatch = null,
            TextureAtlasBuilder miscBillboardAtlas         = null,
            DaggerfallBillboardBatch miscBillboardBatch    = null,
            ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland,
            ClimateSeason climateSeason     = ClimateSeason.Summer)
        {
            // Get block data from name
            DFBlock blockData;

            if (!RMBLayout.GetBlockData(blockName, out blockData))
            {
                return(null);
            }

            // Create base object from block data
            GameObject go = CreateRMBBlockGameObject(
                blockData,
                layoutX,
                layoutY,
                addGroundPlane,
                cloneFrom,
                natureBillboardBatch,
                lightsBillboardBatch,
                animalsBillboardBatch,
                miscBillboardAtlas,
                miscBillboardBatch,
                climateNature,
                climateSeason);

            return(go);
        }
Пример #4
0
        /// <summary>
        /// Add misc block flats.
        /// Batching is conditionally supported.
        /// </summary>
        public static void AddMiscBlockFlats(
            ref DFBlock blockData,
            Transform flatsParent,
            DaggerfallBillboardBatch animalsBillboardBatch = null,
            TextureAtlasBuilder miscBillboardsAtlas        = null,
            DaggerfallBillboardBatch miscBillboardsBatch   = null)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return;
            }

            // Add block flats
            foreach (DFBlock.RmbBlockFlatObjectRecord obj in blockData.RmbBlock.MiscFlatObjectRecords)
            {
                // Ignore lights as they are handled by AddLights()
                if (obj.TextureArchive == TextureReader.LightsTextureArchive)
                {
                    continue;
                }

                // Calculate position
                Vector3 billboardPosition = new Vector3(
                    obj.XPos,
                    -obj.YPos + blockFlatsOffsetY,
                    obj.ZPos + BlocksFile.RMBDimension) * MeshReader.GlobalScale;

                // Import custom 3d gameobject instead of flat
                if (MeshReplacement.ImportCustomFlatGameobject(obj.TextureArchive, obj.TextureRecord, billboardPosition, flatsParent) != null)
                {
                    continue;
                }

                //// Use misc billboard atlas where available
                //if (miscBillboardsAtlas != null && miscBillboardsBatch != null)
                //{
                //    TextureAtlasBuilder.AtlasItem item = miscBillboardsAtlas.GetAtlasItem(obj.TextureArchive, obj.TextureRecord);
                //    if (item.key != -1)
                //    {
                //        miscBillboardsBatch.AddItem(item.rect, item.textureItem.size, item.textureItem.scale, billboardPosition);
                //        continue;
                //    }
                //}

                // Add to batch where available
                //if (obj.TextureArchive == TextureReader.AnimalsTextureArchive && animalsBillboardBatch != null)
                //{
                //    animalsBillboardBatch.AddItem(obj.TextureRecord, billboardPosition);
                //    continue;
                //}

                // Add standalone billboard gameobject
                GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(obj.TextureArchive, obj.TextureRecord, flatsParent);
                go.transform.position = billboardPosition;
                AlignBillboardToBase(go);

                // Add animal sound
                if (obj.TextureArchive == TextureReader.AnimalsTextureArchive)
                {
                    AddAnimalAudioSource(go);
                }

                // If flat record has a non-zero faction id, then it's an exterior NPC
                if (obj.FactionID != 0)
                {
                    // Add RMB data to billboard
                    DaggerfallBillboard dfBillboard = go.GetComponent <DaggerfallBillboard>();
                    dfBillboard.SetRMBPeopleData(obj.FactionID, obj.Flags, obj.Position);

                    // Add StaticNPC behaviour
                    StaticNPC npc = go.AddComponent <StaticNPC>();
                    npc.SetLayoutData(obj);
                }
            }
        }
        /// <summary>
        /// TEMP: Creates super-atlas populated with all archives in array.
        /// Currently does not support animated textures, normal map, or emission map.
        /// TODO: Integrate this feature fully with material system.
        /// </summary>
        /// <param name="archives">Archive array.</param>
        /// <param name="borderSize">Number of pixels border to add around image.</param>
        /// <param name="dilate">Blend texture into surrounding empty pixels. Requires border.</param>
        /// <param name="maxAtlasSize">Maximum atlas size.</param>
        /// <param name="alphaTextureFormat">Alpha TextureFormat.</param>
        /// <param name="nonAlphaFormat">Non-alpha TextureFormat.</param>
        /// <returns>TextureAtlasBuilder.</returns>
        public TextureAtlasBuilder CreateTextureAtlasBuilder(
            int[] archives,
            int borderSize = 0,
            bool dilate = false,
            int maxAtlasSize = 2048,
            SupportedAlphaTextureFormats alphaTextureFormat = SupportedAlphaTextureFormats.RGBA32,
            SupportedNonAlphaTextureFormats nonAlphaFormat = SupportedNonAlphaTextureFormats.RGB24)
        {
            // Iterate archives
            TextureFile textureFile = new TextureFile();
            TextureAtlasBuilder builder = new TextureAtlasBuilder();
            GetTextureSettings settings = TextureReader.CreateTextureSettings(0, 0, 0, 0, borderSize, dilate, maxAtlasSize);
            settings.stayReadable = true;
            for (int i = 0; i < archives.Length; i++)
            {
                // Load texture file
                settings.archive = archives[i];
                textureFile.Load(Path.Combine(Arena2Path, TextureFile.IndexToFileName(settings.archive)), FileUsage.UseMemory, true);

                // Add all records for this archive - single frame only
                for (int record = 0; record < textureFile.RecordCount; record++)
                {
                    settings.record = record;
                    GetTextureResults results = GetTexture2D(settings, alphaTextureFormat, nonAlphaFormat);
                    DFSize size = textureFile.GetSize(record);
                    DFSize scale = textureFile.GetScale(record);
                    builder.AddTextureItem(
                        results.albedoMap,
                        settings.archive,
                        settings.record,
                        0, 1,
                        new Vector2(size.Width, size.Height),
                        new Vector2(scale.Width, scale.Height));
                }
            }

            // Apply the builder
            builder.Rebuild(borderSize);

            return builder;
        }
        /// <summary>
        /// Layout a complete RMB block game object.
        /// Can be used standalone or as part of a city build.
        /// </summary>
        public static GameObject CreateRMBBlockGameObject(
            string blockName,
            bool addGroundPlane = true,
            DaggerfallRMBBlock cloneFrom = null,
            DaggerfallBillboardBatch natureBillboardBatch = null,
            DaggerfallBillboardBatch lightsBillboardBatch = null,
            DaggerfallBillboardBatch animalsBillboardBatch = null,
            TextureAtlasBuilder miscBillboardAtlas = null,
            DaggerfallBillboardBatch miscBillboardBatch = null,
            ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland,
            ClimateSeason climateSeason = ClimateSeason.Summer)
        {
            // Get DaggerfallUnity
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;
            if (!dfUnity.IsReady)
                return null;

            // Create base object
            DFBlock blockData;
            GameObject go = RMBLayout.CreateBaseGameObject(blockName, out blockData, cloneFrom);

            // Create flats node
            GameObject flatsNode = new GameObject("Flats");
            flatsNode.transform.parent = go.transform;

            // Create lights node
            GameObject lightsNode = new GameObject("Lights");
            lightsNode.transform.parent = go.transform;

            // If billboard batching is enabled but user has not specified
            // a batch, then make our own auto batch for this block
            bool autoLightsBatch = false;
            bool autoNatureBatch = false;
            bool autoAnimalsBatch = false;
            if (dfUnity.Option_BatchBillboards)
            {
                if (natureBillboardBatch == null)
                {
                    autoNatureBatch = true;
                    int natureArchive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason);
                    natureBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(natureArchive, flatsNode.transform);
                }
                if (lightsBillboardBatch == null)
                {
                    autoLightsBatch = true;
                    lightsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.LightsTextureArchive, flatsNode.transform);
                }
                if (animalsBillboardBatch == null)
                {
                    autoAnimalsBatch = true;
                    animalsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.AnimalsTextureArchive, flatsNode.transform);
                }
            }

            // Layout light billboards and gameobjects
            RMBLayout.AddLights(ref blockData, flatsNode.transform, lightsNode.transform, lightsBillboardBatch);

            // Layout nature billboards
            RMBLayout.AddNatureFlats(ref blockData, flatsNode.transform, natureBillboardBatch, climateNature, climateSeason);

            // Layout all other flats
            RMBLayout.AddMiscBlockFlats(ref blockData, flatsNode.transform, animalsBillboardBatch, miscBillboardAtlas, miscBillboardBatch);

            // Add ground plane
            if (addGroundPlane)
                RMBLayout.AddGroundPlane(ref blockData, go.transform);

            // Apply auto batches
            if (autoNatureBatch) natureBillboardBatch.Apply();
            if (autoLightsBatch) lightsBillboardBatch.Apply();
            if (autoAnimalsBatch) animalsBillboardBatch.Apply();

            return go;
        }
Пример #7
0
        /// <summary>
        /// Add misc block flats.
        /// Batching is conditionally supported.
        /// </summary>
        public static void AddMiscBlockFlats(
            ref DFBlock blockData,
            Transform flatsParent,
            DaggerfallBillboardBatch animalsBillboardBatch = null,
            TextureAtlasBuilder miscBillboardsAtlas = null,
            DaggerfallBillboardBatch miscBillboardsBatch = null)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;
            if (!dfUnity.IsReady)
                return;

            // Add block flats
            foreach (DFBlock.RmbBlockFlatObjectRecord obj in blockData.RmbBlock.MiscFlatObjectRecords)
            {
                // Ignore lights as they are handled by AddLights()
                if (obj.TextureArchive == TextureReader.LightsTextureArchive)
                    continue;

                // Calculate position
                Vector3 billboardPosition = new Vector3(
                    obj.XPos,
                    -obj.YPos + blockFlatsOffsetY,
                    obj.ZPos + BlocksFile.RMBDimension) * MeshReader.GlobalScale;

                // Use misc billboard atlas where available
                if (miscBillboardsAtlas != null && miscBillboardsBatch != null)
                {
                    TextureAtlasBuilder.AtlasItem item = miscBillboardsAtlas.GetAtlasItem(obj.TextureArchive, obj.TextureRecord);
                    if (item.key != -1)
                    {
                        miscBillboardsBatch.AddItem(item.rect, item.textureItem.size, item.textureItem.scale, billboardPosition);
                        continue;
                    }
                }

                // Add to batch where available
                if (obj.TextureArchive == TextureReader.AnimalsTextureArchive && animalsBillboardBatch != null)
                {
                    animalsBillboardBatch.AddItem(obj.TextureRecord, billboardPosition);
                }
                else
                {
                    // Add standalone billboard gameobject
                    GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(obj.TextureArchive, obj.TextureRecord, flatsParent);
                    go.transform.position = billboardPosition;
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Layout a complete RMB block game object.
        /// Can be used standalone or as part of a city build.
        /// </summary>
        public static GameObject CreateRMBBlockGameObject(
            string blockName,
            bool addGroundPlane          = true,
            DaggerfallRMBBlock cloneFrom = null,
            DaggerfallBillboardBatch natureBillboardBatch  = null,
            DaggerfallBillboardBatch lightsBillboardBatch  = null,
            DaggerfallBillboardBatch animalsBillboardBatch = null,
            TextureAtlasBuilder miscBillboardAtlas         = null,
            DaggerfallBillboardBatch miscBillboardBatch    = null,
            ClimateNatureSets climateNature = ClimateNatureSets.TemperateWoodland,
            ClimateSeason climateSeason     = ClimateSeason.Summer)
        {
            // Get DaggerfallUnity
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return(null);
            }

            // Create base object
            DFBlock    blockData;
            GameObject go = RMBLayout.CreateBaseGameObject(blockName, out blockData, cloneFrom);

            // Create flats node
            GameObject flatsNode = new GameObject("Flats");

            flatsNode.transform.parent = go.transform;

            // Create lights node
            GameObject lightsNode = new GameObject("Lights");

            lightsNode.transform.parent = go.transform;

            // If billboard batching is enabled but user has not specified
            // a batch, then make our own auto batch for this block
            bool autoLightsBatch  = false;
            bool autoNatureBatch  = false;
            bool autoAnimalsBatch = false;

            if (dfUnity.Option_BatchBillboards)
            {
                if (natureBillboardBatch == null)
                {
                    autoNatureBatch = true;
                    int natureArchive = ClimateSwaps.GetNatureArchive(climateNature, climateSeason);
                    natureBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(natureArchive, flatsNode.transform);
                }
                if (lightsBillboardBatch == null)
                {
                    autoLightsBatch      = true;
                    lightsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.LightsTextureArchive, flatsNode.transform);
                }
                if (animalsBillboardBatch == null)
                {
                    autoAnimalsBatch      = true;
                    animalsBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.AnimalsTextureArchive, flatsNode.transform);
                }
            }

            // Layout light billboards and gameobjects
            RMBLayout.AddLights(ref blockData, flatsNode.transform, lightsNode.transform, lightsBillboardBatch);

            // Layout nature billboards
            RMBLayout.AddNatureFlats(ref blockData, flatsNode.transform, natureBillboardBatch, climateNature, climateSeason);

            // Layout all other flats
            RMBLayout.AddMiscBlockFlats(ref blockData, flatsNode.transform, animalsBillboardBatch, miscBillboardAtlas, miscBillboardBatch);

            // Add ground plane
            if (addGroundPlane)
            {
                RMBLayout.AddGroundPlane(ref blockData, go.transform);
            }

            // Apply auto batches
            if (autoNatureBatch)
            {
                natureBillboardBatch.Apply();
            }
            if (autoLightsBatch)
            {
                lightsBillboardBatch.Apply();
            }
            if (autoAnimalsBatch)
            {
                animalsBillboardBatch.Apply();
            }

            return(go);
        }
Пример #9
0
        /// <summary>
        /// Add misc block flats.
        /// Batching is conditionally supported.
        /// </summary>
        public static void AddMiscBlockFlats(
            ref DFBlock blockData,
            Transform flatsParent,
            int mapId,
            int locationIndex,
            DaggerfallBillboardBatch animalsBillboardBatch = null,
            TextureAtlasBuilder miscBillboardsAtlas        = null,
            DaggerfallBillboardBatch miscBillboardsBatch   = null)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return;
            }

            // Add block flats
            foreach (DFBlock.RmbBlockFlatObjectRecord obj in blockData.RmbBlock.MiscFlatObjectRecords)
            {
                // Ignore lights as they are handled by AddLights()
                if (obj.TextureArchive == TextureReader.LightsTextureArchive)
                {
                    continue;
                }

                // Calculate position
                Vector3 billboardPosition = new Vector3(
                    obj.XPos,
                    -obj.YPos + blockFlatsOffsetY,
                    obj.ZPos + BlocksFile.RMBDimension) * MeshReader.GlobalScale;

                GameObject go = MeshReplacement.ImportCustomFlatGameobject(obj.TextureArchive, obj.TextureRecord, billboardPosition, flatsParent);
                if (go == null)
                {
                    // Add standalone billboard gameobject
                    go = GameObjectHelper.CreateDaggerfallBillboardGameObject(obj.TextureArchive, obj.TextureRecord, flatsParent);
                    go.transform.position = billboardPosition;
                    AlignBillboardToBase(go);
                }

                // Add animal sound
                if (obj.TextureArchive == TextureReader.AnimalsTextureArchive)
                {
                    AddAnimalAudioSource(go, obj.TextureRecord);
                }

                // If flat record has a non-zero faction id, then it's an exterior NPC
                if (obj.FactionID != 0)
                {
                    // Add RMB data to billboard
                    Billboard dfBillboard = go.GetComponent <Billboard>();
                    if (dfBillboard != null)
                    {
                        dfBillboard.SetRMBPeopleData(obj.FactionID, obj.Flags, obj.Position);
                    }

                    // Add StaticNPC behaviour
                    StaticNPC npc = go.AddComponent <StaticNPC>();
                    npc.SetLayoutData(obj, mapId, locationIndex);
                }
            }
        }