mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-25 16:32:55 +08:00
Moved entity light hash generation to YmapEntityDef and added Lights array to entity
This commit is contained in:
parent
384ad0c9cb
commit
e18cf990fe
@ -1681,6 +1681,9 @@ namespace CodeWalker.GameFiles
|
||||
public object LodManagerRenderable = null;
|
||||
|
||||
|
||||
public LightInstance[] Lights { get; set; }
|
||||
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
@ -2069,6 +2072,129 @@ namespace CodeWalker.GameFiles
|
||||
return _CEntityDef.ToString() + ((ChildList != null) ? (" (" + ChildList.Count.ToString() + " children) ") : " ") + _CEntityDef.lodLevel.ToString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void EnsureLights(DrawableBase db)
|
||||
{
|
||||
if (Lights != null) return;
|
||||
if (Archetype == null) return;
|
||||
if (db == null) return;
|
||||
|
||||
var dd = db as Drawable;
|
||||
var fd = db as FragDrawable;
|
||||
LightAttributes_s[] lightAttrs = null;
|
||||
Bounds b = null;
|
||||
if (dd != null)
|
||||
{
|
||||
lightAttrs = dd.LightAttributes?.data_items;
|
||||
b = dd.Bound;
|
||||
}
|
||||
else if (fd != null)
|
||||
{
|
||||
lightAttrs = fd.OwnerFragment?.LightAttributes?.data_items;
|
||||
b = fd.OwnerFragment?.PhysicsLODGroup?.PhysicsLOD1?.Bound;
|
||||
}
|
||||
if (lightAttrs == null) return;
|
||||
|
||||
var abmin = Vector3.Min(Archetype.BBMin, db.BoundingBoxMin);
|
||||
var abmax = Vector3.Max(Archetype.BBMax, db.BoundingBoxMax);
|
||||
if (b != null)
|
||||
{
|
||||
abmin = Vector3.Min(abmin, b.BoxMin);
|
||||
abmax = Vector3.Max(abmax, b.BoxMax);
|
||||
}
|
||||
var bb = new BoundingBox(abmin, abmax).Transform(Position, Orientation, Scale);
|
||||
var ints = new uint[7];
|
||||
ints[0] = (uint)(bb.Minimum.X * 10.0f);
|
||||
ints[1] = (uint)(bb.Minimum.Y * 10.0f);
|
||||
ints[2] = (uint)(bb.Minimum.Z * 10.0f);
|
||||
ints[3] = (uint)(bb.Maximum.X * 10.0f);
|
||||
ints[4] = (uint)(bb.Maximum.Y * 10.0f);
|
||||
ints[5] = (uint)(bb.Maximum.Z * 10.0f);
|
||||
|
||||
var lightInsts = new LightInstance[lightAttrs.Length];
|
||||
for (int i = 0; i < lightAttrs.Length; i++)
|
||||
{
|
||||
ints[6] = (uint)(i + 1);
|
||||
var li = new LightInstance();
|
||||
li.Attributes = lightAttrs[i];
|
||||
li.Hash = ComputeLightHash(ints);
|
||||
lightInsts[i] = li;
|
||||
}
|
||||
Lights = lightInsts;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static uint ComputeLightHash(uint[] ints, uint seed = 0)
|
||||
{
|
||||
var a2 = ints.Length;
|
||||
var v3 = a2;
|
||||
var v5 = (uint)(seed + 0xDEADBEEF + 4 * ints.Length);
|
||||
var v6 = v5;
|
||||
var v7 = v5;
|
||||
|
||||
var c = 0;
|
||||
for (var i = 0; i < (ints.Length - 4) / 3 + 1; i++, v3 -= 3, c += 3)
|
||||
{
|
||||
var v9 = ints[c + 2] + v5;
|
||||
var v10 = ints[c + 1] + v6;
|
||||
var v11 = ints[c] - v9;
|
||||
var v13 = v10 + v9;
|
||||
var v14 = (v7 + v11) ^ BitUtil.RotateLeft(v9, 4);
|
||||
var v15 = v10 - v14;
|
||||
var v17 = v13 + v14;
|
||||
var v18 = v15 ^ BitUtil.RotateLeft(v14, 6);
|
||||
var v19 = v13 - v18;
|
||||
var v21 = v17 + v18;
|
||||
var v22 = v19 ^ BitUtil.RotateLeft(v18, 8);
|
||||
var v23 = v17 - v22;
|
||||
var v25 = v21 + v22;
|
||||
var v26 = v23 ^ BitUtil.RotateLeft(v22, 16);
|
||||
var v27 = v21 - v26;
|
||||
var v29 = v27 ^ BitUtil.RotateRight(v26, 13);
|
||||
var v30 = v25 - v29;
|
||||
v7 = v25 + v26;
|
||||
v6 = v7 + v29;
|
||||
v5 = v30 ^ BitUtil.RotateLeft(v29, 4);
|
||||
}
|
||||
|
||||
if (v3 == 3)
|
||||
{
|
||||
v5 += ints[c + 2];
|
||||
}
|
||||
|
||||
if (v3 >= 2)
|
||||
{
|
||||
v6 += ints[c + 1];
|
||||
}
|
||||
|
||||
if (v3 >= 1)
|
||||
{
|
||||
var v34 = (v6 ^ v5) - BitUtil.RotateLeft(v6, 14);
|
||||
var v35 = (v34 ^ (v7 + ints[c])) - BitUtil.RotateLeft(v34, 11);
|
||||
var v36 = (v35 ^ v6) - BitUtil.RotateRight(v35, 7);
|
||||
var v37 = (v36 ^ v34) - BitUtil.RotateLeft(v36, 16);
|
||||
var v38 = BitUtil.RotateLeft(v37, 4);
|
||||
var v39 = (((v35 ^ v37) - v38) ^ v36) - BitUtil.RotateLeft((v35 ^ v37) - v38, 14);
|
||||
return (v39 ^ v37) - BitUtil.RotateRight(v39, 8);
|
||||
}
|
||||
|
||||
return v5;
|
||||
}
|
||||
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public class LightInstance
|
||||
{
|
||||
public LightAttributes_s Attributes { get; set; } //just for display purposes!
|
||||
public uint Hash { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Hash.ToString() + ": " + Attributes.Type.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -267,6 +267,14 @@ namespace CodeWalker
|
||||
if (flag) return SetBit(value, bit);
|
||||
else return ClearBit(value, bit);
|
||||
}
|
||||
public static uint RotateLeft(uint value, int count)
|
||||
{
|
||||
return (value << count) | (value >> (32 - count));
|
||||
}
|
||||
public static uint RotateRight(uint value, int count)
|
||||
{
|
||||
return (value >> count) | (value << (32 - count));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,11 +94,6 @@ namespace CodeWalker.Project.Panels
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
@ -118,28 +113,17 @@ namespace CodeWalker.Project.Panels
|
||||
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);
|
||||
var fphys = (dwbl as FragDrawable)?.OwnerFragmentPhys;
|
||||
|
||||
ent.EnsureLights(dwbl);
|
||||
var elights = ent.Lights;
|
||||
if (elights != null)
|
||||
{
|
||||
|
||||
for (int li = 0; li<lightAttrs.Length;li++)
|
||||
for (int li = 0; li<elights.Length;li++)
|
||||
{
|
||||
var la = lightAttrs[li];
|
||||
var elight = elights[li];
|
||||
var la = elight.Attributes;
|
||||
//transform this light with the entity position and orientation
|
||||
//generate lights data from it!
|
||||
|
||||
@ -164,9 +148,9 @@ namespace CodeWalker.Project.Panels
|
||||
if (bone != null)
|
||||
{
|
||||
var modeltransforms = skeleton.Transformations;
|
||||
var fragtransforms = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod?.FragTransforms?.Matrices;
|
||||
var fragtransformid = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysIndex ?? 0;
|
||||
var fragoffset = new Vector4(fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod.Unknown_30h ?? Vector3.Zero, 0.0f);
|
||||
var fragtransforms = fphys?.OwnerFragPhysLod?.FragTransforms?.Matrices;
|
||||
var fragtransformid = fphys?.OwnerFragPhysIndex ?? 0;
|
||||
var fragoffset = new Vector4(fphys?.OwnerFragPhysLod.Unknown_30h ?? Vector3.Zero, 0.0f);
|
||||
|
||||
if ((fragtransforms != null) && (fragtransformid < fragtransforms.Length))
|
||||
{
|
||||
@ -206,9 +190,7 @@ namespace CodeWalker.Project.Panels
|
||||
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, dwbl, li);
|
||||
uint h = elight.Hash;
|
||||
|
||||
if (ent._CEntityDef.guid == 91259075)
|
||||
{ } //h = 2324437992? should be:19112537
|
||||
@ -375,204 +357,6 @@ namespace CodeWalker.Project.Panels
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint ComputeHash(IReadOnlyList<uint> ints, uint seed = 0)
|
||||
{
|
||||
var a2 = ints.Count;
|
||||
var v3 = a2;
|
||||
var v5 = (uint)(seed + 0xDEADBEEF + 4 * ints.Count);
|
||||
var v6 = v5;
|
||||
var v7 = v5;
|
||||
|
||||
var c = 0;
|
||||
for (var i = 0; i < (ints.Count - 4) / 3 + 1; i++, v3 -= 3, c += 3)
|
||||
{
|
||||
var v9 = ints[c + 2] + v5;
|
||||
var v10 = ints[c + 1] + v6;
|
||||
var v11 = ints[c] - v9;
|
||||
var v13 = v10 + v9;
|
||||
var v14 = (v7 + v11) ^ RotateLeft(v9, 4);
|
||||
var v15 = v10 - v14;
|
||||
var v17 = v13 + v14;
|
||||
var v18 = v15 ^ RotateLeft(v14, 6);
|
||||
var v19 = v13 - v18;
|
||||
var v21 = v17 + v18;
|
||||
var v22 = v19 ^ RotateLeft(v18, 8);
|
||||
var v23 = v17 - v22;
|
||||
var v25 = v21 + v22;
|
||||
var v26 = v23 ^ RotateLeft(v22, 16);
|
||||
var v27 = v21 - v26;
|
||||
var v29 = v27 ^ RotateRight(v26, 13);
|
||||
var v30 = v25 - v29;
|
||||
v7 = v25 + v26;
|
||||
v6 = v7 + v29;
|
||||
v5 = v30 ^ RotateLeft(v29, 4);
|
||||
}
|
||||
|
||||
if (v3 == 3)
|
||||
{
|
||||
v5 += ints[c + 2];
|
||||
}
|
||||
|
||||
if (v3 >= 2)
|
||||
{
|
||||
v6 += ints[c + 1];
|
||||
}
|
||||
|
||||
if (v3 >= 1)
|
||||
{
|
||||
var v34 = (v6 ^ v5) - RotateLeft(v6, 14);
|
||||
var v35 = (v34 ^ (v7 + ints[c])) - RotateLeft(v34, 11);
|
||||
var v36 = (v35 ^ v6) - RotateRight(v35, 7);
|
||||
var v37 = (v36 ^ v34) - RotateLeft(v36, 16);
|
||||
var v38 = RotateLeft(v37, 4);
|
||||
var v39 = (((v35 ^ v37) - v38) ^ v36) - RotateLeft((v35 ^ v37) - v38, 14);
|
||||
return (v39 ^ v37) - RotateRight(v39, 8);
|
||||
}
|
||||
|
||||
return v5;
|
||||
}
|
||||
|
||||
private uint GetLightHash(YmapEntityDef ent, DrawableBase dwbl, int lightIndex)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var len = 7;
|
||||
|
||||
var ori = ent.Orientation;
|
||||
var pos = ent.Position;
|
||||
var abmin = Vector3.Min(ent.Archetype.BBMin, dwbl.BoundingBoxMin);
|
||||
var abmax = Vector3.Max(ent.Archetype.BBMax, dwbl.BoundingBoxMax);
|
||||
|
||||
Bounds b = null;
|
||||
if (dwbl is Drawable ddwbl)
|
||||
{
|
||||
b = ddwbl.Bound;
|
||||
}
|
||||
if (dwbl is FragDrawable fdwbl)
|
||||
{
|
||||
b = fdwbl.OwnerFragment?.PhysicsLODGroup?.PhysicsLOD1?.Bound;
|
||||
}
|
||||
if (b != null)
|
||||
{
|
||||
abmin = Vector3.Min(abmin, b.BoxMin);
|
||||
abmax = Vector3.Max(abmax, b.BoxMax);
|
||||
}
|
||||
|
||||
Vector3[] c = new Vector3[8];
|
||||
c[0] = abmin;
|
||||
c[1] = new Vector3(abmin.X, abmin.Y, abmax.Z);
|
||||
c[2] = new Vector3(abmin.X, abmax.Y, abmin.Z);
|
||||
c[3] = new Vector3(abmin.X, abmax.Y, abmax.Z);
|
||||
c[4] = new Vector3(abmax.X, abmin.Y, abmin.Z);
|
||||
c[5] = new Vector3(abmax.X, abmin.Y, abmax.Z);
|
||||
c[6] = new Vector3(abmax.X, abmax.Y, abmin.Z);
|
||||
c[7] = abmax;
|
||||
var bbmin = new Vector3(float.MaxValue);
|
||||
var bbmax = new Vector3(float.MinValue);
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
Vector3 corn = ori.Multiply(c[j]) + pos;
|
||||
bbmin = Vector3.Min(bbmin, corn);
|
||||
bbmax = Vector3.Max(bbmax, corn);
|
||||
}
|
||||
|
||||
|
||||
var ints = new uint[len];
|
||||
ints[0] = (uint)(bbmin.X * 10.0f);
|
||||
ints[1] = (uint)(bbmin.Y * 10.0f);
|
||||
ints[2] = (uint)(bbmin.Z * 10.0f);
|
||||
ints[3] = (uint)(bbmax.X * 10.0f);
|
||||
ints[4] = (uint)(bbmax.Y * 10.0f);
|
||||
ints[5] = (uint)(bbmax.Z * 10.0f);
|
||||
ints[6] = (uint)lightIndex + 1;
|
||||
|
||||
return ComputeHash(ints);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private AABB_s GetAABB(YmapEntityDef ent)
|
||||
{
|
||||
var arch = ent.Archetype;
|
||||
var ori = ent.Orientation;
|
||||
Vector3 bbmin = ent.Position - ent.BSRadius; //sphere
|
||||
Vector3 bbmax = ent.Position + ent.BSRadius;
|
||||
if (arch != null)
|
||||
{
|
||||
Vector3[] c = new Vector3[8];
|
||||
Vector3 abmin = arch.BBMin * ent.Scale; //entity box
|
||||
Vector3 abmax = arch.BBMax * ent.Scale;
|
||||
c[0] = abmin;
|
||||
c[1] = new Vector3(abmin.X, abmin.Y, abmax.Z);
|
||||
c[2] = new Vector3(abmin.X, abmax.Y, abmin.Z);
|
||||
c[3] = new Vector3(abmin.X, abmax.Y, abmax.Z);
|
||||
c[4] = new Vector3(abmax.X, abmin.Y, abmin.Z);
|
||||
c[5] = new Vector3(abmax.X, abmin.Y, abmax.Z);
|
||||
c[6] = new Vector3(abmax.X, abmax.Y, abmin.Z);
|
||||
c[7] = abmax;
|
||||
bbmin = new Vector3(float.MaxValue);
|
||||
bbmax = new Vector3(float.MinValue);
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
Vector3 corn = ori.Multiply(c[j]) + ent.Position;
|
||||
bbmin = Vector3.Min(bbmin, corn);
|
||||
bbmax = Vector3.Max(bbmax, corn);
|
||||
}
|
||||
}
|
||||
AABB_s b = new AABB_s();
|
||||
b.Min = new Vector4(bbmin, 0f);
|
||||
b.Max = new Vector4(bbmax, 0f);
|
||||
return b;
|
||||
}
|
||||
private AABB_s GetAABB2(YmapEntityDef ent)
|
||||
{
|
||||
var arch = ent.Archetype;
|
||||
var ori = ent.Orientation;
|
||||
var pos = ent.Position;
|
||||
var sca = ent.Scale;
|
||||
var mat = Matrix.Transformation(Vector3.Zero, Quaternion.Identity, sca, Vector3.Zero, ori, pos);
|
||||
var matabs = mat;
|
||||
matabs.Column1 = mat.Column1.Abs();
|
||||
matabs.Column2 = mat.Column2.Abs();
|
||||
matabs.Column3 = mat.Column3.Abs();
|
||||
matabs.Column4 = mat.Column4.Abs();
|
||||
Vector3 bbmin = pos - ent.BSRadius; //sphere
|
||||
Vector3 bbmax = pos + ent.BSRadius;
|
||||
if (arch != null)
|
||||
{
|
||||
var bbcenter = (arch.BBMax + arch.BBMin) * 0.5f;
|
||||
var bbextent = (arch.BBMax - arch.BBMin) * 0.5f;
|
||||
var ncenter = Vector3.TransformCoordinate(bbcenter, mat);
|
||||
var nextent = Vector3.TransformNormal(bbextent, matabs);
|
||||
bbmin = ncenter - nextent;
|
||||
bbmax = ncenter + nextent;
|
||||
}
|
||||
AABB_s b = new AABB_s();
|
||||
b.Min = new Vector4(bbmin, 0f);
|
||||
b.Max = new Vector4(bbmax, 0f);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static uint RotateLeft(uint value, int count)
|
||||
{
|
||||
return (value << count) | (value >> (32 - count));
|
||||
}
|
||||
private static uint RotateRight(uint value, int count)
|
||||
{
|
||||
return (value >> count) | (value << (32 - count));
|
||||
}
|
||||
private static int RotateLeft(int value, int count)
|
||||
{
|
||||
return (int)RotateLeft((uint)value, count);
|
||||
}
|
||||
private static int RotateRight(int value, int count)
|
||||
{
|
||||
return (int)RotateRight((uint)value, count);
|
||||
}
|
||||
|
||||
public class Light
|
||||
{
|
||||
public MetaVECTOR3 position { get; set; }
|
||||
|
@ -3263,15 +3263,20 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
|
||||
|
||||
if (renderlights && shaders.deferred && (rndbl.Lights != null) && interiorent)//only interior ents making lights! todo: fix LOD lights
|
||||
if (renderlights && shaders.deferred && (rndbl.Lights != null))
|
||||
{
|
||||
var linst = new RenderableLightInst();
|
||||
for (int i = 0; i < rndbl.Lights.Length; i++)
|
||||
entity?.EnsureLights(rndbl.Key);
|
||||
|
||||
if (interiorent)//only interior ents making lights! todo: fix LOD lights
|
||||
{
|
||||
linst.EntityPosition = position;
|
||||
linst.EntityRotation = orientation;
|
||||
linst.Light = rndbl.Lights[i];
|
||||
shaders.Enqueue(ref linst);
|
||||
var linst = new RenderableLightInst();
|
||||
for (int i = 0; i < rndbl.Lights.Length; i++)
|
||||
{
|
||||
linst.EntityPosition = position;
|
||||
linst.EntityRotation = orientation;
|
||||
linst.Light = rndbl.Lights[i];
|
||||
shaders.Enqueue(ref linst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user