Ejemplo n.º 1
0
        private void ArchetypeNameTextBox_TextChanged(object sender, EventArgs e)
        {
            var archetypeHash = JenkHash.GenHash(ArchetypeNameTextBox.Text);
            var archetype     = ProjectForm.GameFileCache.GetArchetype(archetypeHash);

            if (archetype == null)
            {
                HashLabel.Text = $@"Hash: {archetypeHash} (invalid)";
                return;
            }
            CurrentBatch.Archetype = archetype;
            var b = CurrentBatch.Batch;

            b.archetypeName    = archetypeHash;
            CurrentBatch.Batch = b;
            ProjectForm.WorldForm.UpdateGrassBatchGraphics(CurrentBatch);
            HashLabel.Text = $@"Hash: {archetypeHash}";
            UpdateFormTitle();
            CurrentBatch.HasChanged = true;
            ProjectForm.SetGrassBatchHasChanged(false);
            ProjectForm.SetYmapHasChanged(true);
        }
Ejemplo n.º 2
0
        private void ArchetypeNameTextBox_TextChanged(object sender, EventArgs e)
        {
            var hash = 0u;

            if (!uint.TryParse(ArchetypeNameTextBox.Text, out hash))//don't re-hash hashes
            {
                hash = JenkHash.GenHash(ArchetypeNameTextBox.Text);
            }

            if (CurrentArchetype._BaseArchetypeDef.name != hash)
            {
                CurrentArchetype._BaseArchetypeDef.name = hash;
                UpdateFormTitle();

                TreeNode tn = ProjectForm.ProjectExplorer?.FindArchetypeTreeNode(CurrentArchetype);
                if (tn != null)
                {
                    tn.Text = ArchetypeNameTextBox.Text ?? "0"; // using the text box text because the name may not be in the gfc.
                }
                ProjectForm.SetYtypHasChanged(true);
            }
        }
Ejemplo n.º 3
0
        private void SetYmapPhysicsDictionariesFromTextbox()
        {
            if (populatingui)
            {
                return;
            }
            if (Ymap == null)
            {
                return;
            }

            List <MetaHash> hashes = new List <MetaHash>();

            var strs = YmapPhysicsDictionariesTextBox.Text.Split('\n');

            foreach (var str in strs)
            {
                var tstr = str.Trim();
                if (!string.IsNullOrEmpty(tstr))
                {
                    uint h = 0;
                    if (uint.TryParse(tstr, out h))
                    {
                        hashes.Add(h);
                    }
                    else
                    {
                        h = JenkHash.GenHash(tstr.ToLowerInvariant());
                        hashes.Add(h);
                    }
                }
            }

            lock (ProjectForm.ProjectSyncRoot)
            {
                Ymap.physicsDictionaries = (hashes.Count > 0) ? hashes.ToArray() : null;
                SetYmapHasChanged(true);
            }
        }
Ejemplo n.º 4
0
        private void YmapParentTextBox_TextChanged(object sender, EventArgs e)
        {
            if (populatingui)
            {
                return;
            }
            uint   hash = 0;
            string name = YmapParentTextBox.Text;

            if (!uint.TryParse(name, out hash))//don't re-hash hashes
            {
                hash = JenkHash.GenHash(name);
                JenkIndex.Ensure(name);
            }
            YmapParentHashLabel.Text = "Hash: " + hash.ToString();

            if (hash != 0)
            {
                var entry = ProjectForm.FindParentYmapEntry(hash);
                if (entry == null)
                {
                    YmapParentHashLabel.Text += " (not found!)";
                }
            }

            if (Ymap != null)
            {
                lock (ProjectForm.ProjectSyncRoot)
                {
                    if (Ymap._CMapData.parent.Hash != hash)
                    {
                        Ymap._CMapData.parent = new MetaHash(hash);
                        SetYmapHasChanged(true);

                        //TODO: confirm entity parent linkage?
                    }
                }
            }
        }
Ejemplo n.º 5
0
        private void TextureDictTextBox_TextChanged(object sender, EventArgs e)
        {
            // Check that the form is not null before locking...
            if (ProjectForm == null)
            {
                return;
            }

            lock (ProjectForm.ProjectSyncRoot)
            {
                // Embedded...
                if (TextureDictTextBox.Text == ArchetypeNameTextBox.Text)
                {
                    TextureDictHashLabel.Text = "Embedded";
                    CurrentArchetype._BaseArchetypeDef.textureDictionary = CurrentArchetype._BaseArchetypeDef.name;
                    return;
                }

                var hash = 0u;
                if (!uint.TryParse(TextureDictTextBox.Text, out hash))//don't re-hash hashes
                {
                    hash = JenkHash.GenHash(TextureDictTextBox.Text);
                }

                if (CurrentArchetype._BaseArchetypeDef.textureDictionary != hash)
                {
                    var ytd = ProjectForm.GameFileCache.GetYtd(hash);
                    if (ytd == null)
                    {
                        TextureDictHashLabel.Text = "Hash: " + hash.ToString() + " (invalid)";
                        ProjectForm.SetYtypHasChanged(true);
                        return;
                    }
                    CurrentArchetype._BaseArchetypeDef.textureDictionary = hash;
                    ProjectForm.SetYtypHasChanged(true);
                }
                TextureDictHashLabel.Text = "Hash: " + hash.ToString();
            }
        }
