mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2026-05-14 09:14:49 +08:00
961 lines
34 KiB
C#
961 lines
34 KiB
C#
using CodeWalker.GameFiles;
|
|
using CodeWalker.World;
|
|
using SharpDX;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace CodeWalker.Forms
|
|
{
|
|
public partial class ModelLightForm : Form
|
|
{
|
|
private ModelForm ModelForm;
|
|
private Drawable Drawable;
|
|
private FragDrawable FragDrawable;
|
|
private Dictionary<uint, Drawable> DrawableDict;
|
|
|
|
LightAttributes selectedLight = null;
|
|
|
|
bool populatingui = false;
|
|
|
|
public ModelLightForm(ModelForm modelForm)
|
|
{
|
|
InitializeComponent();
|
|
|
|
ModelForm = modelForm;
|
|
}
|
|
|
|
public void LoadModel(DrawableBase drawable)
|
|
{
|
|
LightsTreeView.Nodes.Clear();
|
|
LightsTreeView.ShowRootLines = false;
|
|
|
|
var dr = drawable as Drawable;
|
|
var fr = drawable as FragDrawable;
|
|
|
|
if (dr != null)
|
|
{
|
|
Drawable = dr;
|
|
var lights = dr.LightAttributes;
|
|
if (lights != null)
|
|
{
|
|
AddLightsTreeNodes(lights.data_items);
|
|
}
|
|
}
|
|
else if (fr != null)
|
|
{
|
|
FragDrawable = fr;
|
|
var lights = fr.OwnerFragment?.LightAttributes;
|
|
if (lights != null)
|
|
{
|
|
AddLightsTreeNodes(lights.data_items);
|
|
}
|
|
}
|
|
}
|
|
public void LoadModels(Dictionary<uint, Drawable> dict)
|
|
{
|
|
DrawableDict = dict;
|
|
|
|
LightsTreeView.Nodes.Clear();
|
|
|
|
if (dict != null)
|
|
{
|
|
foreach (var kvp in dict)
|
|
{
|
|
MetaHash mhash = new MetaHash(kvp.Key);
|
|
var drawable = kvp.Value;
|
|
|
|
var dnode = LightsTreeView.Nodes.Add(mhash.ToString());
|
|
dnode.Tag = drawable;
|
|
|
|
var lights = drawable.LightAttributes.data_items;
|
|
if(lights != null)
|
|
{
|
|
AddLightsTreeNodes(lights, dnode);
|
|
}
|
|
|
|
dnode.Expand();
|
|
}
|
|
}
|
|
}
|
|
private void AddLightsTreeNodes(LightAttributes[] lights, TreeNode parent = null)
|
|
{
|
|
if (lights == null) return;
|
|
|
|
for (int mi = 0; mi < lights.Length; mi++)
|
|
{
|
|
var tnc = LightsTreeView.Nodes;
|
|
var light = lights[mi];
|
|
string mprefix = "Light" + (mi + 1).ToString() + " : " + light.Type.ToString();
|
|
var mnode = parent == null ? tnc.Add(mprefix) : parent.Nodes.Add(mprefix);
|
|
mnode.Tag = light;
|
|
mnode.Expand();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateUI()
|
|
{
|
|
var light = selectedLight;
|
|
|
|
if(light == null)
|
|
{
|
|
DeleteLightButton.Enabled = false;
|
|
EditDeleteLightMenu.Enabled = false;
|
|
populatingui = true;
|
|
PositionTextBox.Text = "";
|
|
DirectionTextBox.Text = "";
|
|
TangentTextBox.Text = "";
|
|
TypeComboBox.SelectedItem = "Point";
|
|
ColourRUpDown.Value = 0;
|
|
ColourGUpDown.Value = 0;
|
|
ColourBUpDown.Value = 0;
|
|
IntensityTextBox.Text = "";
|
|
FlashinessUpDown.Value = 0;
|
|
BoneIDUpDown.Value = 0;
|
|
GroupIDUpDown.Value = 0;
|
|
FalloffTextBox.Text = "";
|
|
FalloffExponentTextBox.Text = "";
|
|
InnerAngleTextBox.Text = "";
|
|
OuterAngleTextBox.Text = "";
|
|
CoronaSizeTextBox.Text = "";
|
|
CoronaIntensityTextBox.Text = "";
|
|
ExtentTextBox.Text = "";
|
|
ShadowBlurUpDown.Value = 0;
|
|
LightFadeDistanceUpDown.Value = 0;
|
|
CoronaZBiasTextBox.Text = "";
|
|
TextureHashTextBox.Text = "";
|
|
VolumeIntensityTextBox.Text = "";
|
|
VolumeSizeScaleTextBox.Text = "";
|
|
VolumeColorRUpDown.Value = 0;
|
|
VolumeColorGUpDown.Value = 0;
|
|
VolumeColorBUpDown.Value = 0;
|
|
VolumeOuterExponentTextBox.Text = "";
|
|
ShadowFadeDistanceUpDown.Value = 0;
|
|
SpecularFadeDistanceUpDown.Value = 0;
|
|
VolumetricFadeDistanceUpDown.Value = 0;
|
|
ShadowNearClipTextBox.Text = "";
|
|
CullingPlaneNormalTextBox.Text = "";
|
|
CullingPlaneOffsetTextBox.Text = "";
|
|
TimeFlagsTextBox.Text = "";
|
|
populatingui = false;
|
|
}
|
|
else
|
|
{
|
|
DeleteLightButton.Enabled = true;
|
|
EditDeleteLightMenu.Enabled = true;
|
|
populatingui = true;
|
|
PositionTextBox.Text = FloatUtil.GetVector3String(light.Position);
|
|
DirectionTextBox.Text = FloatUtil.GetVector3String(light.Direction);
|
|
TangentTextBox.Text = FloatUtil.GetVector3String(light.Tangent);
|
|
TypeComboBox.SelectedItem = light.Type.ToString();
|
|
ColourRUpDown.Value = light.ColorR;
|
|
ColourGUpDown.Value = light.ColorG;
|
|
ColourBUpDown.Value = light.ColorB;
|
|
ColourLabel.BackColor = System.Drawing.Color.FromArgb(light.ColorR, light.ColorG, light.ColorB);
|
|
IntensityTextBox.Text = FloatUtil.ToString(light.Intensity);
|
|
FlashinessUpDown.Value = light.Flashiness;
|
|
BoneIDUpDown.Value = light.BoneId;
|
|
GroupIDUpDown.Value = light.GroupId;
|
|
FalloffTextBox.Text = FloatUtil.ToString(light.Falloff);
|
|
FalloffExponentTextBox.Text = FloatUtil.ToString(light.FalloffExponent);
|
|
InnerAngleTextBox.Text = FloatUtil.ToString(light.ConeInnerAngle);
|
|
OuterAngleTextBox.Text = FloatUtil.ToString(light.ConeOuterAngle);
|
|
CoronaSizeTextBox.Text = FloatUtil.ToString(light.CoronaSize);
|
|
CoronaIntensityTextBox.Text = FloatUtil.ToString(light.CoronaIntensity);
|
|
ExtentTextBox.Text = FloatUtil.GetVector3String(light.Extent);
|
|
ShadowBlurUpDown.Value = light.ShadowBlur;
|
|
LightFadeDistanceUpDown.Value = light.LightFadeDistance;
|
|
CoronaZBiasTextBox.Text = FloatUtil.ToString(light.CoronaZBias);
|
|
TextureHashTextBox.Text = light.ProjectedTextureHash.ToCleanString();
|
|
VolumeIntensityTextBox.Text = FloatUtil.ToString(light.VolumeIntensity);
|
|
VolumeSizeScaleTextBox.Text = FloatUtil.ToString(light.VolumeSizeScale);
|
|
VolumeColorRUpDown.Value = light.VolumeOuterColorR;
|
|
VolumeColorGUpDown.Value = light.VolumeOuterColorG;
|
|
VolumeColorBUpDown.Value = light.VolumeOuterColorB;
|
|
VolumeColorLabel.BackColor = System.Drawing.Color.FromArgb(light.VolumeOuterColorR, light.VolumeOuterColorG, light.VolumeOuterColorB);
|
|
VolumeOuterExponentTextBox.Text = FloatUtil.ToString(light.VolumeOuterExponent);
|
|
ShadowFadeDistanceUpDown.Value = light.ShadowFadeDistance;
|
|
SpecularFadeDistanceUpDown.Value = light.SpecularFadeDistance;
|
|
VolumetricFadeDistanceUpDown.Value = light.VolumetricFadeDistance;
|
|
ShadowNearClipTextBox.Text = FloatUtil.ToString(light.ShadowNearClip);
|
|
CullingPlaneNormalTextBox.Text = FloatUtil.GetVector3String(light.CullingPlaneNormal);
|
|
CullingPlaneOffsetTextBox.Text = FloatUtil.ToString(light.CullingPlaneOffset);
|
|
TimeFlagsTextBox.Text = light.TimeFlags.ToString();
|
|
UpdateFlagsCheckBoxes();
|
|
populatingui = false;
|
|
}
|
|
}
|
|
|
|
public void UpdateLightParams()
|
|
{
|
|
if (selectedLight == null) return;
|
|
selectedLight.UpdateRenderable = true;
|
|
}
|
|
|
|
|
|
private LightAttributes NewLightAttribute()
|
|
{
|
|
LightAttributes light = new LightAttributes();
|
|
light.Direction = Vector3.BackwardLH;
|
|
light.Tangent = Vector3.Right;
|
|
light.Intensity = 5;
|
|
light.ConeInnerAngle = 5;
|
|
light.ConeOuterAngle = 35;
|
|
light.Extent = Vector3.One;
|
|
light.Type = LightType.Spot;
|
|
light.Falloff = 10;
|
|
light.ColorR = 255;
|
|
light.ColorG = 255;
|
|
light.ColorB = 255;
|
|
light.TimeFlags = 14680191;
|
|
return light;
|
|
}
|
|
private void SelectLight(LightAttributes light)
|
|
{
|
|
if (light == null)
|
|
{
|
|
selectedLight = null;
|
|
ModelForm.selectedLight = null;
|
|
UpdateUI();
|
|
}
|
|
else
|
|
{
|
|
selectedLight = light;
|
|
ModelForm.selectedLight = light;
|
|
UpdateUI();
|
|
ModelForm.SetWidgetTransform(light.Position, light.Orientation, new Vector3(light.Falloff));
|
|
}
|
|
}
|
|
private void SelectLightTreeNode(LightAttributes light)
|
|
{
|
|
foreach (TreeNode rn in LightsTreeView.Nodes)
|
|
{
|
|
if (rn.Tag == light)
|
|
{
|
|
LightsTreeView.SelectedNode = rn;
|
|
break;
|
|
}
|
|
var found = false;
|
|
foreach (TreeNode tn in rn.Nodes)
|
|
{
|
|
if (tn.Tag == light)
|
|
{
|
|
LightsTreeView.SelectedNode = tn;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (found)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
private void CreateLight()
|
|
{
|
|
selectedLight = NewLightAttribute();
|
|
if(Drawable != null)
|
|
{
|
|
if (Drawable.LightAttributes == null) Drawable.LightAttributes = new ResourceSimpleList64<LightAttributes>();
|
|
List<LightAttributes> lights = Drawable.LightAttributes.data_items?.ToList() ?? new List<LightAttributes>();
|
|
lights.Add(selectedLight);
|
|
Drawable.LightAttributes.data_items = lights.ToArray();
|
|
UpdateLightParams();
|
|
LoadModel(Drawable);
|
|
}
|
|
else if(FragDrawable != null)
|
|
{
|
|
if (FragDrawable.OwnerFragment.LightAttributes == null) FragDrawable.OwnerFragment.LightAttributes = new ResourceSimpleList64<LightAttributes>();
|
|
List<LightAttributes> lights = FragDrawable.OwnerFragment.LightAttributes.data_items?.ToList() ?? new List<LightAttributes>();
|
|
lights.Add(selectedLight);
|
|
FragDrawable.OwnerFragment.LightAttributes.data_items = lights.ToArray();
|
|
UpdateLightParams();
|
|
LoadModel(FragDrawable);
|
|
}
|
|
else
|
|
{
|
|
var n = LightsTreeView.SelectedNode;
|
|
if (n != null)
|
|
{
|
|
var dr = n.Tag as Drawable;
|
|
if (dr == null) { dr = n.Parent.Tag as Drawable; } //try parent node tag also
|
|
if (dr!= null)
|
|
{
|
|
if (dr.LightAttributes == null) dr.LightAttributes = new ResourceSimpleList64<LightAttributes>();
|
|
List<LightAttributes> lights = dr.LightAttributes.data_items?.ToList() ?? new List<LightAttributes>();
|
|
lights.Add(selectedLight);
|
|
dr.LightAttributes.data_items = lights.ToArray();
|
|
UpdateLightParams();
|
|
LoadModels(DrawableDict);
|
|
}
|
|
}
|
|
}
|
|
SelectLightTreeNode(selectedLight);
|
|
}
|
|
private void DeleteLight()
|
|
{
|
|
if (selectedLight == null) return;
|
|
if(Drawable != null)
|
|
{
|
|
List<LightAttributes> lights = Drawable.LightAttributes.data_items.ToList();
|
|
lights.Remove(selectedLight);
|
|
Drawable.LightAttributes.data_items = lights.ToArray();
|
|
UpdateLightParams();
|
|
LoadModel(Drawable);
|
|
}
|
|
else if(FragDrawable != null)
|
|
{
|
|
List<LightAttributes> lights = FragDrawable.OwnerFragment.LightAttributes.data_items.ToList();
|
|
lights.Remove(selectedLight);
|
|
FragDrawable.OwnerFragment.LightAttributes.data_items = lights.ToArray();
|
|
UpdateLightParams();
|
|
LoadModel(Drawable);
|
|
}
|
|
else
|
|
{
|
|
var dr = LightsTreeView.SelectedNode.Parent.Tag as Drawable;
|
|
if (dr != null)
|
|
{
|
|
List<LightAttributes> lights = dr.LightAttributes.data_items.ToList();
|
|
lights.Remove(selectedLight);
|
|
dr.LightAttributes.data_items = lights.ToArray();
|
|
UpdateLightParams();
|
|
LoadModels(DrawableDict);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateFlagsCheckBoxes()
|
|
{
|
|
var l = selectedLight;
|
|
var tfam = (l.TimeFlags >> 0) & 0xFFF;
|
|
var tfpm = (l.TimeFlags >> 12) & 0xFFF;
|
|
for (int i = 0; i < TimeFlagsAMCheckedListBox.Items.Count; i++)
|
|
{
|
|
TimeFlagsAMCheckedListBox.SetItemCheckState(i, ((tfam & (1u << i)) > 0) ? CheckState.Checked : CheckState.Unchecked);
|
|
}
|
|
for (int i = 0; i < TimeFlagsPMCheckedListBox.Items.Count; i++)
|
|
{
|
|
TimeFlagsPMCheckedListBox.SetItemCheckState(i, ((tfpm & (1u << i)) > 0) ? CheckState.Checked : CheckState.Unchecked);
|
|
}
|
|
}
|
|
|
|
private uint GetFlagsFromItemCheck(CheckedListBox clb, ItemCheckEventArgs e)
|
|
{
|
|
uint flags = 0;
|
|
for (int i = 0; i < clb.Items.Count; i++)
|
|
{
|
|
if ((e != null) && (e.Index == i))
|
|
{
|
|
if (e.NewValue == CheckState.Checked)
|
|
{
|
|
flags += (uint)(1 << i);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (clb.GetItemChecked(i))
|
|
{
|
|
flags += (uint)(1 << i);
|
|
}
|
|
}
|
|
}
|
|
return flags;
|
|
}
|
|
|
|
private void UpdateColour()
|
|
{
|
|
if (populatingui) return;
|
|
|
|
var r = (byte)ColourRUpDown.Value;
|
|
var g = (byte)ColourGUpDown.Value;
|
|
var b = (byte)ColourBUpDown.Value;
|
|
|
|
ColourLabel.BackColor = System.Drawing.Color.FromArgb(r, g, b);
|
|
|
|
if (selectedLight != null)
|
|
{
|
|
selectedLight.ColorR = r;
|
|
selectedLight.ColorG = g;
|
|
selectedLight.ColorB = b;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void UpdateVolumeColour()
|
|
{
|
|
if (populatingui) return;
|
|
|
|
var r = (byte)VolumeColorRUpDown.Value;
|
|
var g = (byte)VolumeColorGUpDown.Value;
|
|
var b = (byte)VolumeColorBUpDown.Value;
|
|
|
|
VolumeColorLabel.BackColor = System.Drawing.Color.FromArgb(r, g, b);
|
|
|
|
if (selectedLight != null)
|
|
{
|
|
selectedLight.VolumeOuterColorR = r;
|
|
selectedLight.VolumeOuterColorG = g;
|
|
selectedLight.VolumeOuterColorB = b;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void SetWidgetModeUI(WidgetMode mode)
|
|
{
|
|
MoveMenuItem.Checked = (mode == WidgetMode.Position);
|
|
MoveMenuItem.BackColor = (mode == WidgetMode.Position) ? SystemColors.GradientActiveCaption : SystemColors.Control;
|
|
RotateMenuItem.Checked = (mode == WidgetMode.Rotation);
|
|
RotateMenuItem.BackColor = (mode == WidgetMode.Rotation) ? SystemColors.GradientActiveCaption : SystemColors.Control;
|
|
ScaleMenuItem.Checked = (mode == WidgetMode.Scale);
|
|
ScaleMenuItem.BackColor = (mode == WidgetMode.Scale) ? SystemColors.GradientActiveCaption : SystemColors.Control;
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LightsTreeView_AfterSelect(object sender, TreeViewEventArgs e)
|
|
{
|
|
SelectLight(e.Node.Tag as LightAttributes);
|
|
}
|
|
|
|
private void ModelLightForm_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
ModelForm.OnLightFormClosed();
|
|
}
|
|
|
|
private void GoToButton_Click(object sender, EventArgs e)
|
|
{
|
|
ModelForm.SetCameraPosition(selectedLight.Position, selectedLight.Falloff * 2f);
|
|
}
|
|
|
|
private void PositionTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
Vector3 v = FloatUtil.ParseVector3String(PositionTextBox.Text);
|
|
if (selectedLight.Position != v)
|
|
{
|
|
selectedLight.Position = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void TypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
string type = TypeComboBox.Text;
|
|
switch (type)
|
|
{
|
|
case "Point":
|
|
selectedLight.Type = LightType.Point;
|
|
break;
|
|
case "Capsule":
|
|
selectedLight.Type = LightType.Capsule;
|
|
break;
|
|
default:
|
|
selectedLight.Type = LightType.Spot;
|
|
break;
|
|
}
|
|
UpdateLightParams();
|
|
}
|
|
|
|
private void IntensityTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(IntensityTextBox.Text);
|
|
if (selectedLight.Intensity != v)
|
|
{
|
|
selectedLight.Intensity = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void ColourRUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateColour();
|
|
}
|
|
|
|
private void ColourGUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateColour();
|
|
}
|
|
|
|
private void ColourBUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateColour();
|
|
}
|
|
|
|
private void ColourLabel_Click(object sender, EventArgs e)
|
|
{
|
|
var colDiag = new ColorDialog { Color = ColourLabel.BackColor };
|
|
if (colDiag.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
var c = colDiag.Color;
|
|
ColourRUpDown.Value = c.R;
|
|
ColourGUpDown.Value = c.G;
|
|
ColourBUpDown.Value = c.B;
|
|
}
|
|
}
|
|
|
|
private void FalloffTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(FalloffTextBox.Text);
|
|
if (selectedLight.Falloff != v)
|
|
{
|
|
selectedLight.Falloff = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void FalloffExponentTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(FalloffExponentTextBox.Text);
|
|
if (selectedLight.FalloffExponent != v)
|
|
{
|
|
selectedLight.FalloffExponent = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void InnerAngleTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(InnerAngleTextBox.Text);
|
|
if (selectedLight.ConeInnerAngle != v)
|
|
{
|
|
selectedLight.ConeInnerAngle = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void OuterAngleTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(OuterAngleTextBox.Text);
|
|
if (selectedLight.ConeOuterAngle != v)
|
|
{
|
|
selectedLight.ConeOuterAngle = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void CoronaIntensityTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(CoronaIntensityTextBox.Text);
|
|
if (selectedLight.CoronaIntensity != v)
|
|
{
|
|
selectedLight.CoronaIntensity = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void CoronaSizeTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(CoronaSizeTextBox.Text);
|
|
if (selectedLight.CoronaSize != v)
|
|
{
|
|
selectedLight.CoronaSize = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void DirectionTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
Vector3 v = FloatUtil.ParseVector3String(DirectionTextBox.Text);
|
|
if (selectedLight.Direction != v)
|
|
{
|
|
selectedLight.Direction = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void NormalizeDirectionButton_Click(object sender, EventArgs e)
|
|
{
|
|
Vector3 d = Vector3.Normalize(FloatUtil.ParseVector3String(DirectionTextBox.Text));
|
|
DirectionTextBox.Text = FloatUtil.GetVector3String(d);
|
|
}
|
|
|
|
private void TangentTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
Vector3 v = FloatUtil.ParseVector3String(TangentTextBox.Text);
|
|
if (selectedLight.Tangent != v)
|
|
{
|
|
selectedLight.Tangent = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void NormalizeTangentButton_Click(object sender, EventArgs e)
|
|
{
|
|
Vector3 t = Vector3.Normalize(FloatUtil.ParseVector3String(TangentTextBox.Text));
|
|
TangentTextBox.Text = FloatUtil.GetVector3String(t);
|
|
}
|
|
|
|
private void FlagsTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
uint.TryParse(FlagsTextBox.Text, out uint v);
|
|
if (selectedLight.Flags != v)
|
|
{
|
|
selectedLight.Flags = v;
|
|
UpdateLightParams();
|
|
}
|
|
|
|
}
|
|
|
|
private void FlashinessUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (byte)FlashinessUpDown.Value;
|
|
if (selectedLight.Flashiness != v)
|
|
{
|
|
selectedLight.Flashiness = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void BoneIDUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (ushort)BoneIDUpDown.Value;
|
|
if (selectedLight.BoneId != v)
|
|
{
|
|
selectedLight.BoneId = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void GroupIDUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (byte)GroupIDUpDown.Value;
|
|
if (selectedLight.GroupId != v)
|
|
{
|
|
selectedLight.GroupId = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void ExtentTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
Vector3 v = FloatUtil.ParseVector3String(ExtentTextBox.Text);
|
|
if (selectedLight.Extent != v)
|
|
{
|
|
selectedLight.Extent = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void ShadowBlurUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (byte)ShadowBlurUpDown.Value;
|
|
if (selectedLight.ShadowBlur != v)
|
|
{
|
|
selectedLight.ShadowBlur = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void LightFadeDistanceUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (byte)LightFadeDistanceUpDown.Value;
|
|
if (selectedLight.LightFadeDistance != v)
|
|
{
|
|
selectedLight.LightFadeDistance = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void CoronaZBiasTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(CoronaZBiasTextBox.Text);
|
|
if (selectedLight.CoronaZBias != v)
|
|
{
|
|
selectedLight.CoronaZBias = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void VolumeIntensityTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(VolumeIntensityTextBox.Text);
|
|
if (selectedLight.VolumeIntensity != v)
|
|
{
|
|
selectedLight.VolumeIntensity = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void VolumeSizeScaleTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(VolumeSizeScaleTextBox.Text);
|
|
if (selectedLight.VolumeSizeScale != v)
|
|
{
|
|
selectedLight.VolumeSizeScale = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void VolumeOuterExponentTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(VolumeOuterExponentTextBox.Text);
|
|
if (selectedLight.VolumeOuterExponent != v)
|
|
{
|
|
selectedLight.VolumeOuterExponent = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void ShadowFadeDistanceUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (byte)ShadowFadeDistanceUpDown.Value;
|
|
if (selectedLight.ShadowFadeDistance != v)
|
|
{
|
|
selectedLight.ShadowFadeDistance = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void SpecularFadeDistanceUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (byte)SpecularFadeDistanceUpDown.Value;
|
|
if (selectedLight.SpecularFadeDistance != v)
|
|
{
|
|
selectedLight.SpecularFadeDistance = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void VolumetricFadeDistanceUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var v = (byte)VolumetricFadeDistanceUpDown.Value;
|
|
if (selectedLight.VolumetricFadeDistance != v)
|
|
{
|
|
selectedLight.VolumetricFadeDistance = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void ShadowNearClipTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(ShadowNearClipTextBox.Text);
|
|
if (selectedLight.ShadowNearClip != v)
|
|
{
|
|
selectedLight.ShadowNearClip = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void VolumeColorLabel_Click(object sender, EventArgs e)
|
|
{
|
|
var colDiag = new ColorDialog { Color = ColourLabel.BackColor };
|
|
if (colDiag.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
var c = colDiag.Color;
|
|
VolumeColorRUpDown.Value = c.R;
|
|
VolumeColorGUpDown.Value = c.G;
|
|
VolumeColorBUpDown.Value = c.B;
|
|
}
|
|
}
|
|
|
|
private void VolumeColorRUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateVolumeColour();
|
|
}
|
|
|
|
private void VolumeColorGUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateVolumeColour();
|
|
}
|
|
|
|
private void VolumeColorBUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateVolumeColour();
|
|
}
|
|
|
|
private void TimeFlagsTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
uint.TryParse(TimeFlagsTextBox.Text, out uint v);
|
|
if (selectedLight.TimeFlags != v)
|
|
{
|
|
selectedLight.TimeFlags = v;
|
|
}
|
|
populatingui = true;
|
|
UpdateFlagsCheckBoxes();
|
|
populatingui = false;
|
|
}
|
|
|
|
private void TimeFlagsAMCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var tfam = GetFlagsFromItemCheck(TimeFlagsAMCheckedListBox, e);
|
|
var tfpm = GetFlagsFromItemCheck(TimeFlagsPMCheckedListBox, null);
|
|
var v = tfam + (tfpm << 12);
|
|
if (selectedLight.TimeFlags != v)
|
|
{
|
|
selectedLight.TimeFlags = v;
|
|
}
|
|
populatingui = true;
|
|
TimeFlagsTextBox.Text = selectedLight.TimeFlags.ToString();
|
|
populatingui = false;
|
|
}
|
|
|
|
private void TimeFlagsPMCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
var tfam = GetFlagsFromItemCheck(TimeFlagsAMCheckedListBox, null);
|
|
var tfpm = GetFlagsFromItemCheck(TimeFlagsPMCheckedListBox, e);
|
|
var v = tfam + (tfpm << 12);
|
|
if (selectedLight.TimeFlags != v)
|
|
{
|
|
selectedLight.TimeFlags = v;
|
|
}
|
|
populatingui = true;
|
|
TimeFlagsTextBox.Text = selectedLight.TimeFlags.ToString();
|
|
populatingui = false;
|
|
}
|
|
|
|
private void TextureHashTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
if (!uint.TryParse(TextureHashTextBox.Text, out uint v))
|
|
{
|
|
v = JenkHash.GenHash(TextureHashTextBox.Text);
|
|
}
|
|
if (selectedLight.ProjectedTextureHash != v)
|
|
{
|
|
selectedLight.ProjectedTextureHash = v;
|
|
}
|
|
}
|
|
|
|
private void CullingPlaneNormalTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
Vector3 v = FloatUtil.ParseVector3String(CullingPlaneNormalTextBox.Text);
|
|
if (selectedLight.CullingPlaneNormal != v)
|
|
{
|
|
selectedLight.CullingPlaneNormal = v;
|
|
}
|
|
}
|
|
|
|
private void CullingPlaneOffsetTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (populatingui) return;
|
|
if (selectedLight == null) return;
|
|
float v = FloatUtil.Parse(CullingPlaneOffsetTextBox.Text);
|
|
if (selectedLight.CullingPlaneOffset != v)
|
|
{
|
|
selectedLight.CullingPlaneOffset = v;
|
|
UpdateLightParams();
|
|
}
|
|
}
|
|
|
|
private void EditNewLightMenu_Click(object sender, EventArgs e)
|
|
{
|
|
CreateLight();
|
|
}
|
|
|
|
private void EditDeleteLightMenu_Click(object sender, EventArgs e)
|
|
{
|
|
DeleteLight();
|
|
}
|
|
|
|
private void OptionsShowOutlinesMenu_Click(object sender, EventArgs e)
|
|
{
|
|
OptionsShowOutlinesMenu.Checked = !OptionsShowOutlinesMenu.Checked;
|
|
ModelForm.showLightGizmos = OptionsShowOutlinesMenu.Checked;
|
|
}
|
|
|
|
private void MoveMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var mode = MoveMenuItem.Checked ? WidgetMode.Default : WidgetMode.Position;
|
|
SetWidgetModeUI(mode);
|
|
ModelForm.SetWidgetMode(mode);
|
|
}
|
|
|
|
private void RotateMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var mode = RotateMenuItem.Checked ? WidgetMode.Default : WidgetMode.Rotation;
|
|
SetWidgetModeUI(mode);
|
|
ModelForm.SetWidgetMode(mode);
|
|
}
|
|
|
|
private void ScaleMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var mode = ScaleMenuItem.Checked ? WidgetMode.Default : WidgetMode.Scale;
|
|
SetWidgetModeUI(mode);
|
|
ModelForm.SetWidgetMode(mode);
|
|
}
|
|
|
|
private void NewLightButton_Click(object sender, EventArgs e)
|
|
{
|
|
CreateLight();
|
|
}
|
|
|
|
private void DeleteLightButton_Click(object sender, EventArgs e)
|
|
{
|
|
DeleteLight();
|
|
}
|
|
}
|
|
}
|