diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs index e26dab8..bab1f01 100644 --- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs +++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs @@ -831,10 +831,10 @@ namespace CodeWalker.GameFiles } } - skel.TransformationsInverted = (Matrix[])TransformationsInverted.Clone(); - skel.Transformations = (Matrix[])Transformations.Clone(); - skel.ParentIndices = (short[])ParentIndices.Clone(); - skel.ChildIndices = (short[])ChildIndices.Clone(); + skel.TransformationsInverted = (Matrix[])TransformationsInverted?.Clone(); + skel.Transformations = (Matrix[])Transformations?.Clone(); + skel.ParentIndices = (short[])ParentIndices?.Clone(); + skel.ChildIndices = (short[])ChildIndices?.Clone(); skel.AssignBoneParents(); skel.BuildBonesMap(); @@ -2657,6 +2657,70 @@ namespace CodeWalker.GameFiles if (DrawableModelsX != null) list.Add(DrawableModelsX); return list.ToArray(); } + + + + public DrawableBase ShallowCopy() + { + DrawableBase r = null; + if (this is FragDrawable fd) + { + var f = new FragDrawable(); + f.Unknown_0A8h = fd.Unknown_0A8h; + f.Unknown_0ACh = fd.Unknown_0ACh; + f.FragMatrix = fd.FragMatrix; + f.FragMatricesIndsCount = fd.FragMatricesIndsCount; + f.FragMatricesCount = fd.FragMatricesCount; + f.Count3 = fd.Count3; + f.Count4 = fd.Count4; + f.Bound = fd.Bound; + f.FragMatricesInds = fd.FragMatricesInds; + f.FragMatrices = fd.FragMatrices; + f.Name = fd.Name; + f.OwnerFragment = fd.OwnerFragment; + f.OwnerFragmentCloth = fd.OwnerFragmentCloth; + f.OwnerFragmentPhys = fd.OwnerFragmentPhys; + r = f; + } + if (this is Drawable dd) + { + var d = new Drawable(); + d.LightAttributes = dd.LightAttributes; + d.Name = dd.Name; + d.Bound = dd.Bound; + r = d; + } + if (r != null) + { + r.BoundingCenter = BoundingCenter; + r.BoundingSphereRadius = BoundingSphereRadius; + r.BoundingBoxMin = BoundingBoxMin; + r.BoundingBoxMax = BoundingBoxMax; + r.LodDistHigh = LodDistHigh; + r.LodDistMed = LodDistMed; + r.LodDistLow = LodDistLow; + r.LodDistVlow = LodDistVlow; + r.Unknown_80h = Unknown_80h; + r.Unknown_84h = Unknown_84h; + r.Unknown_88h = Unknown_88h; + r.Unknown_8Ch = Unknown_8Ch; + r.Unknown_98h = Unknown_98h; + r.Unknown_9Ah = Unknown_9Ah; + r.ShaderGroup = ShaderGroup; + r.Skeleton = Skeleton?.Clone(); + r.DrawableModelsHigh = DrawableModelsHigh; + r.DrawableModelsMedium = DrawableModelsMedium; + r.DrawableModelsLow = DrawableModelsLow; + r.DrawableModelsVeryLow = DrawableModelsVeryLow; + r.DrawableModelsX = DrawableModelsX; + r.Joints = Joints; + r.AllModels = AllModels; + r.VertexDecls = VertexDecls; + r.Owner = Owner; + } + return r; + } + } [TypeConverter(typeof(ExpandableObjectConverter))] public class Drawable : DrawableBase diff --git a/CodeWalker.Core/World/Ped.cs b/CodeWalker.Core/World/Ped.cs index 09df2d0..c08413a 100644 --- a/CodeWalker.Core/World/Ped.cs +++ b/CodeWalker.Core/World/Ped.cs @@ -34,6 +34,7 @@ namespace CodeWalker.World public Vector3 Position { get; set; } = Vector3.Zero; public Quaternion Rotation { get; set; } = Quaternion.Identity; + public YmapEntityDef RenderEntity = new YmapEntityDef(); //placeholder entity object for rendering public void Init(string name, GameFileCache gfc) @@ -117,6 +118,8 @@ namespace CodeWalker.World Ycd?.ClipMap?.TryGetValue(cliphash, out cme); AnimClip = cme; + + UpdateEntity(); } @@ -182,7 +185,7 @@ namespace CodeWalker.World } - if (d != null) Drawables[index] = d; + if (d != null) Drawables[index] = d.ShallowCopy() as Drawable; if (t != null) Textures[index] = t; DrawableNames[index] = name; @@ -216,5 +219,13 @@ namespace CodeWalker.World } + + + public void UpdateEntity() + { + RenderEntity.SetPosition(Position); + RenderEntity.SetOrientation(Rotation); + } + } } diff --git a/CodeWalker.Core/World/Weapon.cs b/CodeWalker.Core/World/Weapon.cs index 344c250..1bcfbe8 100644 --- a/CodeWalker.Core/World/Weapon.cs +++ b/CodeWalker.Core/World/Weapon.cs @@ -16,6 +16,9 @@ namespace CodeWalker.World public MetaHash NameHash { get; set; } = 0;//base weapon name hash public MetaHash ModelHash { get; set; } = 0;//weapon model name hash, can be _hi + public YdrFile Ydr { get; set; } = null; + public Drawable Drawable { get; set; } = null; + public YmapEntityDef RenderEntity = new YmapEntityDef(); //placeholder entity object for rendering public Vector3 Position { get; set; } = Vector3.Zero; @@ -33,6 +36,25 @@ namespace CodeWalker.World NameHash = modelhash; ModelHash = ydrhash; + var useHash = ModelHash; + Ydr = gfc.GetYdr(ModelHash); + if (Ydr == null) + { + useHash = NameHash; + Ydr = gfc.GetYdr(NameHash); + } + + while ((Ydr != null) && (!Ydr.Loaded)) + { + Thread.Sleep(20);//kinda hacky + Ydr = gfc.GetYdr(useHash); + } + + if (Ydr != null) + { + Drawable = Ydr.Drawable?.ShallowCopy() as Drawable; + } + UpdateEntity(); } diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index a06adea..6ebe23b 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -2504,7 +2504,7 @@ namespace CodeWalker.Rendering return res; } - public bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, uint txdHash = 0, TextureDictionary txdExtra = null, Texture diffOverride = null, ClipMapEntry animClip = null, Ped ped = null) + public bool RenderDrawable(DrawableBase drawable, Archetype arche, YmapEntityDef entity, uint txdHash = 0, TextureDictionary txdExtra = null, Texture diffOverride = null, ClipMapEntry animClip = null) { //enqueue a single drawable for rendering. @@ -2529,10 +2529,10 @@ namespace CodeWalker.Rendering rndbl.ResetBoneTransforms(); } - return RenderRenderable(rndbl, arche, entity, ped); + return RenderRenderable(rndbl, arche, entity); } - private bool RenderRenderable(Renderable rndbl, Archetype arche, YmapEntityDef entity, Ped ped = null) + private bool RenderRenderable(Renderable rndbl, Archetype arche, YmapEntityDef entity) { //enqueue a single renderable for rendering. @@ -2572,15 +2572,6 @@ namespace CodeWalker.Rendering camrel += position; distance = entity.Distance; } - else if (ped != null) - { - position = ped.Position; - orientation = ped.Rotation; - bbmin += position; - bbmax += position; - camrel += position; - distance = (camrel + bscen).Length(); - } else { distance = (camrel + bscen).Length(); @@ -2751,18 +2742,10 @@ namespace CodeWalker.Rendering public void RenderWeapon(Weapon weapon, ClipMapEntry animClip = null) { - - YdrFile ydr = gameFileCache.GetYdr(weapon.ModelHash); - if (ydr == null) + if (weapon?.Drawable != null) { - ydr = gameFileCache.GetYdr(weapon.NameHash);//fallback to low def version? - } - - if ((ydr != null) && (ydr.Loaded) && (ydr.Drawable != null)) - { - var d = ydr.Drawable; + var d = weapon.Drawable; var txdhash = weapon.NameHash; - RenderDrawable(d, null, weapon.RenderEntity, txdhash, null, null, animClip); } } @@ -2849,7 +2832,7 @@ namespace CodeWalker.Rendering if (drawFlag) { - RenderDrawable(drawable, null, null, 0, td, texture, ac, ped); + RenderDrawable(drawable, null, ped.RenderEntity, 0, td, texture, ac); } diff --git a/World/CutsceneForm.cs b/World/CutsceneForm.cs index fa4e686..05d22b4 100644 --- a/World/CutsceneForm.cs +++ b/World/CutsceneForm.cs @@ -489,6 +489,7 @@ namespace CodeWalker.World { obj.Ped.Position = pos; obj.Ped.Rotation = rot; + obj.Ped.UpdateEntity(); obj.Ped.AnimClip = cme; } if (obj.Prop != null)