From 0fef64ece9bcf566c06889ca771c4aeb2533baef Mon Sep 17 00:00:00 2001 From: dexy Date: Thu, 6 Jan 2022 21:35:33 +1100 Subject: [PATCH] Use animated bone transform for lights rendering, Made lights editor widget and selection outlines also use bone transform --- CodeWalker/Forms/ModelForm.cs | 23 ++++++++++++++++++- CodeWalker/Forms/ModelLightForm.cs | 13 ++++++++++- CodeWalker/Rendering/Renderable.cs | 9 ++------ CodeWalker/Rendering/Renderer.cs | 20 +++++++++------- CodeWalker/Rendering/Shaders/DeferredScene.cs | 21 +++++++++++++---- 5 files changed, 65 insertions(+), 21 deletions(-) diff --git a/CodeWalker/Forms/ModelForm.cs b/CodeWalker/Forms/ModelForm.cs index 9d9fd30..ecb0364 100644 --- a/CodeWalker/Forms/ModelForm.cs +++ b/CodeWalker/Forms/ModelForm.cs @@ -109,6 +109,7 @@ namespace CodeWalker.Forms bool editingLights = false; public LightAttributes selectedLight = null; public bool showLightGizmos = true; + public Skeleton Skeleton = null; ExploreForm exploreForm = null; RpfFileEntry rpfFileEntry = null; @@ -553,7 +554,9 @@ namespace CodeWalker.Forms { if (showLightGizmos) { - Renderer.RenderSelectionDrawableLight(selectedLight); + Bone bone = null; + Skeleton?.BonesMap?.TryGetValue(selectedLight.BoneId, out bone); + Renderer.RenderSelectionDrawableLight(selectedLight, bone); } } } @@ -594,6 +597,15 @@ namespace CodeWalker.Forms //called during UpdateWidgets() if (newpos == oldpos) return; if (selectedLight == null || lightForm == null || !editingLights) return; + + Bone bone = null; + Skeleton?.BonesMap?.TryGetValue(selectedLight.BoneId, out bone); + if (bone != null) + { + var xforminv = Matrix.Invert(bone.AbsTransform); + newpos = xforminv.Multiply(newpos); + } + selectedLight.Position = newpos; selectedLight.UpdateRenderable = true; } @@ -718,6 +730,8 @@ namespace CodeWalker.Forms if (ydr.Drawable != null) { MoveCameraToView(ydr.Drawable.BoundingCenter, ydr.Drawable.BoundingSphereRadius); + + Skeleton = ydr.Drawable.Skeleton; } if(ydr.Drawable?.LightAttributes.data_items.Length > 0) @@ -741,6 +755,11 @@ namespace CodeWalker.Forms foreach (var d in Ydd.Drawables) { maxrad = Math.Max(maxrad, d.BoundingSphereRadius); + + if (d.Skeleton != null) + { + Skeleton = d.Skeleton; + } } MoveCameraToView(Vector3.Zero, maxrad); } @@ -781,6 +800,8 @@ namespace CodeWalker.Forms if (dr != null) { MoveCameraToView(dr.BoundingCenter, dr.BoundingSphereRadius); + + Skeleton = dr.Skeleton; } if (yft.Fragment?.LightAttributes.data_items.Length > 0) diff --git a/CodeWalker/Forms/ModelLightForm.cs b/CodeWalker/Forms/ModelLightForm.cs index 91dcda9..77c5e5f 100644 --- a/CodeWalker/Forms/ModelLightForm.cs +++ b/CodeWalker/Forms/ModelLightForm.cs @@ -233,7 +233,18 @@ namespace CodeWalker.Forms selectedLight = light; ModelForm.selectedLight = light; UpdateUI(); - ModelForm.SetWidgetTransform(light.Position, light.Orientation, new Vector3(light.Falloff)); + + var pos = light.Position; + Bone bone = null; + ModelForm.Skeleton?.BonesMap?.TryGetValue(light.BoneId, out bone); + if (bone != null) + { + var xform = bone.AbsTransform; + pos = xform.Multiply(pos); + //TODO:? handle bone's rotation correctly for widget?? + } + + ModelForm.SetWidgetTransform(pos, light.Orientation, new Vector3(light.Falloff)); } } private void SelectLightTreeNode(LightAttributes light) diff --git a/CodeWalker/Rendering/Renderable.cs b/CodeWalker/Rendering/Renderable.cs index b2dd047..bd6a3bc 100644 --- a/CodeWalker/Rendering/Renderable.cs +++ b/CodeWalker/Rendering/Renderable.cs @@ -1360,6 +1360,7 @@ namespace CodeWalker.Rendering { public LightAttributes OwnerLight; public Renderable Owner; + public Bone Bone; public Vector3 Position; public Vector3 Colour; public Vector3 Direction; @@ -1384,13 +1385,7 @@ namespace CodeWalker.Rendering var dir = l.Direction; var tan = l.Tangent; var bones = Owner?.Skeleton?.BonesMap; - if ((bones != null) && (bones.TryGetValue(l.BoneId, out Bone bone))) - { - var xform = bone.AbsTransform; - pos = xform.Multiply(pos); - dir = xform.MultiplyRot(dir); - tan = xform.MultiplyRot(tan); - } + bones?.TryGetValue(l.BoneId, out Bone); Position = pos; Colour = new Vector3(l.ColorR, l.ColorG, l.ColorB) * (2.0f * l.Intensity / 255.0f); Direction = dir; diff --git a/CodeWalker/Rendering/Renderer.cs b/CodeWalker/Rendering/Renderer.cs index 52b75ea..ef7759f 100644 --- a/CodeWalker/Rendering/Renderer.cs +++ b/CodeWalker/Rendering/Renderer.cs @@ -1025,21 +1025,25 @@ namespace CodeWalker.Rendering v.Position = c5; SelectionLineVerts.Add(v); } - public void RenderSelectionDrawableLight(LightAttributes dlight) + public void RenderSelectionDrawableLight(LightAttributes light, Bone bone) { var colblu = (uint)(new Color(0, 0, 255, 255).ToRgba()); var colwht = (uint)(new Color(255, 255, 255, 255).ToRgba()); - RenderableLight light = new RenderableLight(); - light.Init(dlight); - var pos = light.Position; var dir = light.Direction; - var tx = light.TangentX; - var ty = light.TangentY; + var tx = light.Tangent; + if (bone != null) + { + var xform = bone.AnimTransform; + pos = xform.Multiply(pos); + dir = xform.MultiplyRot(dir); + tx = xform.MultiplyRot(tx); + } + var ty = Vector3.Normalize(Vector3.Cross(dir, tx)); var extent = light.Falloff; - var innerAngle = light.ConeInnerAngle; - var outerAngle = light.ConeOuterAngle; + var innerAngle = Math.Min(light.ConeInnerAngle, light.ConeOuterAngle) * 0.01745329f; + var outerAngle = Math.Max(light.ConeInnerAngle, light.ConeOuterAngle) * 0.01745329f; //pi/180 var type = light.Type; switch (type) { diff --git a/CodeWalker/Rendering/Shaders/DeferredScene.cs b/CodeWalker/Rendering/Shaders/DeferredScene.cs index 153a9a2..30a3c14 100644 --- a/CodeWalker/Rendering/Shaders/DeferredScene.cs +++ b/CodeWalker/Rendering/Shaders/DeferredScene.cs @@ -546,10 +546,23 @@ namespace CodeWalker.Rendering var li = lights[i]; var rl = li.Light; - LightInstVars.Vars.InstPosition = li.EntityPosition + li.EntityRotation.Multiply(rl.Position) - camera.Position; - LightInstVars.Vars.InstDirection = li.EntityRotation.Multiply(rl.Direction); - LightInstVars.Vars.InstTangentX = li.EntityRotation.Multiply(rl.TangentX); - LightInstVars.Vars.InstTangentY = li.EntityRotation.Multiply(rl.TangentY); + var pos = rl.Position; + var dir = rl.Direction; + var tx = rl.TangentX; + var ty = rl.TangentY; + if (rl.Bone != null) + { + var xform = rl.Bone.AnimTransform; + pos = xform.Multiply(pos); + dir = xform.MultiplyRot(dir); + tx = xform.MultiplyRot(tx); + ty = xform.MultiplyRot(ty); + } + + LightInstVars.Vars.InstPosition = li.EntityPosition + li.EntityRotation.Multiply(pos) - camera.Position; + LightInstVars.Vars.InstDirection = li.EntityRotation.Multiply(dir); + LightInstVars.Vars.InstTangentX = li.EntityRotation.Multiply(tx); + LightInstVars.Vars.InstTangentY = li.EntityRotation.Multiply(ty); LightInstVars.Vars.InstCapsuleExtent = li.EntityRotation.Multiply(rl.CapsuleExtent); LightInstVars.Vars.InstCullingPlaneNormal = li.EntityRotation.Multiply(rl.CullingPlaneNormal); LightInstVars.Vars.InstColour = rl.Colour;