Ejemplo n.º 6
0
        private void LoadStringsButton_Click(object sender, EventArgs e)
        {
            if (OpenFileDialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            string file = OpenFileDialog.FileName;

            if (!File.Exists(file))
            {
                return;
            }

            try
            {
                string   txt   = File.ReadAllText(file);
                string[] lines = txt.Split('\n');
                foreach (string line in lines)
                {
                    string str = line.Trim();
                    if (str.Length > 2) //remove double quotes from start and end, if both present...
                    {
                        if ((str[0] == '\"') && (str[str.Length - 1] == '\"'))
                        {
                            str = str.Substring(1, str.Length - 2);
                        }
                    }
                    var hash = JenkHash.GenHash(str);
                    extraStrings[hash] = str;
                }
                MessageBox.Show(lines.Length.ToString() + " strings imported successfully.");
            }
            catch
            {
                MessageBox.Show("Error reading file.");
            }
        }
Ejemplo n.º 7
0
        private void PhysicsDictionaryTextBox_TextChanged(object sender, EventArgs e)
        {
            lock (ProjectForm.ProjectSyncRoot)
            {
                if (ProjectForm == null)
                {
                    return;
                }

                // Embedded...
                if (PhysicsDictionaryTextBox.Text == ArchetypeNameTextBox.Text)
                {
                    PhysicsDictHashLabel.Text = "Embedded";
                    CurrentArchetype._BaseArchetypeDef.physicsDictionary = CurrentArchetype._BaseArchetypeDef.name;
                    return;
                }

                var hash = 0u;
                if (!uint.TryParse(PhysicsDictionaryTextBox.Text, out hash))//don't re-hash hashes
                {
                    hash = JenkHash.GenHash(PhysicsDictionaryTextBox.Text);
                }

                if (CurrentArchetype._BaseArchetypeDef.physicsDictionary != hash)
                {
                    var ytd = ProjectForm.GameFileCache.GetYbn(hash);
                    if (ytd == null)
                    {
                        PhysicsDictHashLabel.Text = "Hash: " + hash.ToString() + " (invalid)";
                        ProjectForm.SetYtypHasChanged(true);
                        return;
                    }
                    CurrentArchetype._BaseArchetypeDef.physicsDictionary = hash;
                    ProjectForm.SetYtypHasChanged(true);
                }
                PhysicsDictHashLabel.Text = "Hash: " + hash.ToString();
            }
        }
Ejemplo n.º 8
0
        private void LoadGxt2(CutEvent e)
        {
            if (GameFileCache == null)
            {
                return;
            }
            if (Gxt2File != null)
            {
            }

            var args = e.EventArgs as CutFinalNameEventArgs;

            if (args == null)
            {
                return;
            }

            var namel    = args.cName?.ToLowerInvariant();
            var namehash = JenkHash.GenHash(namel);

            RpfFileEntry gxt2entry = null;

            GameFileCache.Gxt2Dict.TryGetValue(namehash, out gxt2entry);

            if (gxt2entry != null) //probably should do this load async
            {
                Gxt2File = GameFileCache.RpfMan.GetFile <Gxt2File>(gxt2entry);

                if (Gxt2File != null)
                {
                    for (int i = 0; i < Gxt2File.TextEntries.Length; i++)
                    {
                        var te = Gxt2File.TextEntries[i];
                        GlobalText.Ensure(te.Text, te.Hash);
                    }
                }
            }
        }
Ejemplo n.º 9
0
        private void Timecycle2TextBox_TextChanged(object sender, EventArgs e)
        {
            if (populatingui)
            {
                return;
            }
            if (CurrentRoom == null)
            {
                return;
            }

            var hash = JenkHash.GenHash(Timecycle2TextBox.Text);

            lock (ProjectForm.ProjectSyncRoot)
            {
                if (CurrentRoom._Data.secondaryTimecycleName != hash)
                {
                    CurrentRoom._Data.secondaryTimecycleName = hash;
                    ProjectForm.SetYtypHasChanged(true);
                    JenkIndex.Ensure(Timecycle2TextBox.Text);
                }
            }
        }
Ejemplo n.º 10
0
        public void LoadVehicle()
        {
            var      modelname   = VehicleModelComboBox.Text;
            var      modelnamel  = modelname.ToLowerInvariant();
            MetaHash modelhash   = JenkHash.GenHash(modelnamel);
            MetaHash modelhashhi = JenkHash.GenHash(modelnamel + "_hi");
            bool     hidet       = VehicleHighDetailCheckBox.Checked;
            var      yfthash     = hidet ? modelhashhi : modelhash;

            VehicleInitData vid = null;

            if (GameFileCache.VehiclesInitDict.TryGetValue(modelhash, out vid))
            {
                bool vehiclechange = SelectedVehicleHash != modelhash;
                SelectedModelHash   = yfthash;
                SelectedVehicleHash = modelhash;
                SelectedVehicleInit = vid;
                SelectedVehicleYft  = GameFileCache.GetYft(SelectedModelHash);
                while ((SelectedVehicleYft != null) && (!SelectedVehicleYft.Loaded))
                {
                    Thread.Sleep(20);//kinda hacky
                    SelectedVehicleYft = GameFileCache.GetYft(SelectedModelHash);
                }
                LoadModel(SelectedVehicleYft, vehiclechange);
                VehicleMakeLabel.Text = GlobalText.TryGetString(JenkHash.GenHash(vid.vehicleMakeName.ToLower()));
                VehicleNameLabel.Text = GlobalText.TryGetString(JenkHash.GenHash(vid.gameName.ToLower()));
            }
            else
            {
                SelectedModelHash     = 0;
                SelectedVehicleHash   = 0;
                SelectedVehicleInit   = null;
                SelectedVehicleYft    = null;
                VehicleMakeLabel.Text = "-";
                VehicleNameLabel.Text = "-";
            }
        }
Ejemplo n.º 11
0
        private void EntitySetNameTextBox_TextChanged(object sender, EventArgs e)
        {
            if (populatingui)
            {
                return;
            }
            if (CurrentEntitySet == null)
            {
                return;
            }

            var str = EntitySetNameTextBox.Text;

            if (CurrentEntitySet.Name != str)
            {
                uint h = 0;
                if (uint.TryParse(str, out h))
                {
                    CurrentEntitySet._Data.name = h;
                }
                else
                {
                    JenkIndex.Ensure(str);
                    CurrentEntitySet._Data.name = JenkHash.GenHash(str);
                }

                TreeNode tn = ProjectForm.ProjectExplorer?.FindMloEntitySetTreeNode(CurrentEntitySet);
                if (tn != null)
                {
                    tn.Text = CurrentEntitySet.Name;
                }

                UpdateFormTitle();
                ProjectForm.SetYtypHasChanged(true);
            }
        }
Ejemplo n.º 12
0
        public void SetComponentDrawable(int index, string name, string tex, GameFileCache gfc)
        {
            if (string.IsNullOrEmpty(name))
            {
                DrawableNames[index] = null;
                Drawables[index]     = null;
                Textures[index]      = null;
                Expressions[index]   = null;
                return;
            }

            MetaHash namehash = JenkHash.GenHash(name.ToLowerInvariant());
            Drawable d        = null;

            if (Ydd?.Dict != null)
            {
                Ydd.Dict.TryGetValue(namehash, out d);
            }
            if ((d == null) && (DrawableFilesDict != null))
            {
                RpfFileEntry file = null;
                if (DrawableFilesDict.TryGetValue(namehash, out file))
                {
                    var ydd = gfc.GetFileUncached <YddFile>(file);
                    while ((ydd != null) && (!ydd.Loaded))
                    {
                        Thread.Sleep(1);//kinda hacky
                        gfc.TryLoadEnqueue(ydd);
                    }
                    if (ydd?.Drawables?.Length > 0)
                    {
                        d = ydd.Drawables[0];//should only be one in this dict
                    }
                }
            }

            MetaHash texhash = JenkHash.GenHash(tex.ToLowerInvariant());
            Texture  t       = null;

            if (Ytd?.TextureDict?.Dict != null)
            {
                Ytd.TextureDict.Dict.TryGetValue(texhash, out t);
            }
            if ((t == null) && (TextureFilesDict != null))
            {
                RpfFileEntry file = null;
                if (TextureFilesDict.TryGetValue(texhash, out file))
                {
                    var ytd = gfc.GetFileUncached <YtdFile>(file);
                    while ((ytd != null) && (!ytd.Loaded))
                    {
                        Thread.Sleep(1);//kinda hacky
                        gfc.TryLoadEnqueue(ytd);
                    }
                    if (ytd?.TextureDict?.Textures?.data_items.Length > 0)
                    {
                        t = ytd.TextureDict.Textures.data_items[0];//should only be one in this dict
                    }
                }
            }

            CharacterCloth cc = null;

            if (Yld?.Dict != null)
            {
                Yld.Dict.TryGetValue(namehash, out cc);
            }
            if ((cc == null) && (ClothFilesDict != null))
            {
                RpfFileEntry file = null;
                if (ClothFilesDict.TryGetValue(namehash, out file))
                {
                    var yld = gfc.GetFileUncached <YldFile>(file);
                    while ((yld != null) && (!yld.Loaded))
                    {
                        Thread.Sleep(1);//kinda hacky
                        gfc.TryLoadEnqueue(yld);
                    }
                    if (yld?.ClothDictionary?.Clothes?.data_items?.Length > 0)
                    {
                        cc = yld.ClothDictionary.Clothes.data_items[0];//should only be one in this dict
                    }
                }
            }
            ClothInstance c = null;

            if (cc != null)
            {
                c = new ClothInstance();
                c.Init(cc, Skeleton);
            }

            Expression e = null;

            if (Yed?.ExprMap != null)
            {
                Yed.ExprMap.TryGetValue(namehash, out e);
            }


            if (d != null)
            {
                Drawables[index] = d.ShallowCopy() as Drawable;
            }
            if (t != null)
            {
                Textures[index] = t;
            }
            if (c != null)
            {
                Clothes[index] = c;
            }
            if (e != null)
            {
                Expressions[index] = e;
            }

            DrawableNames[index] = name;
        }
Ejemplo n.º 13
0
        public void Init(MetaHash pedhash, GameFileCache gfc)
        {
            Name     = string.Empty;
            NameHash = 0;
            InitData = null;
            Ydd      = null;
            Ytd      = null;
            Yld      = null;
            Ycd      = null;
            Yed      = null;
            Yft      = null;
            Ymt      = null;
            AnimClip = null;
            for (int i = 0; i < 12; i++)
            {
                Drawables[i]   = null;
                Textures[i]    = null;
                Expressions[i] = null;
            }


            CPedModelInfo__InitData initdata = null;

            if (!gfc.PedsInitDict.TryGetValue(pedhash, out initdata))
            {
                return;
            }

            var ycdhash = JenkHash.GenHash(initdata.ClipDictionaryName.ToLowerInvariant());
            var yedhash = JenkHash.GenHash(initdata.ExpressionDictionaryName.ToLowerInvariant());

            //bool pedchange = NameHash != pedhash;
            //Name = pedname;
            NameHash = pedhash;
            InitData = initdata;
            Ydd      = gfc.GetYdd(pedhash);
            Ytd      = gfc.GetYtd(pedhash);
            Ycd      = gfc.GetYcd(ycdhash);
            Yed      = gfc.GetYed(yedhash);
            Yft      = gfc.GetYft(pedhash);

            PedFile pedFile = null;

            gfc.PedVariationsDict?.TryGetValue(pedhash, out pedFile);
            Ymt = pedFile;

            Dictionary <MetaHash, RpfFileEntry> peddict = null;

            gfc.PedDrawableDicts.TryGetValue(NameHash, out peddict);
            DrawableFilesDict = peddict;
            DrawableFiles     = DrawableFilesDict?.Values.ToArray();
            gfc.PedTextureDicts.TryGetValue(NameHash, out peddict);
            TextureFilesDict = peddict;
            TextureFiles     = TextureFilesDict?.Values.ToArray();
            gfc.PedClothDicts.TryGetValue(NameHash, out peddict);
            ClothFilesDict = peddict;
            ClothFiles     = ClothFilesDict?.Values.ToArray();

            RpfFileEntry clothFile = null;

            if (ClothFilesDict?.TryGetValue(pedhash, out clothFile) ?? false)
            {
                Yld = gfc.GetFileUncached <YldFile>(clothFile);
                while ((Yld != null) && (!Yld.Loaded))
                {
                    Thread.Sleep(1);//kinda hacky
                    gfc.TryLoadEnqueue(Yld);
                }
            }



            while ((Ydd != null) && (!Ydd.Loaded))
            {
                Thread.Sleep(1);//kinda hacky
                Ydd = gfc.GetYdd(pedhash);
            }
            while ((Ytd != null) && (!Ytd.Loaded))
            {
                Thread.Sleep(1);//kinda hacky
                Ytd = gfc.GetYtd(pedhash);
            }
            while ((Ycd != null) && (!Ycd.Loaded))
            {
                Thread.Sleep(1);//kinda hacky
                Ycd = gfc.GetYcd(ycdhash);
            }
            while ((Yed != null) && (!Yed.Loaded))
            {
                Thread.Sleep(1);//kinda hacky
                Yed = gfc.GetYed(yedhash);
            }
            while ((Yft != null) && (!Yft.Loaded))
            {
                Thread.Sleep(1);//kinda hacky
                Yft = gfc.GetYft(pedhash);
            }


            Skeleton = Yft?.Fragment?.Drawable?.Skeleton?.Clone();

            MetaHash     cliphash = JenkHash.GenHash("idle");
            ClipMapEntry cme      = null;

            Ycd?.ClipMap?.TryGetValue(cliphash, out cme);
            AnimClip = cme;

            var        exprhash = JenkHash.GenHash(initdata.ExpressionName.ToLowerInvariant());
            Expression expr     = null;

            Yed?.ExprMap?.TryGetValue(exprhash, out expr);
            Expression = expr;


            UpdateEntity();
        }
Ejemplo n.º 14
0
        private void ParamTextBox_TextChanged(object sender, EventArgs e)
        {
            var tb   = sender as TextBox;
            var parm = tb?.Tag as ShaderParameter;
            var txt  = tb?.Text;

            if (parm == null)
            {
                return;
            }

            if (parm.DataType == 0)//texture
            {
                var tex  = parm.Data as TextureBase;
                var ttex = tex as Texture;
                if (ttex == null)//don't do this for embedded textures!
                {
                    tex.Name     = txt;
                    tex.NameHash = JenkHash.GenHash(txt.ToLowerInvariant());
                }
                else
                {
                    //TODO: modify embedded textures!
                }
            }
            else if (parm.DataType == 1)//Vector4
            {
                parm.Data = FloatUtil.ParseVector4String(txt);
            }
            else //Vector4 array
            {
                var strs = txt.Split(';');
                var vecs = new Vector4[parm.DataType];
                for (int i = 0; i < parm.DataType; i++)
                {
                    var vec = Vector4.Zero;
                    if (i < strs.Length)
                    {
                        vec = FloatUtil.ParseVector4String(strs[i].Trim());
                    }
                    vecs[i] = vec;
                }
                parm.Data = vecs;
            }


            var geom = ModelsTreeView.SelectedNode?.Tag as DrawableGeometry;

            if (geom != null)
            {
                if (Drawable != null)
                {
                    UpdateRenderableParams(Drawable, geom.Shader);
                }
                if (DrawableDict != null)
                {
                    foreach (var dwbl in DrawableDict.Values)
                    {
                        UpdateRenderableParams(dwbl, geom.Shader);
                    }
                }
            }

            ModelForm.OnModelModified();
        }
Ejemplo n.º 15
0
        private void GenerateButton_Click(object sender, EventArgs e)
        {
            //var space = ProjectForm?.WorldForm?.Space;
            //if (space == null) return;
            var gameFileCache = ProjectForm?.WorldForm?.GameFileCache;

            if (gameFileCache == null)
            {
                return;
            }

            var path = ProjectForm.CurrentProjectFile.GetFullFilePath("lodlights") + "\\";

            GenerateButton.Enabled = false;


            List <YmapFile> projectYmaps = ProjectForm.CurrentProjectFile.YmapFiles;

            var pname = NameTextBox.Text;

            Task.Run(() =>
            {
                var lights = new List <Light>();
                var eemin  = new Vector3(float.MaxValue);
                var eemax  = new Vector3(float.MinValue);
                var semin  = new Vector3(float.MaxValue);
                var semax  = new Vector3(float.MinValue);
                //var rnd = new Random();

                foreach (var ymap in projectYmaps)
                {
                    if (ymap?.AllEntities == null)
                    {
                        continue;
                    }
                    foreach (var ent in ymap.AllEntities)
                    {
                        if (ent.Archetype == null)
                        {
                            continue;
                        }

                        bool waiting = false;
                        var dwbl     = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                        while (waiting)
                        {
                            dwbl = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                            UpdateStatus("Waiting for " + ent.Archetype.AssetName + " to load...");
                            Thread.Sleep(20);
                        }
                        UpdateStatus("Adding lights from " + ent.Archetype.Name + "...");
                        if (dwbl != null)
                        {
                            Drawable ddwbl                 = dwbl as Drawable;
                            FragDrawable fdwbl             = dwbl as FragDrawable;
                            LightAttributes_s[] lightAttrs = null;
                            if (ddwbl != null)
                            {
                                lightAttrs = ddwbl.LightAttributes?.data_items;
                            }
                            else if (fdwbl != null)
                            {
                                lightAttrs = fdwbl.OwnerFragment?.LightAttributes?.data_items;
                            }
                            if (lightAttrs != null)
                            {
                                eemin = Vector3.Min(eemin, ent.BBMin);
                                eemax = Vector3.Max(eemax, ent.BBMax);
                                semin = Vector3.Min(semin, ent.BBMin - ent._CEntityDef.lodDist);
                                semax = Vector3.Max(semax, ent.BBMax + ent._CEntityDef.lodDist);


                                for (int li = 0; li < lightAttrs.Length; li++)
                                {
                                    var la = lightAttrs[li];
                                    //transform this light with the entity position and orientation
                                    //generate lights data from it!


                                    //gotta transform the light position by the given bone! annoying
                                    Bone bone    = null;
                                    Matrix xform = Matrix.Identity;
                                    int boneidx  = 0;
                                    var skeleton = dwbl.Skeleton;
                                    if (skeleton?.Bones?.Data != null)
                                    {
                                        for (int j = 0; j < skeleton.Bones.Data.Count; j++)
                                        {
                                            var tbone = skeleton.Bones.Data[j];
                                            if (tbone.Tag == la.BoneId)
                                            {
                                                boneidx = j;
                                                bone    = tbone;
                                                break;
                                            }
                                        }
                                        if (bone != null)
                                        {
                                            var modeltransforms = skeleton.Transformations;
                                            var fragtransforms  = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod?.FragTransforms?.Data;
                                            var fragtransformid = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysIndex ?? 0;
                                            var fragoffset      = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod.Unknown_30h ?? Vector4.Zero;
                                            fragoffset.W        = 0.0f;

                                            if ((fragtransforms != null) && (fragtransformid < fragtransforms.Length))
                                            {
                                                xform       = fragtransforms[fragtransformid];
                                                xform.Row4 += fragoffset;
                                            }
                                            else
                                            {
                                                //when using the skeleton's matrices, they need to be transformed by parent
                                                xform         = modeltransforms[boneidx];
                                                xform.Column4 = Vector4.UnitW;
                                                //xform = Matrix.Identity;
                                                short[] pinds   = skeleton.ParentIndices;
                                                short parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (short)-1;
                                                while ((parentind >= 0) && (parentind < pinds.Length))
                                                {
                                                    Matrix ptrans  = (parentind < modeltransforms.Length) ? modeltransforms[parentind] : Matrix.Identity;
                                                    ptrans.Column4 = Vector4.UnitW;
                                                    xform          = Matrix.Multiply(ptrans, xform);
                                                    parentind      = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (short)-1;
                                                }
                                            }
                                        }
                                    }



                                    Vector3 lpos = la.Position;
                                    Vector3 ldir = la.Direction;
                                    Vector3 bpos = xform.Multiply(lpos);
                                    Vector3 bdir = xform.MultiplyRot(ldir);
                                    Vector3 epos = ent.Orientation.Multiply(bpos) + ent.Position;
                                    Vector3 edir = ent.Orientation.Multiply(bdir);

                                    uint r = la.ColorR;
                                    uint g = la.ColorG;
                                    uint b = la.ColorB;
                                    uint i = (byte)Math.Min(la.Intensity * 4, 255);
                                    uint c = (i << 24) + (r << 16) + (g << 8) + b;


                                    uint h = GetLightHash(ent, li);// (uint)rnd.NextLong();

                                    if (ent._CEntityDef.guid == 91259075)
                                    {
                                    }   //h = 2324437992?     should be:19112537
                                    if (ent._CEntityDef.guid == 889043351)
                                    {
                                    }   //h = 422028630 ?     should be:4267224866



                                    //any other way to know if it's a streetlight?
                                    //var name = ent.Archetype.Name;
                                    var flags          = la.Flags;
                                    bool isStreetLight = (((flags >> 10) & 1u) == 1); // (name != null) && (name.Contains("street") || name.Contains("traffic"));
                                    isStreetLight      = false;                       //TODO: fix this!


                                    //@Calcium:
                                    //1 = point
                                    //2 = spot
                                    //4 = capsule
                                    uint type = (uint)la.Type;
                                    uint unk  = isStreetLight ? 1u : 0;//2 bits - isStreetLight low bit, unk high bit
                                    uint t    = la.TimeFlags | (type << 26) | (unk << 24);

                                    var maxext = (byte)Math.Max(Math.Max(la.Extent.X, la.Extent.Y), la.Extent.Z);



                                    var light                    = new Light();
                                    light.position               = new MetaVECTOR3(epos);
                                    light.colour                 = c;
                                    light.direction              = new MetaVECTOR3(edir);
                                    light.falloff                = la.Falloff;
                                    light.falloffExponent        = la.FalloffExponent;
                                    light.timeAndStateFlags      = t;
                                    light.hash                   = h;
                                    light.coneInnerAngle         = (byte)la.ConeInnerAngle;
                                    light.coneOuterAngleOrCapExt = Math.Max((byte)la.ConeOuterAngle, maxext);
                                    light.coronaIntensity        = (byte)(la.CoronaIntensity * 6);
                                    light.isStreetLight          = isStreetLight;
                                    lights.Add(light);
                                }
                            }
                        }
                    }
                }


                if (lights.Count == 0)
                {
                    MessageBox.Show("No lights found in project!");
                    return;
                }



                //final lights should be sorted by isStreetLight (1 first!) and then hash
                lights.Sort((a, b) =>
                {
                    if (a.isStreetLight != b.isStreetLight)
                    {
                        return(b.isStreetLight.CompareTo(a.isStreetLight));
                    }
                    return(a.hash.CompareTo(b.hash));
                });



                var position          = new List <MetaVECTOR3>();
                var colour            = new List <uint>();
                var direction         = new List <MetaVECTOR3>();
                var falloff           = new List <float>();
                var falloffExponent   = new List <float>();
                var timeAndStateFlags = new List <uint>();
                var hash                   = new List <uint>();
                var coneInnerAngle         = new List <byte>();
                var coneOuterAngleOrCapExt = new List <byte>();
                var coronaIntensity        = new List <byte>();
                ushort numStreetLights     = 0;
                foreach (var light in lights)
                {
                    position.Add(light.position);
                    colour.Add(light.colour);
                    direction.Add(light.direction);
                    falloff.Add(light.falloff);
                    falloffExponent.Add(light.falloffExponent);
                    timeAndStateFlags.Add(light.timeAndStateFlags);
                    hash.Add(light.hash);
                    coneInnerAngle.Add(light.coneInnerAngle);
                    coneOuterAngleOrCapExt.Add(light.coneOuterAngleOrCapExt);
                    coronaIntensity.Add(light.coronaIntensity);
                    if (light.isStreetLight)
                    {
                        numStreetLights++;
                    }
                }



                UpdateStatus("Creating new ymap files...");

                var lodymap               = new YmapFile();
                var distymap              = new YmapFile();
                var ll                    = new YmapLODLights();
                var dl                    = new YmapDistantLODLights();
                var cdl                   = new CDistantLODLight();
                cdl.category              = 1;//0=small, 1=med, 2=large
                cdl.numStreetLights       = numStreetLights;
                dl.CDistantLODLight       = cdl;
                dl.positions              = position.ToArray();
                dl.colours                = colour.ToArray();
                ll.direction              = direction.ToArray();
                ll.falloff                = falloff.ToArray();
                ll.falloffExponent        = falloffExponent.ToArray();
                ll.timeAndStateFlags      = timeAndStateFlags.ToArray();
                ll.hash                   = hash.ToArray();
                ll.coneInnerAngle         = coneInnerAngle.ToArray();
                ll.coneOuterAngleOrCapExt = coneOuterAngleOrCapExt.ToArray();
                ll.coronaIntensity        = coronaIntensity.ToArray();


                lodymap._CMapData.flags         = 0;
                distymap._CMapData.flags        = 2;
                lodymap._CMapData.contentFlags  = 128;
                distymap._CMapData.contentFlags = 256;

                lodymap._CMapData.entitiesExtentsMin   = eemin;
                lodymap._CMapData.entitiesExtentsMax   = eemax;
                lodymap._CMapData.streamingExtentsMin  = semin - 1000f;
                lodymap._CMapData.streamingExtentsMax  = semax + 1000f; //vanilla = ~1km
                distymap._CMapData.entitiesExtentsMin  = eemin;
                distymap._CMapData.entitiesExtentsMax  = eemax;
                distymap._CMapData.streamingExtentsMin = semin - 5000f; //make it huge
                distymap._CMapData.streamingExtentsMax = semax + 5000f; //vanilla = ~3km

                lodymap.LODLights         = ll;
                distymap.DistantLODLights = dl;

                var lodname                     = pname + "_lodlights";
                var distname                    = pname + "_distantlights";
                lodymap.Name                    = lodname;
                lodymap._CMapData.name          = JenkHash.GenHash(lodname);
                lodymap.RpfFileEntry            = new RpfResourceFileEntry();
                lodymap.RpfFileEntry.Name       = lodname + ".ymap";
                lodymap.RpfFileEntry.NameLower  = lodname + ".ymap";
                distymap.Name                   = distname;
                distymap._CMapData.name         = JenkHash.GenHash(distname);
                distymap.RpfFileEntry           = new RpfResourceFileEntry();
                distymap.RpfFileEntry.Name      = distname + ".ymap";
                distymap.RpfFileEntry.NameLower = distname + ".ymap";

                lodymap._CMapData.parent = distymap._CMapData.name;


                UpdateStatus("Adding new ymap files to project...");

                ProjectForm.Invoke((MethodInvoker) delegate
                {
                    ProjectForm.AddYmapToProject(lodymap);
                    ProjectForm.AddYmapToProject(distymap);
                });

                var stats = "";
                UpdateStatus("Process complete. " + stats);
                GenerateComplete();
            });
        }
Ejemplo n.º 16
0
        public void UpdateYmapUI()
        {
            if (Ymap == null)
            {
                YmapNameTextBox.Text                 = "<No ymap selected>";
                YmapNameHashLabel.Text               = "Hash: 0";
                YmapParentTextBox.Text               = string.Empty;
                YmapParentHashLabel.Text             = "Hash: 0";
                YmapFlagsTextBox.Text                = string.Empty;
                YmapContentFlagsTextBox.Text         = string.Empty;
                YmapCFlagsHDCheckBox.Checked         = false;
                YmapCFlagsLODCheckBox.Checked        = false;
                YmapCFlagsSLOD2CheckBox.Checked      = false;
                YmapCFlagsInteriorCheckBox.Checked   = false;
                YmapCFlagsSLODCheckBox.Checked       = false;
                YmapCFlagsOcclusionCheckBox.Checked  = false;
                YmapCFlagsPhysicsCheckBox.Checked    = false;
                YmapCFlagsLODLightsCheckBox.Checked  = false;
                YmapCFlagsDistLightsCheckBox.Checked = false;
                YmapCFlagsCriticalCheckBox.Checked   = false;
                YmapCFlagsGrassCheckBox.Checked      = false;
                YmapFlagsScriptedCheckBox.Checked    = false;
                YmapFlagsLODCheckBox.Checked         = false;
                YmapPhysicsDictionariesTextBox.Text  = string.Empty;
                YmapEntitiesExtentsMinTextBox.Text   = string.Empty;
                YmapEntitiesExtentsMaxTextBox.Text   = string.Empty;
                YmapStreamingExtentsMinTextBox.Text  = string.Empty;
                YmapStreamingExtentsMaxTextBox.Text  = string.Empty;
                YmapFileLocationTextBox.Text         = string.Empty;
                YmapProjectPathTextBox.Text          = string.Empty;
            }
            else
            {
                populatingui = true;
                var md = Ymap.CMapData;
                if (md.name.Hash == 0)
                {
                    string name = Path.GetFileNameWithoutExtension(Ymap.Name);
                    JenkIndex.Ensure(name);
                    md.name = new MetaHash(JenkHash.GenHash(name));
                }

                var project = ProjectForm?.CurrentProjectFile;

                YmapNameTextBox.Text                = md.name.ToString();
                YmapNameHashLabel.Text              = "Hash: " + md.name.Hash.ToString();
                YmapParentTextBox.Text              = md.parent.ToString();
                YmapParentHashLabel.Text            = "Hash: " + md.parent.Hash.ToString();
                YmapEntitiesExtentsMinTextBox.Text  = FloatUtil.GetVector3String(md.entitiesExtentsMin);
                YmapEntitiesExtentsMaxTextBox.Text  = FloatUtil.GetVector3String(md.entitiesExtentsMax);
                YmapStreamingExtentsMinTextBox.Text = FloatUtil.GetVector3String(md.streamingExtentsMin);
                YmapStreamingExtentsMaxTextBox.Text = FloatUtil.GetVector3String(md.streamingExtentsMax);
                YmapFileLocationTextBox.Text        = Ymap.RpfFileEntry?.Path ?? Ymap.FilePath;
                YmapProjectPathTextBox.Text         = (project != null) ? project.GetRelativePath(Ymap.FilePath) : Ymap.FilePath;

                UpdateYmapFlagsUI(true, true);

                UpdateYmapPhysicsDictionariesUI();

                populatingui = false;

                ////struct CMapData:
                //MetaHash name { get; set; } //8   8: Hash: 0: name
                //MetaHash parent { get; set; } //12   12: Hash: 0: parent
                //uint flags { get; set; } //16   16: UnsignedInt: 0: flags
                //uint contentFlags { get; set; } //20   20: UnsignedInt: 0: contentFlags//1785155637
                //Vector3 streamingExtentsMin { get; set; } //32   32: Float_XYZ: 0: streamingExtentsMin//3710026271
                //Vector3 streamingExtentsMax { get; set; } //48   48: Float_XYZ: 0: streamingExtentsMax//2720965429
                //Vector3 entitiesExtentsMin { get; set; } //64   64: Float_XYZ: 0: entitiesExtentsMin//477478129
                //Vector3 entitiesExtentsMax { get; set; } //80   80: Float_XYZ: 0: entitiesExtentsMax//1829192759
                //Array_StructurePointer entities { get; set; } //96   96: Array: 0: entities  {0: StructurePointer: 0: 256}
                //Array_Structure containerLods { get; set; } //112   112: Array: 0: containerLods//2935983381  {0: Structure: 372253349: 256}
                //Array_Structure boxOccluders { get; set; } //128   128: Array: 0: boxOccluders//3983590932  {0: Structure: SectionUNKNOWN7: 256}
                //Array_Structure occludeModels { get; set; } //144   144: Array: 0: occludeModels//2132383965  {0: Structure: SectionUNKNOWN5: 256}
                //Array_uint physicsDictionaries { get; set; } //160   160: Array: 0: physicsDictionaries//949589348  {0: Hash: 0: 256}
                //rage__fwInstancedMapData instancedData { get; set; } //176   176: Structure: rage__fwInstancedMapData: instancedData//2569067561
                //Array_Structure timeCycleModifiers { get; set; } //224   224: Array: 0: timeCycleModifiers  {0: Structure: CTimeCycleModifier: 256}
                //Array_Structure carGenerators { get; set; } //240   240: Array: 0: carGenerators//3254823756  {0: Structure: CCarGen: 256}
                //CLODLight LODLightsSOA { get; set; } //256   256: Structure: CLODLight: LODLightsSOA//1774371066
                //CDistantLODLight DistantLODLightsSOA { get; set; } //392   392: Structure: CDistantLODLight: DistantLODLightsSOA//2954466641
                //CBlockDesc block { get; set; } //440   440: Structure: CBlockDesc//3072355914: block
            }
        }
Ejemplo n.º 17
0
        private void EntityArchetypeTextBox_TextChanged(object sender, EventArgs e)
        {
            if (populatingui)
            {
                return;
            }
            if (CurrentEntity == null)
            {
                return;
            }
            uint   hash = 0;
            string name = EntityArchetypeTextBox.Text;

            if (!uint.TryParse(name, out hash))//don't re-hash hashes
            {
                hash = JenkHash.GenHash(name);
                JenkIndex.Ensure(name);
            }
            EntityArchetypeHashLabel.Text = "Hash: " + hash.ToString();

            var arch = ProjectForm.GameFileCache.GetArchetype(hash);

            if (arch == null)
            {
                EntityArchetypeHashLabel.Text += " (not found)";
            }

            TreeNode tn = ProjectForm.ProjectExplorer?.FindEntityTreeNode(CurrentEntity);

            if (tn != null)
            {
                tn.Text = name;
            }
            else
            {
                tn = ProjectForm.ProjectExplorer?.FindMloEntityTreeNode(CurrentMCEntity);
                if (tn != null)
                {
                    tn.Text = name;
                }
            }

            if (CurrentEntity != null)
            {
                lock (ProjectForm.ProjectSyncRoot)
                {
                    CurrentEntity._CEntityDef.archetypeName = new MetaHash(hash);

                    if (CurrentMCEntity != null)
                    {
                        CurrentMCEntity._Data.archetypeName = new MetaHash(hash);
                    }

                    if (CurrentEntity.Archetype != arch)
                    {
                        CurrentEntity.SetArchetype(arch);

                        if (CurrentEntity.IsMlo)
                        {
                            CurrentEntity.MloInstance.InitYmapEntityArchetypes(ProjectForm.GameFileCache);
                        }

                        ProjectItemChanged();
                    }
                }
            }
        }
Ejemplo n.º 18
0
        public byte[] BuildYcd()
        {
            YcdFile ycd = new YcdFile();

            ycd.ClipDictionary = new ClipDictionary();


            var clipmap = new List <ClipMapEntry>();
            var animmap = new List <AnimationMapEntry>();

            foreach (var onim in OnimFiles)
            {
                var anim = new Animation();
                anim.Hash               = JenkHash.GenHash(onim.Name.ToLowerInvariant());
                anim.Frames             = (ushort)onim.Frames;
                anim.SequenceFrameLimit = (ushort)onim.SequenceFrameLimit;
                anim.Duration           = onim.Duration;

                JenkIndex.Ensure(onim.Name.ToLowerInvariant());//just to make it nicer to debug really

                bool isUV          = false;
                bool hasRootMotion = false;
                var  boneIds       = new List <AnimationBoneId>();
                var  seqs          = new List <Sequence>();
                var  aseqs         = new List <List <AnimSequence> >();
                foreach (var oseq in onim.SequenceList)
                {
                    var boneid = new AnimationBoneId();
                    boneid.BoneId = (ushort)oseq.BoneID; //TODO: bone ID mapping
                    boneid.Unk0   = 0;                   //what to use here?
                    switch (oseq.Track)
                    {
                    case "BonePosition": boneid.Track = 0;
                        break;

                    case "BoneRotation": boneid.Track = 1;
                        break;

                    case "ModelPosition": boneid.Track = 5; hasRootMotion = true;
                        break;

                    case "ModelRotation": boneid.Track = 6; hasRootMotion = true;
                        break;

                    case "UV0": boneid.Track = 17; isUV = true;
                        break;

                    case "UV1": boneid.Track = 18; isUV = true;
                        break;

                    case "LightColor": boneid.Track = 0;    //what should this be?
                        break;

                    case "LightRange": boneid.Track = 0;    //what should this be?
                        break;

                    case "LightIntensity1": boneid.Track = 0;    //what should this be?
                        break;

                    case "LightIntensity2": boneid.Track = 0;    //what should this be?
                        break;

                    case "LightDirection": boneid.Track = 0;    //what should this be?
                        break;

                    case "Type21": boneid.Track = 0;    //what should this be?
                        break;

                    case "CameraPosition": boneid.Track = 7;
                        break;

                    case "CameraRotation": boneid.Track = 8;
                        break;

                    case "CameraFOV": boneid.Track = 0;    //what should this be?
                        break;

                    case "CameraDof": boneid.Track = 0;    //what should this be?
                        break;

                    case "CameraMatrixRotateFactor": boneid.Track = 0;    //what should this be?
                        break;

                    case "CameraControl": boneid.Track = 0;    //what should this be?
                        break;

                    case "ActionFlags":    //not sure what this is for? just ignore it for now
                        continue;

                    default:
                        break;
                    }
                    boneIds.Add(boneid);

                    for (int i = 0; i < oseq.FramesData.Count; i++)
                    {
                        var framesData = oseq.FramesData[i];
                        if (i > 0)
                        {
                        }
                        Sequence            seq      = null;
                        List <AnimSequence> aseqlist = null;
                        while (i >= seqs.Count)
                        {
                            seq = new Sequence();
                            seqs.Add(seq);
                            aseqlist = new List <AnimSequence>();
                            aseqs.Add(aseqlist);
                        }
                        seq      = seqs[i];
                        aseqlist = aseqs[i];


                        var chanlist = new List <AnimChannel>();
                        if (framesData.IsStatic)
                        {
                            var vals = (framesData.Channels.Count > 0) ? framesData.Channels[0].Values : null;
                            if (vals != null)
                            {
                                if (vals.Length == 1)
                                {
                                    var acsf = new AnimChannelStaticFloat();
                                    acsf.Value = vals[0];
                                    chanlist.Add(acsf);
                                }
                                else if (vals.Length == 3)
                                {
                                    var acsv = new AnimChannelStaticVector3();
                                    acsv.Value = new Vector3(vals[0], vals[1], vals[2]);
                                    chanlist.Add(acsv);
                                }
                                else if (vals.Length == 4)
                                {
                                    var acsq = new AnimChannelStaticQuaternion();
                                    acsq.Value = new Quaternion(vals[0], vals[1], vals[2], vals[3]);
                                    chanlist.Add(acsq);
                                }
                                else
                                {
                                }
                            }
                            else
                            {
                            }
                        }
                        else
                        {
                            int chanCount = framesData.Channels.Count;

                            for (int c = 0; c < chanCount; c++)
                            {
                                var ochan = framesData.Channels[c];
                                var vals  = ochan.Values;
                                if (vals.Length == 1)//static channel...
                                {
                                    var acsf = new AnimChannelStaticFloat();
                                    acsf.Value = vals[0];
                                    chanlist.Add(acsf);
                                }
                                else //if (vals.Length == onim.Frames)
                                {
                                    float minval   = float.MaxValue;
                                    float maxval   = float.MinValue;
                                    float lastval  = 0;
                                    float mindelta = float.MaxValue;
                                    foreach (var val in vals)
                                    {
                                        minval = Math.Min(minval, val);
                                        maxval = Math.Max(maxval, val);
                                        if (val != lastval)
                                        {
                                            float adelta = Math.Abs(val - lastval);
                                            mindelta = Math.Min(mindelta, adelta);
                                        }
                                        lastval = val;
                                    }
                                    if (mindelta == float.MaxValue)
                                    {
                                        mindelta = 0;
                                    }
                                    float range    = maxval - minval;
                                    float minquant = range / 1048576.0f;
                                    float quantum  = Math.Max(mindelta, minquant);

                                    var acqf = new AnimChannelQuantizeFloat();
                                    acqf.Values  = vals;
                                    acqf.Offset  = minval;
                                    acqf.Quantum = quantum;
                                    chanlist.Add(acqf);
                                }
                            }

                            if (chanCount == 4)
                            {
                                //assume it's a quaternion... add the extra quaternion channel
                                var acq1 = new AnimChannelCachedQuaternion(AnimChannelType.CachedQuaternion2);
                                acq1.QuatIndex = 3;//what else should it be?
                                chanlist.Add(acq1);
                            }
                        }

                        if (chanlist.Count == 4)
                        {
                        }  //shouldn't happen

                        AnimSequence aseq = new AnimSequence();
                        aseq.Channels = chanlist.ToArray();

                        aseqlist.Add(aseq);
                    }
                }

                int remframes = anim.Frames;
                for (int i = 0; i < seqs.Count; i++)
                {
                    var seq      = seqs[i];
                    var aseqlist = aseqs[i];

                    seq.Unknown_00h = 0;//what to set this???
                    seq.NumFrames   = (ushort)Math.Max(Math.Min(anim.SequenceFrameLimit, remframes), 0);
                    seq.Sequences   = aseqlist.ToArray();

                    seq.AssociateSequenceChannels();

                    remframes -= anim.SequenceFrameLimit;
                }


                anim.BoneIds            = new ResourceSimpleList64_s <AnimationBoneId>();
                anim.BoneIds.data_items = boneIds.ToArray();

                anim.Sequences            = new ResourcePointerList64 <Sequence>();
                anim.Sequences.data_items = seqs.ToArray();

                anim.Unknown_10h = hasRootMotion ? (byte)16 : (byte)0;
                anim.Unknown_1Ch = 0; //???

                anim.AssignSequenceBoneIds();



                var cliphash = anim.Hash;
                if (isUV)
                {
                    var name  = onim.Name.ToLowerInvariant();
                    var uvind = name.IndexOf("_uv_");
                    if (uvind < 0)
                    {
                    }
                    var modelname = name.Substring(0, uvind);
                    var geoindstr = name.Substring(uvind + 4);
                    var geoind    = 0u;
                    uint.TryParse(geoindstr, out geoind);
                    cliphash = JenkHash.GenHash(modelname) + geoind + 1;
                }
                else
                {
                }


                var clip = new ClipAnimation();
                clip.Animation   = anim;
                clip.StartTime   = 0.0f;
                clip.EndTime     = anim.Duration;
                clip.Rate        = 1.0f;
                clip.Name        = "pack:/" + onim.Name + ".clip"; //pack:/name.clip
                clip.Unknown_30h = 0;                              //what's this then?
                clip.Properties  = new ClipPropertyMap();
                clip.Properties.CreatePropertyMap(null);           //TODO?
                clip.Tags = new ClipTagList();                     //TODO?

                var cme = new ClipMapEntry();
                cme.Clip = clip;
                cme.Hash = cliphash;
                clipmap.Add(cme);

                var ame = new AnimationMapEntry();
                ame.Hash      = anim.Hash;//is this right? what else to use?
                ame.Animation = anim;
                animmap.Add(ame);
            }


            ycd.ClipDictionary.CreateClipsMap(clipmap.ToArray());
            ycd.ClipDictionary.CreateAnimationsMap(animmap.ToArray());

            ycd.ClipDictionary.BuildMaps();
            ycd.ClipDictionary.UpdateUsageCounts();
            ycd.InitDictionaries();

            byte[] data = ycd.Save();
            return(data);
        }
Ejemplo n.º 19
0
        public void Init(GameFileCache gameFileCache, Action <string> updateStatus)
        {
            Inited = false;

            GameFileCache = gameFileCache;

            var rpfman = gameFileCache.RpfMan;

            string filename = "common.rpf\\data\\levels\\gta5\\popzone.ipl";

            if (gameFileCache.EnableDlc)
            {
                filename = "update\\update.rpf\\common\\data\\levels\\gta5\\popzone.ipl";
            }

            string ipltext = rpfman.GetFileUTF8Text(filename);

            if (string.IsNullOrEmpty(ipltext))
            {
                ipltext = "";
            }

            Groups.Clear();

            var  ipllines = ipltext.Split('\n');
            bool inzone   = false;

            foreach (var iplline in ipllines)
            {
                var linet = iplline.Trim();
                if (linet == "zone")
                {
                    inzone = true;
                }
                else if (linet == "end")
                {
                    inzone = false;
                }
                else if (inzone)
                {
                    PopZoneBox box = new PopZoneBox();
                    box.Init(linet);

                    PopZone group;
                    if (!Groups.TryGetValue(box.NameLabel, out group))
                    {
                        group                 = new PopZone();
                        group.NameLabel       = box.NameLabel;
                        Groups[box.NameLabel] = group;
                    }

                    group.Boxes.Add(box);
                }
            }


            foreach (var group in Groups.Values)
            {
                var hash = JenkHash.GenHash(group.NameLabel.ToLowerInvariant());
                group.Name = GlobalText.TryGetString(hash);
            }


            BuildVertices();

            Inited = true;
        }
Ejemplo n.º 20
0
        private ShaderFX TryConvertMaterial(FbxNode matNode)
        {
            var shader = new ShaderFX();

            var spsName  = "default";
            var texConns = new List <FbxNode>();
            var texNames = new List <string>();

            #region 3dsmax/GIMS properties
            //var floatValueNames = new List<string>();
            //var floatValues = new List<Vector4>();
            //var texValueNames = new List<string>();
            //var texValues = new List<FbxNode>();
            //var matProps = matNode["Properties70"];
            //foreach (var matProp in matProps.Nodes)//currently broken due to GIMS not doing things right
            //{
            //    if (matProp == null) continue;
            //    if (matProp.Name != "P") continue;
            //    var propStr = GetStringFromObjectList(matProp.Properties, 4);
            //    var propId = matProp.Value as string;
            //    if (propId == null) continue;
            //    if (propId == "3dsMax|params|SPSName") spsName = propStr?.ToLowerInvariant() ?? "default";
            //    if (propId.StartsWith("3dsMax|params|FloatValueNames|FloatValueNames")) floatValueNames.Add(propStr);
            //    if (propId.StartsWith("3dsMax|params|FloatValues|FloatValues")) floatValues.Add(GetVector4FromObjectList(matProp.Properties, 4));
            //    if (propId.StartsWith("3dsMax|params|TexValueNames|TexValueNames")) texValueNames.Add(propStr);
            //    if (propId.StartsWith("3dsMax|params|TexValues|TexValues")) texValues.Add(matProp);
            //}
            #endregion

            foreach (var conn in matNode.Connections)
            {
                if (conn.Name == "Texture")
                {
                    texConns.Add(conn);
                    var texName  = GetStringFromObjectList(conn.Properties, 1)?.Replace("Texture::", "");
                    var ftexName = conn["FileName"]?.Value as string;
                    if (ftexName != null)
                    {
                        try
                        {
                            texName = Path.GetFileNameWithoutExtension(ftexName);
                        }
                        catch
                        { }
                    }
                    texNames.Add(texName);
                }
            }

            if (texNames.Count > 1)
            {
                spsName = "normal";
            }

            var spsFileName = spsName + ".sps";

            shader.Name     = JenkHash.GenHash(spsName);
            shader.FileName = JenkHash.GenHash(spsFileName);

            shader.ParametersList = new ShaderParametersBlock();
            var paramsBlock = shader.ParametersList;
            var pNames      = new List <ShaderParamNames>();
            var pVals       = new List <ShaderParameter>();


            shader.Unknown_Ch   = 0;
            shader.RenderBucket = 0;
            shader.Unknown_12h  = 32768;//shrugs
            shader.Unknown_1Ch  = 0;
            shader.Unknown_24h  = 0;
            shader.Unknown_26h  = 0;
            shader.Unknown_28h  = 0;


            switch (spsName)
            {
            default:
            case "default":
                //shader.RenderBucket = 3;
                //shader.ParameterSize = 208;
                //shader.ParameterDataSize = 272;
                AddShaderParam(pNames, pVals, ShaderParamNames.DiffuseSampler, GetTextureBaseParam(texNames, 0));    //assume first texture is diffuse...
                AddShaderParam(pNames, pVals, ShaderParamNames.matMaterialColorScale, new Vector4(1, 0, 0, 1));
                AddShaderParam(pNames, pVals, ShaderParamNames.HardAlphaBlend, new Vector4(0, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.useTessellation, new Vector4(0, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.wetnessMultiplier, new Vector4(1, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.globalAnimUV1, new Vector4(0, 1, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.globalAnimUV0, new Vector4(1, 0, 0, 0));
                break;

            case "normal":
                //shader.RenderBucket = 0;
                //shader.ParameterSize = 320;
                //shader.ParameterDataSize = 400;
                AddShaderParam(pNames, pVals, ShaderParamNames.DiffuseSampler, GetTextureBaseParam(texNames, 0)); //assume first texture is diffuse...
                AddShaderParam(pNames, pVals, ShaderParamNames.BumpSampler, GetTextureBaseParam(texNames, 1));    //assume 2nd texture is normalmap..
                AddShaderParam(pNames, pVals, ShaderParamNames.HardAlphaBlend, new Vector4(1, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.useTessellation, new Vector4(0, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.wetnessMultiplier, new Vector4(1, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.bumpiness, new Vector4(1, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.specularIntensityMult, new Vector4(0.5f, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.specularFalloffMult, new Vector4(20, 0, 0, 0));    //too metallic?
                AddShaderParam(pNames, pVals, ShaderParamNames.specularFresnel, new Vector4(0.9f, 0, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.globalAnimUV1, new Vector4(0, 1, 0, 0));
                AddShaderParam(pNames, pVals, ShaderParamNames.globalAnimUV0, new Vector4(1, 0, 0, 0));
                break;
            }

            for (int i = 0; i < pVals.Count; i++)
            {
                var pVal = pVals[i];
                if (pVal.DataType == 1)
                {
                    pVal.Unknown_1h = (byte)(160 + ((pVals.Count - 1) - i));//seriously wtf is this and why
                }
            }

            MetaName[] nameHashes = new MetaName[pNames.Count];
            for (int i = 0; i < pNames.Count; i++)
            {
                nameHashes[i] = (MetaName)pNames[i];
            }

            paramsBlock.Hashes     = nameHashes;
            paramsBlock.Parameters = pVals.ToArray();
            paramsBlock.Count      = pVals.Count;

            shader.ParameterSize          = paramsBlock.ParametersSize;
            shader.ParameterDataSize      = (ushort)(paramsBlock.BlockLength + 36);//but why +36?
            shader.ParameterCount         = (byte)pVals.Count;
            shader.TextureParametersCount = paramsBlock.TextureParamsCount;
            shader.RenderBucketMask       = (1u << shader.RenderBucket) | 0xFF00;


            return(shader);
        }
Ejemplo n.º 21
0
        private void Search()
        {
            SearchResultsGrid.SelectedObject = null;

            if (CurrentFile?.RelDatasSorted == null)
            {
                return;
            }


            bool textsearch = SearchTextRadio.Checked;
            var  text       = SearchTextBox.Text;
            var  textl      = text.ToLowerInvariant();

            uint hash  = 0;
            uint hashl = 0;

            if (!uint.TryParse(text, out hash))//don't re-hash hashes
            {
                hash = JenkHash.GenHash(text);
                JenkIndex.Ensure(text);
                hashl = JenkHash.GenHash(textl);
                JenkIndex.Ensure(textl);
            }
            else
            {
                hashl = hash;
            }


            var results = new List <RelData>();

            foreach (var rd in CurrentFile.RelDatasSorted)
            {
                if (textsearch)
                {
                    if (((rd.Name?.ToLowerInvariant().Contains(textl)) ?? false) || (rd.NameHash == hash) || (rd.NameHash == hashl) ||
                        (rd.NameHash.ToString().ToLowerInvariant().Contains(textl)))
                    {
                        results.Add(rd);
                    }
                }
                else
                {
                    if ((rd.NameHash == hash) || (rd.NameHash == hashl))
                    {
                        SearchResultsGrid.SelectedObject = rd;
                        return;
                    }
                }
            }

            if (textsearch && (results.Count > 0))
            {
                SearchResultsGrid.SelectedObject = results.ToArray();
            }
            else
            {
                SearchResultsGrid.SelectedObject = null;
            }
        }
Ejemplo n.º 22
0
        public void Init(GameFileCache gameFileCache, XmlNode node)
        {
            Name                     = Xml.GetChildInnerText(node, "Name");
            NameHash                 = new MetaHash(JenkHash.GenHash(Name.ToLower()));
            Sun                      = Xml.GetChildFloatAttribute(node, "Sun", "value");
            Cloud                    = Xml.GetChildFloatAttribute(node, "Cloud", "value");
            WindMin                  = Xml.GetChildFloatAttribute(node, "WindMin", "value");
            WindMax                  = Xml.GetChildFloatAttribute(node, "WindMax", "value");
            Rain                     = Xml.GetChildFloatAttribute(node, "Rain", "value");
            Snow                     = Xml.GetChildFloatAttribute(node, "Snow", "value");
            SnowMist                 = Xml.GetChildFloatAttribute(node, "SnowMist", "value");
            Fog                      = Xml.GetChildFloatAttribute(node, "Fog", "value");
            RippleBumpiness          = Xml.GetChildFloatAttribute(node, "RippleBumpiness", "value");
            RippleMinBumpiness       = Xml.GetChildFloatAttribute(node, "RippleMinBumpiness", "value");
            RippleMaxBumpiness       = Xml.GetChildFloatAttribute(node, "RippleMaxBumpiness", "value");
            RippleBumpinessWindScale = Xml.GetChildFloatAttribute(node, "RippleBumpinessWindScale", "value");
            RippleScale              = Xml.GetChildFloatAttribute(node, "RippleScale", "value");
            RippleSpeed              = Xml.GetChildFloatAttribute(node, "RippleSpeed", "value");
            RippleVelocityTransfer   = Xml.GetChildFloatAttribute(node, "RippleVelocityTransfer", "value");
            OceanBumpiness           = Xml.GetChildFloatAttribute(node, "OceanBumpiness", "value");
            DeepOceanScale           = Xml.GetChildFloatAttribute(node, "DeepOceanScale", "value");
            OceanNoiseMinAmplitude   = Xml.GetChildFloatAttribute(node, "OceanNoiseMinAmplitude", "value");
            OceanWaveAmplitude       = Xml.GetChildFloatAttribute(node, "OceanWaveAmplitude", "value");
            ShoreWaveAmplitude       = Xml.GetChildFloatAttribute(node, "ShoreWaveAmplitude", "value");
            OceanWaveWindScale       = Xml.GetChildFloatAttribute(node, "OceanWaveWindScale", "value");
            ShoreWaveWindScale       = Xml.GetChildFloatAttribute(node, "ShoreWaveWindScale", "value");
            OceanWaveMinAmplitude    = Xml.GetChildFloatAttribute(node, "OceanWaveMinAmplitude", "value");
            ShoreWaveMinAmplitude    = Xml.GetChildFloatAttribute(node, "ShoreWaveMinAmplitude", "value");
            OceanWaveMaxAmplitude    = Xml.GetChildFloatAttribute(node, "OceanWaveMaxAmplitude", "value");
            ShoreWaveMaxAmplitude    = Xml.GetChildFloatAttribute(node, "ShoreWaveMaxAmplitude", "value");
            OceanFoamIntensity       = Xml.GetChildFloatAttribute(node, "OceanFoamIntensity", "value");
            OceanFoamScale           = Xml.GetChildFloatAttribute(node, "OceanFoamScale", "value");
            RippleDisturb            = Xml.GetChildFloatAttribute(node, "RippleDisturb", "value");
            Lightning                = Xml.GetChildFloatAttribute(node, "Lightning", "value");
            Sandstorm                = Xml.GetChildFloatAttribute(node, "Sandstorm", "value");
            OldSettingName           = Xml.GetChildInnerText(node, "OldSettingName");
            DropSettingName          = Xml.GetChildInnerText(node, "DropSettingName");
            MistSettingName          = Xml.GetChildInnerText(node, "MistSettingName");
            GroundSettingName        = Xml.GetChildInnerText(node, "GroundSettingName");
            TimeCycleFilename        = Xml.GetChildInnerText(node, "TimeCycleFilename");
            CloudSettingsName        = Xml.GetChildInnerText(node, "CloudSettingsName");


            if (!string.IsNullOrEmpty(TimeCycleFilename))
            {
                //TODO: RpfMan should be able to get the right version? or maybe let gameFileCache do it!
                string fname  = TimeCycleFilename.ToLower();
                bool   useupd = gameFileCache.EnableDlc;
                if (useupd)
                {
                    fname = fname.Replace("common:", "update/update.rpf/common");
                }
                XmlDocument tcxml = gameFileCache.RpfMan.GetFileXml(fname);
                if (useupd && !tcxml.HasChildNodes)
                {
                    fname = TimeCycleFilename.ToLower();
                    tcxml = gameFileCache.RpfMan.GetFileXml(fname);
                }

                foreach (XmlNode cycle in tcxml.DocumentElement.ChildNodes)
                {
                    TimeCycleData = new WeatherCycleKeyframeData();
                    TimeCycleData.Init(cycle);
                }
            }
        }
Ejemplo n.º 23
0
        public void Init(GameFileCache gameFileCache, bool sounds = true, bool game = true)
        {
            var rpfman = gameFileCache.RpfMan;

            var datrelentries = new Dictionary <uint, RpfFileEntry>();
            var awcentries    = new Dictionary <uint, RpfFileEntry>();

            void addRpfDatRels(RpfFile rpffile)
            {
                if (rpffile.AllEntries == null)
                {
                    return;
                }
                foreach (var entry in rpffile.AllEntries)
                {
                    if (entry is RpfFileEntry)
                    {
                        var fentry = entry as RpfFileEntry;
                        //if (entry.NameLower.EndsWith(".rel"))
                        //{
                        //    datrels[entry.NameHash] = fentry;
                        //}
                        if (sounds && entry.NameLower.EndsWith(".dat54.rel"))
                        {
                            datrelentries[entry.NameHash] = fentry;
                        }
                        if (game && entry.NameLower.EndsWith(".dat151.rel"))
                        {
                            datrelentries[entry.NameHash] = fentry;
                        }
                    }
                }
            }

            void addRpfAwcs(RpfFile rpffile)
            {
                if (rpffile.AllEntries == null)
                {
                    return;
                }
                foreach (var entry in rpffile.AllEntries)
                {
                    if (entry is RpfFileEntry)
                    {
                        var fentry = entry as RpfFileEntry;
                        if (entry.NameLower.EndsWith(".awc"))
                        {
                            var shortname  = entry.GetShortNameLower();
                            var parentname = entry.Parent?.GetShortNameLower() ?? "";
                            if (string.IsNullOrEmpty(parentname) && (entry.Parent?.File != null))
                            {
                                parentname = entry.Parent.File.NameLower;
                                int ind = parentname.LastIndexOf('.');
                                if (ind > 0)
                                {
                                    parentname = parentname.Substring(0, ind);
                                }
                            }
                            var contname = parentname + "/" + shortname;
                            var hash     = JenkHash.GenHash(contname);
                            awcentries[hash] = fentry;
                        }
                    }
                }
            }

            var audrpf = rpfman.FindRpfFile("x64\\audio\\audio_rel.rpf");

            if (audrpf != null)
            {
                addRpfDatRels(audrpf);
            }
            foreach (var baserpf in gameFileCache.BaseRpfs)
            {
                addRpfAwcs(baserpf);
            }
            if (gameFileCache.EnableDlc)
            {
                var updrpf = rpfman.FindRpfFile("update\\update.rpf");
                if (updrpf != null)
                {
                    addRpfDatRels(updrpf);
                }
                foreach (var dlcrpf in gameFileCache.DlcActiveRpfs) //load from current dlc rpfs
                {
                    addRpfDatRels(dlcrpf);
                    addRpfAwcs(dlcrpf);
                }
            }



            var soundsdb = new Dictionary <uint, Dat54Sound>();
            var gamedb   = new Dictionary <uint, Dat151RelData>();

            foreach (var datentry in datrelentries.Values)
            {
                var relfile = rpfman.GetFile <RelFile>(datentry);
                if (relfile?.RelDatas != null)
                {
                    foreach (var rd in relfile.RelDatas)
                    {
                        if (rd is Dat54Sound sd)
                        {
                            soundsdb[sd.NameHash] = sd;
                        }
                        else if (rd is Dat151RelData gd)
                        {
                            gamedb[gd.NameHash] = gd;
                        }
                    }
                }
            }

            ContainerDB = awcentries;
            if (sounds)
            {
                SoundsDB = soundsdb;
            }
            if (game)
            {
                GameDB = gamedb;
            }

            IsInited = true;
        }
Ejemplo n.º 24
0
        private void GenerateButton_Click(object sender, EventArgs e)
        {
            //var space = ProjectForm?.WorldForm?.Space;
            //if (space == null) return;
            var gameFileCache = ProjectForm?.WorldForm?.GameFileCache;

            if (gameFileCache == null)
            {
                return;
            }

            var path = ProjectForm.CurrentProjectFile.GetFullFilePath("lodlights") + "\\";

            GenerateButton.Enabled = false;


            List <YmapFile> projectYmaps = ProjectForm.CurrentProjectFile.YmapFiles;

            var pname = NameTextBox.Text;

            Task.Run(() =>
            {
                var lights = new List <Light>();

                foreach (var ymap in projectYmaps)
                {
                    if (ymap?.AllEntities == null)
                    {
                        continue;
                    }
                    foreach (var ent in ymap.AllEntities)
                    {
                        if (ent.Archetype == null)
                        {
                            continue;
                        }

                        bool waiting = false;
                        var dwbl     = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                        while (waiting)
                        {
                            dwbl = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                            UpdateStatus("Waiting for " + ent.Archetype.AssetName + " to load...");
                            Thread.Sleep(20);
                        }
                        UpdateStatus("Adding lights from " + ent.Archetype.Name + "...");
                        if (dwbl != null)
                        {
                            var fphys = (dwbl as FragDrawable)?.OwnerFragmentPhys;

                            ent.EnsureLights(dwbl);
                            var elights = ent.Lights;
                            if (elights != null)
                            {
                                for (int li = 0; li < elights.Length; li++)
                                {
                                    var elight = elights[li];
                                    var la     = elight.Attributes;

                                    uint r = la.ColorR;
                                    uint g = la.ColorG;
                                    uint b = la.ColorB;
                                    uint i = (byte)Math.Max(Math.Min(Math.Round(la.Intensity * 5.3125f), 255), 0);//5.1=255/48
                                    uint c = (i << 24) + (r << 16) + (g << 8) + b;
                                    uint h = elight.Hash;


                                    //any other way to know if it's a streetlight?
                                    //var name = ent.Archetype.Name;
                                    var flags          = la.Flags;
                                    bool isStreetLight = (((flags >> 10) & 1u) == 1); // (name != null) && (name.Contains("street") || name.Contains("traffic"));
                                    isStreetLight      = false;                       //TODO: fix this!


                                    //@Calcium:
                                    //1 = point
                                    //2 = spot
                                    //4 = capsule
                                    uint type = (uint)la.Type;
                                    uint unk  = isStreetLight ? 1u : 0;//2 bits - isStreetLight low bit, unk high bit
                                    uint t    = la.TimeFlags | (type << 26) | (unk << 24);

                                    var inner = (byte)Math.Round(la.ConeInnerAngle * 1.4117647f);
                                    var outer = (byte)Math.Round(la.ConeOuterAngle * 1.4117647f);
                                    if (type == 4)
                                    {
                                        outer = (byte)Math.Max(Math.Max(la.Extent.X, la.Extent.Y), la.Extent.Z);
                                    }


                                    var light                    = new Light();
                                    light.position               = new MetaVECTOR3(elight.Position);
                                    light.colour                 = c;
                                    light.direction              = new MetaVECTOR3(elight.Direction);
                                    light.falloff                = la.Falloff;
                                    light.falloffExponent        = la.FalloffExponent;
                                    light.timeAndStateFlags      = t;
                                    light.hash                   = h;
                                    light.coneInnerAngle         = inner;
                                    light.coneOuterAngleOrCapExt = outer;
                                    light.coronaIntensity        = (byte)(la.CoronaIntensity * 6);
                                    light.isStreetLight          = isStreetLight;
                                    lights.Add(light);
                                }
                            }
                        }
                    }
                }


                if (lights.Count == 0)
                {
                    MessageBox.Show("No lights found in project!");
                    return;
                }



                //final lights should be sorted by isStreetLight (1 first!) and then hash
                lights.Sort((a, b) =>
                {
                    if (a.isStreetLight != b.isStreetLight)
                    {
                        return(b.isStreetLight.CompareTo(a.isStreetLight));
                    }
                    return(a.hash.CompareTo(b.hash));
                });



                var position          = new List <MetaVECTOR3>();
                var colour            = new List <uint>();
                var direction         = new List <MetaVECTOR3>();
                var falloff           = new List <float>();
                var falloffExponent   = new List <float>();
                var timeAndStateFlags = new List <uint>();
                var hash                   = new List <uint>();
                var coneInnerAngle         = new List <byte>();
                var coneOuterAngleOrCapExt = new List <byte>();
                var coronaIntensity        = new List <byte>();
                ushort numStreetLights     = 0;
                foreach (var light in lights)
                {
                    position.Add(light.position);
                    colour.Add(light.colour);
                    direction.Add(light.direction);
                    falloff.Add(light.falloff);
                    falloffExponent.Add(light.falloffExponent);
                    timeAndStateFlags.Add(light.timeAndStateFlags);
                    hash.Add(light.hash);
                    coneInnerAngle.Add(light.coneInnerAngle);
                    coneOuterAngleOrCapExt.Add(light.coneOuterAngleOrCapExt);
                    coronaIntensity.Add(light.coronaIntensity);
                    if (light.isStreetLight)
                    {
                        numStreetLights++;
                    }
                }



                UpdateStatus("Creating new ymap files...");

                var lodymap  = new YmapFile();
                var distymap = new YmapFile();
                var ll       = new YmapLODLights();
                var dl       = new YmapDistantLODLights();
                var cdl      = new CDistantLODLight();
                distymap.DistantLODLights = dl;
                lodymap.LODLights         = ll;
                lodymap.Parent            = distymap;
                cdl.category        = 1;//0=small, 1=med, 2=large
                cdl.numStreetLights = numStreetLights;
                dl.CDistantLODLight = cdl;
                dl.positions        = position.ToArray();
                dl.colours          = colour.ToArray();
                dl.Ymap             = distymap;
                dl.CalcBB();
                ll.direction         = direction.ToArray();
                ll.falloff           = falloff.ToArray();
                ll.falloffExponent   = falloffExponent.ToArray();
                ll.timeAndStateFlags = timeAndStateFlags.ToArray();
                ll.hash                   = hash.ToArray();
                ll.coneInnerAngle         = coneInnerAngle.ToArray();
                ll.coneOuterAngleOrCapExt = coneOuterAngleOrCapExt.ToArray();
                ll.coronaIntensity        = coronaIntensity.ToArray();
                ll.Ymap                   = lodymap;
                ll.BuildLodLights(dl);
                ll.CalcBB();
                ll.BuildBVH();

                lodymap.CalcFlags();
                lodymap.CalcExtents();
                distymap.CalcFlags();
                distymap.CalcExtents();


                var lodname                     = pname + "_lodlights";
                var distname                    = pname + "_distantlights";
                lodymap.Name                    = lodname;
                lodymap._CMapData.name          = JenkHash.GenHash(lodname);
                lodymap.RpfFileEntry            = new RpfResourceFileEntry();
                lodymap.RpfFileEntry.Name       = lodname + ".ymap";
                lodymap.RpfFileEntry.NameLower  = lodname + ".ymap";
                distymap.Name                   = distname;
                distymap._CMapData.name         = JenkHash.GenHash(distname);
                distymap.RpfFileEntry           = new RpfResourceFileEntry();
                distymap.RpfFileEntry.Name      = distname + ".ymap";
                distymap.RpfFileEntry.NameLower = distname + ".ymap";

                lodymap._CMapData.parent = distymap._CMapData.name;
                lodymap.Loaded           = true;
                distymap.Loaded          = true;

                UpdateStatus("Adding new ymap files to project...");

                ProjectForm.Invoke((MethodInvoker) delegate
                {
                    ProjectForm.AddYmapToProject(lodymap);
                    ProjectForm.AddYmapToProject(distymap);
                });

                var stats = "";
                UpdateStatus("Process complete. " + stats);
                GenerateComplete();
            });
        }
Ejemplo n.º 25
0
        private void GenerateButton_Click(object sender, EventArgs e)
        {
            //var space = ProjectForm?.WorldForm?.Space;
            //if (space == null) return;
            var gameFileCache = ProjectForm?.WorldForm?.GameFileCache;

            if (gameFileCache == null)
            {
                return;
            }

            var path = ProjectForm.CurrentProjectFile.GetFullFilePath("navmeshes") + "\\";

            GenerateButton.Enabled = false;


            List <YmapFile> projectYmaps = ProjectForm.CurrentProjectFile.YmapFiles;

            var pname = NameTextBox.Text;

            Task.Run(() =>
            {
                var position          = new List <MetaVECTOR3>();
                var colour            = new List <uint>();
                var direction         = new List <MetaVECTOR3>();
                var falloff           = new List <float>();
                var falloffExponent   = new List <float>();
                var timeAndStateFlags = new List <uint>();
                var hash                   = new List <uint>();
                var coneInnerAngle         = new List <byte>();
                var coneOuterAngleOrCapExt = new List <byte>();
                var coronaIntensity        = new List <byte>();
                var eemin                  = new Vector3(float.MaxValue);
                var eemax                  = new Vector3(float.MinValue);
                var semin                  = new Vector3(float.MaxValue);
                var semax                  = new Vector3(float.MinValue);

                foreach (var ymap in projectYmaps)
                {
                    foreach (var ent in ymap.AllEntities)
                    {
                        if (ent.Archetype == null)
                        {
                            continue;
                        }

                        bool waiting = false;
                        var dwbl     = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                        while (waiting)
                        {
                            dwbl = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                            UpdateStatus("Waiting for " + ent.Archetype.AssetName + " to load...");
                            Thread.Sleep(20);
                        }
                        UpdateStatus("Adding lights from " + ent.Archetype.Name + "...");
                        if (dwbl != null)
                        {
                            Drawable ddwbl                 = dwbl as Drawable;
                            FragDrawable fdwbl             = dwbl as FragDrawable;
                            LightAttributes_s[] lightAttrs = null;
                            if (ddwbl != null)
                            {
                                lightAttrs = ddwbl.LightAttributes;
                            }
                            else if (fdwbl != null)
                            {
                                lightAttrs = fdwbl.OwnerFragment?.LightAttributes;
                            }
                            if (lightAttrs != null)
                            {
                                eemin = Vector3.Min(eemin, ent.BBMin);
                                eemax = Vector3.Max(eemax, ent.BBMax);
                                semin = Vector3.Min(semin, ent.BBMin - ent._CEntityDef.lodDist);
                                semax = Vector3.Max(semax, ent.BBMax + ent._CEntityDef.lodDist);


                                foreach (var la in lightAttrs)
                                {
                                    //transform this light with the entity position and orientation
                                    //generate lights data from it!


                                    //gotta transform the light position by the given bone! annoying
                                    Bone bone    = null;
                                    Matrix xform = Matrix.Identity;
                                    int boneidx  = 0;
                                    var skeleton = dwbl.Skeleton;
                                    if (skeleton?.Bones?.Data != null)
                                    {
                                        for (int j = 0; j < skeleton.Bones.Data.Count; j++)
                                        {
                                            var tbone = skeleton.Bones.Data[j];
                                            if (tbone.Id == la.BoneId)
                                            {
                                                boneidx = j;
                                                bone    = tbone;
                                                break;
                                            }
                                        }
                                        if (bone != null)
                                        {
                                            var modeltransforms = skeleton.Transformations;
                                            var fragtransforms  = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod?.FragTransforms?.Data;
                                            var fragtransformid = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysIndex ?? 0;
                                            var fragoffset      = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod.Unknown_30h ?? Vector4.Zero;
                                            fragoffset.W        = 0.0f;

                                            if ((fragtransforms != null) && (fragtransformid < fragtransforms.Length))
                                            {
                                                xform       = fragtransforms[fragtransformid];
                                                xform.Row4 += fragoffset;
                                            }
                                            else
                                            {
                                                //when using the skeleton's matrices, they need to be transformed by parent
                                                xform         = modeltransforms[boneidx];
                                                xform.Column4 = Vector4.UnitW;
                                                //xform = Matrix.Identity;
                                                ushort[] pinds   = skeleton.ParentIndices;
                                                ushort parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (ushort)65535;
                                                while (parentind < pinds.Length)
                                                {
                                                    Matrix ptrans  = (parentind < modeltransforms.Length) ? modeltransforms[parentind] : Matrix.Identity;
                                                    ptrans.Column4 = Vector4.UnitW;
                                                    xform          = Matrix.Multiply(ptrans, xform);
                                                    parentind      = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (ushort)65535;
                                                }
                                            }
                                        }
                                    }



                                    Vector3 lpos = new Vector3(la.PositionX, la.PositionY, la.PositionZ);
                                    Vector3 ldir = new Vector3(la.DirectionX, la.DirectionY, la.DirectionZ);
                                    Vector3 bpos = xform.Multiply(lpos);
                                    Vector3 bdir = xform.MultiplyRot(ldir);
                                    Vector3 epos = ent.Orientation.Multiply(bpos) + ent.Position;
                                    Vector3 edir = ent.Orientation.Multiply(bdir);

                                    uint r = la.ColorR;
                                    uint g = la.ColorG;
                                    uint b = la.ColorB;
                                    uint i = (byte)Math.Min(la.Intensity * 4, 255);
                                    uint c = (i << 24) + (r << 16) + (g << 8) + b;

                                    uint h = 123456; //TODO: what hash to use???

                                    //@Calcium:
                                    //1 = point
                                    //2 = spot
                                    //4 = capsule
                                    uint type = 1;
                                    uint t    = la.TimeFlags + (type << 26);

                                    var maxext = (byte)Math.Max(Math.Max(la.ExtentX, la.ExtentY), la.ExtentZ);


                                    position.Add(new MetaVECTOR3(epos));
                                    colour.Add(c);
                                    direction.Add(new MetaVECTOR3(edir));
                                    falloff.Add(la.Falloff);
                                    falloffExponent.Add(la.FalloffExponent);
                                    timeAndStateFlags.Add(t);
                                    hash.Add(h);
                                    coneInnerAngle.Add((byte)la.ConeInnerAngle);
                                    coneOuterAngleOrCapExt.Add(Math.Max((byte)la.ConeOuterAngle, maxext));
                                    coronaIntensity.Add((byte)la.CoronaIntensity);
                                }
                            }
                        }
                    }
                }


                if (position.Count == 0)
                {
                    MessageBox.Show("No lights found in project!");
                    return;
                }


                var lodymap               = new YmapFile();
                var distymap              = new YmapFile();
                var ll                    = new YmapLODLights();
                var dl                    = new YmapDistantLODLights();
                var cdl                   = new CDistantLODLight();
                cdl.category              = 1;
                dl.CDistantLODLight       = cdl;
                dl.positions              = position.ToArray();
                dl.colours                = colour.ToArray();
                ll.direction              = direction.ToArray();
                ll.falloff                = falloff.ToArray();
                ll.falloffExponent        = falloffExponent.ToArray();
                ll.timeAndStateFlags      = timeAndStateFlags.ToArray();
                ll.hash                   = hash.ToArray();
                ll.coneInnerAngle         = coneInnerAngle.ToArray();
                ll.coneOuterAngleOrCapExt = coneOuterAngleOrCapExt.ToArray();
                ll.coronaIntensity        = coronaIntensity.ToArray();


                lodymap._CMapData.flags         = 0;
                distymap._CMapData.flags        = 2;
                lodymap._CMapData.contentFlags  = 128;
                distymap._CMapData.contentFlags = 256;

                lodymap._CMapData.entitiesExtentsMin   = eemin;
                lodymap._CMapData.entitiesExtentsMax   = eemax;
                lodymap._CMapData.streamingExtentsMin  = semin - 1000f;
                lodymap._CMapData.streamingExtentsMax  = semax + 1000f;
                distymap._CMapData.entitiesExtentsMin  = eemin;
                distymap._CMapData.entitiesExtentsMax  = eemax;
                distymap._CMapData.streamingExtentsMin = semin - 5000f; //make it huge
                distymap._CMapData.streamingExtentsMax = semax + 5000f;

                lodymap.LODLights         = ll;
                distymap.DistantLODLights = dl;

                var lodname                     = pname + "_lodlights";
                var distname                    = pname + "_distantlights";
                lodymap.Name                    = lodname;
                lodymap._CMapData.name          = JenkHash.GenHash(lodname);
                lodymap.RpfFileEntry            = new RpfResourceFileEntry();
                lodymap.RpfFileEntry.Name       = lodname + ".ymap";
                lodymap.RpfFileEntry.NameLower  = lodname + ".ymap";
                distymap.Name                   = distname;
                distymap._CMapData.name         = JenkHash.GenHash(distname);
                distymap.RpfFileEntry           = new RpfResourceFileEntry();
                distymap.RpfFileEntry.Name      = distname + ".ymap";
                distymap.RpfFileEntry.NameLower = distname + ".ymap";

                lodymap._CMapData.parent = distymap._CMapData.name;

                ProjectForm.Invoke((MethodInvoker) delegate
                {
                    ProjectForm.AddYmapToProject(lodymap);
                    ProjectForm.AddYmapToProject(distymap);
                });

                var stats = "";
                UpdateStatus("Process complete. " + stats);
                GenerateComplete();
            });
        }