Exemple #1
0
        private WhModel LoadWhCharacterModel(WhRace race, WhGender gender, string[] itemIds)
        {
            var gathererItems = WhDataLoader.LoadItemsFromGatherer(itemIds);

            var options = new WhViewerOptions()
            {
                Cls = WhClass.WARRIOR, Hd = true
            };

            if (gathererItems != null)
            {
                options.Items = gathererItems
                                .Select((x, i) => new WhViewerOptions.Item()
                {
                    Slot = x.Value.OtherData.SlotBak,
                    Id   = x.Value.OtherData.DisplayId,
                    // Пока так, когда узнать откуда взять этот id - надо тоже прописать
                    VisualId = null
                })
                                .ToArray();
            }

            var characterModel = new WhModel(
                options,
                WhModelInfo.CreateForCharacter(race, gender), 0);

            WhDefferedList.Execute();

            characterModel.EmulateDraw(false);

            return(characterModel);
        }
Exemple #2
0
        private WowBone[] MakeBoneHierarchyFromWhModel(WhModel whModel)
        {
            if (whModel.Bones == null || whModel.Bones.Length == 0)
            {
                return(null);
            }

            // Формируем начальный массив всех костей и задаем абсолютные позиции для всех костей (прописываем их временно в локальную позицию)
            var wowBones = whModel.Bones
                           .Select(x => new WowBone()
            {
                Index         = Convert.ToByte(x.Index),
                Id            = x.Id,
                LocalPosition = Vec3.Scale(Vec3.ConvertPositionFromWh(x.Pivot), _scale)
            })
                           .ToArray();

            // Прописываем иерархию родители/дети для всех костей

            for (int boneIdx = 0; boneIdx < wowBones.Length; boneIdx++)
            {
                var wowBone = wowBones[boneIdx];
                var whBone  = whModel.Bones[boneIdx];

                // Если у текущей кости есть родительская кость
                if (whBone.Parent >= 0)
                {
                    wowBone.ParentBone = wowBones[whBone.Parent];
                    wowBone.ParentBone.ChildBones.Add(wowBone);
                }
            }

            return(wowBones);
        }
        public WhBone(WhModel model, int index, BinaryReader r)
        {
            Model       = model;
            Index       = index;
            KeyId       = r.ReadInt32();
            Flags       = r.ReadUInt32();
            Parent      = r.ReadInt16();
            Mesh        = r.ReadUInt16();
            Id          = r.ReadUInt32();
            Pivot       = new Vec3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
            Translation = WhAnimatedVec3.ReadSet(r);
            Rotation    = WhAnimatedQuat.ReadSet(r);
            Scale       = WhAnimatedVec3.ReadSet(r);
            Hidden      = false;
            Updated     = false;

            // Не стал делать
            //self.transformedPivot = vec3.create();
            //self.matrix = mat4.create();
            //self.tmpVec = vec3.create();
            //self.tmpQuat = quat.create();
            //self.tmpMat = mat4.create();

            // Я сделал. -1 значит что эта переменная будет игнорироваться при Update модели
            IndexInParentModel = -1;
        }
Exemple #4
0
        private WowMeshWithMaterials MakeMeshFromWhModel(WhModel whModel)
        {
            var mesh = new WowMeshWithMaterials();

            mesh.Vertices = whModel.Vertices.Select(x => MakeVertexFromWhVertex(x)).ToArray();

            mesh.Submeshes = new List <WowSubmeshWithMaterials>();

            foreach (var whTexUnit in whModel.SortedTexUnits)
            {
                if (!whTexUnit.Show)
                {
                    continue;
                }

                var triangles = ConvertTrianglesFromWh(whModel.Indices
                                                       .Skip(whTexUnit.Mesh.IndexStart)
                                                       .Take(whTexUnit.Mesh.IndexCount)
                                                       .ToArray());

                var material = MakeMaterialFromWhTexUnit(whTexUnit);

                var submesh = new WowSubmeshWithMaterials(mesh, triangles, material);

                mesh.Submeshes.Add(submesh);
            }

            mesh.RemoveUnusedVertices();

            return(mesh);
        }
Exemple #5
0
        private void AddAdditionalMeshToCharacterObject(WowObject characterObject, WhModel whModel)
        {
            var itemObject = new WowObject()
            {
                Parent         = characterObject,
                GlobalPosition = new Vec3(0, 0, 0),
            };

            // На этот раз добавляем не в MainMesh а делаем дополнительный меш, таким образом этот меш будет исползовать те же кости что и основной
            characterObject.Meshes.Add(MakeMeshFromWhModel(whModel));
        }
Exemple #6
0
        public WhItemVisual(WhModel model, int id)
        {
            Model  = model;
            Models = null;
            Loaded = false;

            if (id != 0)
            {
                Load(id);
            }
        }
Exemple #7
0
        private WhModel LoadWhCharacterModel(WhViewerOptions opts)
        {
            var characterModel = new WhModel(
                opts,
                opts.Model, 0);

            WhDefferedList.Execute();

            characterModel.EmulateDraw(false);

            return(characterModel);
        }
        public WhMaterial(WhModel model, int index, BinaryReader r)
        {
            Model = model;
            Index = index;

            Type     = r.ReadInt32();
            Flags    = r.ReadUInt32();
            Filename = r.ReadUInt32();

            Texture = null;

            Load();
        }
Exemple #9
0
        // ToDo: так как тут идет ссылка на Bitmap, который IDispossable, возможно стоит этот класс тоже сделать IDispossable (у js варианта есть destroy метод)

        // ToDo: незнаю пока какого типа index, пока будет int (возможно он не используется, тогда убрать его вообще)
        // Иногда сюда присваивается значение из енума Region, а иногда 0 или 1 (которые по энаму региона явно ничего не значат), то есть видмо разное может означать этот индекс
        public WhTexture(WhModel model, int index, uint file)
        {
            Model = model;
            Index = index;

            // url формировать и сохранять тут не буду, т.к. он нафиг не нужен
            // также не буду добавлять alphaimg, mergedimg и текстуры, так как по сути это все одно и то же (= Img)

            Img = null;

            Loaded = false;

            WhDefferedList.Add(() => LoadAndHandle_Texture(file));
        }
        //tmpColor
        //tmpVec
        //tmpQuat

        public void Setup(WhModel model)
        {
            Model  = model;
            Mesh   = model.Meshes[MeshIndex];
            MeshId = Mesh.Id;

            WhRenderFlag.ComputeFlags(this);

            // На момент теста эта штука была undefined, так что думаю можно это не использовать
            //window.MeshLoadFilter && window.MeshLoadFilter(self);

            //var program = ZamModelViewer.Wow.ShaderTool.GetWowProgram(self.shaderId, self.opcount, self.renderFlag);
            //self.program = program;

            for (int i = 0; i < Opcount; i++)
            {
                if (MaterialIndex > -1 && MaterialIndex < model.MaterialLookup.Length)
                {
                    var matIdx = model.MaterialLookup[MaterialIndex + i];
                    if (matIdx > -1 && matIdx < model.Materials.Length)
                    {
                        Material.Insert(i, model.Materials[matIdx]);
                    }
                }

                //    if (self.textureAnimIndex > -1 && self.textureAnimIndex < model.textureAnimLookup.length) {
                //        var animIdx = model.textureAnimLookup[self.textureAnimIndex + i];
                //        if (animIdx > -1 && model.textureAnims && animIdx < model.textureAnims.length) {
                //            self.textureAnim.splice(i, 0, model.textureAnims[animIdx])
                //        } else {
                //            self.textureAnim.splice(i, 0, null)
                //        }
                //    }
            }

            //if (self.flip) {
            //    self.material = self.material.reverse();
            //    self.textureAnim = self.textureAnim.reverse()
            //}
            //if (model.colors && self.colorIndex > -1 && self.colorIndex < model.colors.length) {
            //    self.color = model.colors[self.colorIndex]
            //}
            //if (self.alphaIndex > -1 && self.alphaIndex < model.alphaLookup.length) {
            //    var alphaIdx = model.alphaLookup[self.alphaIndex];
            //    if (alphaIdx > -1 && alphaIdx < model.alphas.length) {
            //        self.alpha = model.alphas[alphaIdx]
            //    }
            //}
        }
        public WhItem(WhModel model, WhSlot slot, int id, WhRace race, WhGender gender)
        {
            Model       = model;
            Slot        = slot;
            UniqueSlot  = WhGlobal.UniqueSlots[slot];
            SortValue   = WhGlobal.SlotOrder[slot];
            Models      = null;
            Textures    = null;
            GeosetGroup = null;
            Flags       = 0;
            Loaded      = false;
            Visual      = null;
            Visualid    = 0;

            if (id != 0)
            {
                Load(id, race, gender);
            }
        }
Exemple #12
0
        public WowObject BuildFromCharacterWhModel(WhModel whCharacterModel)
        {
            // ToDo: Смотреть как работает, Wow.Model.draw,
            // по сути в зависимости от алгоритма отрисовки идет и алгоритм построения объектов для дальнейшей отрисовки (то что тут происодит)

            // Сам перс

            var characterObject = new WowObject();

            // Добавляем MainMesh
            characterObject.Meshes.Add(MakeMeshFromWhModel(whCharacterModel));

            characterObject.Bones = MakeBoneHierarchyFromWhModel(whCharacterModel);
            characterObject.OptimizeBones();
            TranslateBonePositionsFromGlobalToLocal(characterObject);

            // Рога

            if (whCharacterModel.HornsModel != null)
            {
                AddAdditionalMeshToCharacterObject(characterObject, whCharacterModel.HornsModel);
            }

            // Маунт

            if (whCharacterModel.Mount != null)
            {
                // ToDo: хз че тут  делать, создать его вообще отдельно?

                //var mountObject = new WowObject()
                //{
                //    Parent = characterObject
                //};

                //// MainMesh (не факт что я вообще тут правильно делаю, т.к. еще не тестил)
                //mountObject.Meshes.Add(MakeMeshFromWhModel(whCharacterModel.Mount));

                //characterObject.Children.Add(mountObject);
            }

            // Итемы

            foreach (var whItemInSlot in whCharacterModel.Items)
            {
                var whItem = whItemInSlot.Value;

                if (whItem?.Models == null)
                {
                    continue;
                }

                foreach (var whItemModel in whItem.Models)
                {
                    if (whItemModel?.Model == null)
                    {
                        continue;
                    }

                    if (whItemModel.Bone > -1 && whItemModel.Bone < whCharacterModel.Bones.Length)
                    {
                        var itemPosition = Vec3.Scale(Vec3.ConvertPositionFromWh(whItemModel.Attachment.Position), _scale);

                        var itemObject = new WowObject()
                        {
                            Parent         = characterObject,
                            GlobalPosition = itemPosition,
                        };

                        // MainMesh - по сути он использоваться будет тлолько в AttachedWowObjects кости
                        itemObject.Meshes.Add(MakeMeshFromWhModel(whItemModel.Model));

                        // Если у итема есть кость, к которой можно прикрепиться
                        if (itemObject.Parent != null && whItemModel.Attachment.Bone >= 0)
                        {
                            var parentAttachmentBone   = itemObject.Parent.Bones[whItemModel.Attachment.Bone];
                            var whParentAttachmentBone = whItemModel.Model.Parent.Bones[whItemModel.Attachment.Bone];

                            // записываем объект этого итема в кость, к которой крепимся(у родительского объекта)
                            parentAttachmentBone.AttachedWowObjects.Add(itemObject);

                            // меняем данные о костях в вершинах так итема так, чтобы при привязке к скелету родителя этот итем двигался вместе с костью
                            // (при этом в иерархии объектов он не будет в ноде кости, а будет на том же уровне что и родительский объект, к скелету которого мы привязываем итем)

                            itemObject.MainMesh.ApplyTransform(
                                whParentAttachmentBone.LastUpdatedTranslation,
                                whParentAttachmentBone.LastUpdatedRotation,
                                whParentAttachmentBone.LastUpdatedScale);

                            var eachVertexItemBoneIndexes = new ByteVec4((byte)parentAttachmentBone.Index, 0, 0, 0);
                            var eachVertexItemBoneWeights = new Vec4(1, 0, 0, 0);

                            foreach (var vertex in itemObject.MainMesh.Vertices)
                            {
                                vertex.BoneIndexes = eachVertexItemBoneIndexes;
                                vertex.BoneWeights = eachVertexItemBoneWeights;
                            }
                        }

                        if (whItem.Visual?.Models != null && whItemModel.Model.Loaded)
                        {
                            foreach (var visual in whItem.Visual.Models)
                            {
                                if (visual != null)
                                {
                                    var visualPosition = Vec3.Scale(Vec3.ConvertPositionFromWh(visual.Attachment.Position), _scale);

                                    var visualObject = new WowObject()
                                    {
                                        Parent         = characterObject,
                                        GlobalPosition = visualPosition
                                    };

                                    // MainMesh (не факт что я вообще тут правильно делаю, т.к. еще не тестил)
                                    visualObject.Meshes.Add(MakeMeshFromWhModel(visual.Model));
                                }
                            }
                        }
                    }
                    else if (whItemModel.Bone == -1)
                    {
                        AddAdditionalMeshToCharacterObject(characterObject, whItemModel.Model);
                    }
                }
            }

            foreach (var collection in whCharacterModel.CollectionModels.Values)
            {
                if (collection == null)
                {
                    continue;
                }

                AddAdditionalMeshToCharacterObject(characterObject, collection);
            }

            return(characterObject);
        }
        public void LoadMeta(WhJsonMeta meta)
        {
            Flags        = meta.Item.Flags;
            Slot         = meta.Item.InventoryType;
            ItemClass    = meta.Item.ItemClass;
            ItemSubClass = meta.Item.ItemSubClass;

            if (meta.ComponentTextures != null)
            {
                Textures = new List <WhItemTexture>();
                foreach (var componentTexture in meta.ComponentTextures)
                {
                    var region  = componentTexture.Key;
                    var texFile = SelectBestTexture(meta, componentTexture.Value, Model.Gender, Model.Class, Model.Race);

                    WhItemTexture texture = null;
                    if (texFile != 0)
                    {
                        texture = new WhItemTexture()
                        {
                            Region  = region,
                            Gender  = Model.Gender,
                            File    = texFile,
                            Texture = null
                        };

                        if (region != WhRegion.Base)
                        {
                            texture.Texture = new WhTexture(Model, (int)region, texFile);
                        }
                        else if (Slot == WhSlot.CAPE)
                        {
                            Model.TextureOverrides[2] = new WhTexture(Model, 2, texFile);
                        }
                    }

                    Textures.Add(texture);
                }
            }

            GeosetGroup = meta.Item.GeosetGroup;
            if (Slot == WhSlot.HEAD)
            {
                var gender     = Model.Gender;
                var hideGeoset = gender == WhGender.MALE ? meta.Item.HideGeosetMale : meta.Item.HideGeosetFemale;
                if (gender == WhGender.MALE)
                {
                    HideGeosetMale = meta.Item.HideGeosetMale;
                }
                else
                {
                    HideGeosetFemale = meta.Item.HideGeosetFemale;
                }
            }

            if (Slot == WhSlot.SHOULDER)
            {
                Models = new List <WhItemModel>()
                {
                    null, null
                }
            }
            ;
            else if (WhGlobal.SlotType[Slot] != WhType.ARMOR)
            {
                Models = new List <WhItemModel>()
                {
                    null
                }
            }
            ;

            if (Models != null)
            {
                for (int i = 0; i < Models.Count; i++)
                {
                    var model = new WhItemModel()
                    {
                        Race       = Race,
                        Gender     = Gender,
                        Bone       = -1,
                        Attachment = null,
                        Model      = null
                    };

                    var modelInfo = new WhModelInfo()
                    {
                        Type   = WhGlobal.SlotType[Slot],
                        Id     = Id.ToString(),
                        Parent = Model
                    };

                    if (Slot == WhSlot.SHOULDER)
                    {
                        modelInfo.Shoulder = i + 1;
                    }

                    model.Model = new WhModel(Model.Opts, modelInfo, i, true);
                    model.Model.LoadMeta(meta, modelInfo.Type);
                    Models[i] = model;
                }
            }

            if (Slot == WhSlot.BELT && meta.Model != 0)
            {
                var model = new WhItemModel()
                {
                    Race       = WhRace.Undefined2,
                    Gender     = WhGender.MALE,
                    Bone       = -1,
                    Attachment = null,
                    Model      = null
                };

                var modelInfo = new WhModelInfo()
                {
                    Type   = WhGlobal.SlotType[Slot],
                    Id     = Id.ToString(),
                    Parent = Model
                };

                model.Model = new WhModel(Model.Opts, modelInfo, 0, true);
                model.Model.LoadMeta(meta, WhType.ARMOR);
                Models = new List <WhItemModel>()
                {
                    model
                };
            }

            if (Slot == WhSlot.SHIRT || Slot == WhSlot.CHEST || Slot == WhSlot.ROBE || Slot == WhSlot.BELT || Slot == WhSlot.PANTS || Slot == WhSlot.HANDS || Slot == WhSlot.BOOTS || Slot == WhSlot.HEAD)
            {
                int componentIndex = 0;
                if (Slot == WhSlot.HEAD)
                {
                    componentIndex = 1;
                }

                if (meta.ComponentModels != null && meta.ComponentModels.ContainsKey(componentIndex.ToString()))
                {
                    var modelId = meta.ComponentModels[componentIndex.ToString()];

                    if (modelId != 0 && meta.ModelFiles.ContainsKey(modelId))
                    {
                        var modelInfo = new WhModelInfo()
                        {
                            Type   = WhGlobal.SlotType[Slot],
                            Id     = Id.ToString(),
                            Parent = Model
                        };

                        var model = new WhModel(Model.Opts, modelInfo, 0, true);

                        model.Meta    = meta;
                        model.IsDirty = true;

                        var race   = WhRace.HUMAN;
                        var gender = WhGender.MALE;
                        var cls    = WhClass.WARRIOR;

                        if (Model != null)
                        {
                            race   = Model.Race;
                            gender = Model.Gender;
                            cls    = Model.Class;
                        }

                        var modelFile = model.SelectBestModel(modelId, gender, cls, race);
                        if (modelFile != 0)
                        {
                            if (Model != null)
                            {
                                if (!Model.CollectionModels.ContainsKey(modelFile))
                                {
                                    Model.CollectionModels[modelFile] = model;
                                    CollectionModel = model;
                                    model._Load(WhType.PATH, modelFile.ToString());
                                }
                                else
                                {
                                    CollectionModel = Model.CollectionModels[modelFile];
                                }
                            }
                            else
                            {
                                model._Load(WhType.PATH, modelFile.ToString());
                            }

                            if (meta.Textures != null)
                            {
                                foreach (var texturePair in meta.Textures)
                                {
                                    model.TextureOverrides[texturePair.Key] = new WhTexture(model, texturePair.Key, texturePair.Value);
                                }
                            }
                        }
                    }
                }
            }

            if (Slot == WhSlot.PANTS && GeosetGroup[2] > 0)
            {
                SortValue += 2;
            }

            if (Visualid != 0)
            {
                Visual = new WhItemVisual(Models[0].Model, Visualid);
            }

            Loaded = true;

            Model.UpdateMeshes();
        }