mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-21 22:42:54 +08:00
Spot lights geometry improvement, LodLights cone angles and game crash fixes
This commit is contained in:
parent
ea876743bc
commit
77e036e750
@ -589,7 +589,7 @@ namespace CodeWalker.GameFiles
|
||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0),
|
||||
new MetaStructureEntryInfo_s(MetaName.timeAndStateFlags, 56, MetaStructureEntryDataType.Array, 0, 6, 0),
|
||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0),
|
||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.HASH, 72, MetaStructureEntryDataType.Array, 0, 8, 0),
|
||||
new MetaStructureEntryInfo_s(MetaName.hash, 72, MetaStructureEntryDataType.Array, 0, 8, 0),
|
||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0),
|
||||
new MetaStructureEntryInfo_s(MetaName.coneInnerAngle, 88, MetaStructureEntryDataType.Array, 0, 10, 0),
|
||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0),
|
||||
|
@ -14110,7 +14110,7 @@ namespace CodeWalker.GameFiles
|
||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UInt, 0, 0, 0),
|
||||
new PsoStructureEntryInfo(MetaName.timeAndStateFlags, PsoDataType.Array, 56, 0, (MetaName)6),
|
||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UInt, 0, 0, 0),
|
||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.HASH, PsoDataType.Array, 72, 0, (MetaName)8),
|
||||
new PsoStructureEntryInfo(MetaName.hash, PsoDataType.Array, 72, 0, (MetaName)8),
|
||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UByte, 0, 0, 0),
|
||||
new PsoStructureEntryInfo(MetaName.coneInnerAngle, PsoDataType.Array, 88, 0, (MetaName)10),
|
||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UByte, 0, 0, 0),
|
||||
|
@ -49,9 +49,9 @@ VS_Output main(float4 ipos : POSITION, uint iid : SV_InstanceID)
|
||||
else if (InstType == 2)//spot (cone)
|
||||
{
|
||||
float arads = InstConeOuterAngle;
|
||||
float3 cpos = ipos.xyz * (tan(arads) * extent);
|
||||
cpos.y += ipos.w * extent;
|
||||
opos = (cpos.x * InstTangentX) + (cpos.y * InstDirection) + (cpos.z * InstTangentY);
|
||||
float3 tpos = (ipos.xyz * sin(arads)) + float3(0, 0, ipos.w * cos(arads));
|
||||
float3 cpos = ((ipos.w > 0) ? normalize(tpos) : tpos) * extent;
|
||||
opos = (cpos.x * InstTangentX) + (cpos.y * InstTangentY) + (cpos.z * InstDirection);
|
||||
}
|
||||
else if (InstType == 4)//capsule
|
||||
{
|
||||
|
@ -47,9 +47,9 @@ VS_Output main(float4 ipos : POSITION, uint iid : SV_InstanceID)
|
||||
else if (LightType == 2)//spot (cone)
|
||||
{
|
||||
float arads = lodlight.OuterAngleOrCapExt;
|
||||
float3 cpos = ipos.xyz * (tan(arads) * extent);
|
||||
cpos.y += ipos.w * extent;
|
||||
opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.Direction.xyz) + (cpos.z * lodlight.TangentY.xyz);
|
||||
float3 tpos = (ipos.xyz * sin(arads)) + float3(0, 0, ipos.w * cos(arads));
|
||||
float3 cpos = ((ipos.w>0) ? normalize(tpos) : tpos) * extent;
|
||||
opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.TangentY.xyz) + (cpos.z * lodlight.Direction.xyz);
|
||||
}
|
||||
else if (LightType == 4)//capsule
|
||||
{
|
||||
|
@ -1513,8 +1513,8 @@ namespace CodeWalker.Rendering
|
||||
light.TangentY = new Vector4(l.TangentY, 0.0f);
|
||||
light.Falloff = l.Falloff;
|
||||
light.FalloffExponent = Math.Max(l.FalloffExponent*0.01f, 0.5f);//is this right?
|
||||
light.InnerAngle = l.ConeInnerAngle * 0.0087266462f; //pi/360
|
||||
light.OuterAngleOrCapExt = l.ConeOuterAngleOrCapExt * 0.0087266462f; //pi/360
|
||||
light.InnerAngle = l.ConeInnerAngle * 0.012319971f; //pi/255
|
||||
light.OuterAngleOrCapExt = l.ConeOuterAngleOrCapExt * 0.012319971f; //pi/255
|
||||
var type = l.Type;
|
||||
switch (type)
|
||||
{
|
||||
|
@ -1036,8 +1036,8 @@ namespace CodeWalker.Rendering
|
||||
var tx = lodlight.TangentX;
|
||||
var ty = lodlight.TangentY;
|
||||
var extent = lodlight.Falloff;
|
||||
var innerAngle = lodlight.ConeInnerAngle * 0.0087266462f; //pi/360
|
||||
var outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.0087266462f; //pi/360
|
||||
var innerAngle = lodlight.ConeInnerAngle * 0.012319971f; //pi/255
|
||||
var outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.012319971f; //pi/255
|
||||
var type = lodlight.Type;
|
||||
switch (type)
|
||||
{
|
||||
@ -1047,10 +1047,8 @@ namespace CodeWalker.Rendering
|
||||
RenderSelectionCircle(pos, Vector3.UnitY, Vector3.UnitZ, extent, colwht);
|
||||
break;
|
||||
case LightType.Spot:
|
||||
float coneouterrad = extent * (float)Math.Tan(outerAngle);
|
||||
float coneinnerrad = extent * (float)Math.Tan(innerAngle);
|
||||
RenderSelectionCone(pos, tx, ty, dir, coneouterrad, extent, colblu);
|
||||
RenderSelectionCone(pos, tx, ty, dir, coneinnerrad, extent, colwht);
|
||||
RenderSelectionCone(pos, tx, ty, dir, (float)Math.Sin(outerAngle)*extent, (float)Math.Cos(outerAngle)*extent, colblu);
|
||||
RenderSelectionCone(pos, tx, ty, dir, (float)Math.Sin(innerAngle)*extent, (float)Math.Cos(innerAngle)*extent, colwht);
|
||||
break;
|
||||
case LightType.Capsule:
|
||||
outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.25f;
|
||||
|
@ -90,7 +90,7 @@ namespace CodeWalker.Rendering
|
||||
VertexShader LightVS;
|
||||
PixelShader LightPS;
|
||||
PixelShader LightMSPS;
|
||||
UnitCone LightCone;
|
||||
LightCone LightCone;
|
||||
UnitSphere LightSphere;
|
||||
UnitCapsule LightCapsule;
|
||||
UnitQuad LightQuad;
|
||||
@ -160,8 +160,8 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
|
||||
|
||||
LightCone = new UnitCone(device, bLodLightVS, 4, false);
|
||||
LightSphere = new UnitSphere(device, bLodLightVS, 4, true);
|
||||
LightCone = new LightCone(device, bLodLightVS, 2);
|
||||
LightSphere = new UnitSphere(device, bLodLightVS, 3, true);
|
||||
LightCapsule = new UnitCapsule(device, bLodLightVS, 4, false);
|
||||
LightQuad = new UnitQuad(device, true);
|
||||
LightQuadLayout = new InputLayout(device, bDirLightVS, new[]
|
||||
|
@ -20,12 +20,12 @@ namespace CodeWalker.Rendering
|
||||
private VertexBufferBinding vbbinding;
|
||||
private int indexcount;
|
||||
|
||||
private struct SphTri
|
||||
private struct Tri
|
||||
{
|
||||
public int v1;
|
||||
public int v2;
|
||||
public int v3;
|
||||
public SphTri(int i1, int i2, int i3)
|
||||
public Tri(int i1, int i2, int i3)
|
||||
{
|
||||
v1 = i1;
|
||||
v2 = i2;
|
||||
@ -46,7 +46,7 @@ namespace CodeWalker.Rendering
|
||||
|
||||
List<Vector4> verts = new List<Vector4>();
|
||||
Dictionary<Vector4, int> vdict = new Dictionary<Vector4, int>();
|
||||
List<SphTri> curtris = new List<SphTri>();
|
||||
List<Tri> curtris = new List<Tri>();
|
||||
|
||||
verts.Add(new Vector4(0.0f, 0.0f, 0.0f, 0.0f));//top end (translated by VS!)
|
||||
verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));//top normal
|
||||
@ -82,8 +82,8 @@ namespace CodeWalker.Rendering
|
||||
i1 = 2;
|
||||
}
|
||||
|
||||
curtris.Add(new SphTri(0, i0, i1)); //fill the cone
|
||||
curtris.Add(new SphTri(1, i1+1, i0+1)); //bottom cap triangles
|
||||
curtris.Add(new Tri(0, i0, i1)); //fill the cone
|
||||
curtris.Add(new Tri(1, i1+1, i0+1)); //bottom cap triangles
|
||||
}
|
||||
|
||||
|
||||
@ -149,4 +149,160 @@ namespace CodeWalker.Rendering
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class LightCone
|
||||
{
|
||||
private Buffer VertexBuffer { get; set; }
|
||||
private Buffer IndexBuffer { get; set; }
|
||||
private InputLayout InputLayout { get; set; }
|
||||
private VertexBufferBinding vbbinding;
|
||||
private int indexcount;
|
||||
|
||||
private struct Tri
|
||||
{
|
||||
public Vector4 v1;
|
||||
public Vector4 v2;
|
||||
public Vector4 v3;
|
||||
public Tri(Vector4 i1, Vector4 i2, Vector4 i3)
|
||||
{
|
||||
v1 = i1;
|
||||
v2 = i2;
|
||||
v3 = i3;
|
||||
}
|
||||
}
|
||||
|
||||
public LightCone(Device device, byte[] vsbytes, int detail)
|
||||
{
|
||||
|
||||
InputLayout = new InputLayout(device, vsbytes, new[]
|
||||
{
|
||||
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||
});
|
||||
|
||||
|
||||
var tris = new List<Tri>();
|
||||
var newtris = new List<Tri>();
|
||||
var curtris = new List<Tri>();
|
||||
|
||||
curtris.Clear();//"cone" triangles
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(-1, 0, 0, 1), new Vector4(0, -1, 0, 1)));
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(0, 1, 0, 1), new Vector4(-1, 0, 0, 1)));
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(1, 0, 0, 1), new Vector4(0, 1, 0, 1)));
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(0, -1, 0, 1), new Vector4(1, 0, 0, 1)));
|
||||
for (int i = 0; i < detail; i++)
|
||||
{
|
||||
foreach (var tri in curtris)
|
||||
{
|
||||
var v1 = tri.v1;
|
||||
var v2 = tri.v2;
|
||||
var v3 = tri.v3;
|
||||
var v4 = new Vector4(Vector3.Normalize((v2 + v3).XYZ() * 0.5f), 1);
|
||||
newtris.Add(new Tri(v1, v2, v4));
|
||||
newtris.Add(new Tri(v1, v4, v3));
|
||||
}
|
||||
curtris = newtris;
|
||||
newtris = new List<Tri>();
|
||||
}
|
||||
tris.AddRange(curtris);
|
||||
|
||||
curtris.Clear();//hemisphere triangles
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(0, -1, 0, 1), new Vector4(-1, 0, 0, 1)));
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(-1, 0, 0, 1), new Vector4(0, 1, 0, 1)));
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(0, 1, 0, 1), new Vector4(1, 0, 0, 1)));
|
||||
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(1, 0, 0, 1), new Vector4(0, -1, 0, 1)));
|
||||
for (int i = 0; i < detail; i++)
|
||||
{
|
||||
foreach (var tri in curtris)
|
||||
{
|
||||
var v1 = tri.v1;
|
||||
var v2 = tri.v2;
|
||||
var v3 = tri.v3;
|
||||
var v4 = new Vector4(Vector3.Normalize((v1 + v2).XYZ() * 0.5f), 1);
|
||||
var v5 = new Vector4(Vector3.Normalize((v2 + v3).XYZ() * 0.5f), 1);
|
||||
var v6 = new Vector4(Vector3.Normalize((v3 + v1).XYZ() * 0.5f), 1);
|
||||
newtris.Add(new Tri(v1, v4, v6));
|
||||
newtris.Add(new Tri(v4, v2, v5));
|
||||
newtris.Add(new Tri(v4, v5, v6));
|
||||
newtris.Add(new Tri(v6, v5, v3));
|
||||
}
|
||||
curtris = newtris;
|
||||
newtris = new List<Tri>();
|
||||
}
|
||||
tris.AddRange(curtris);
|
||||
|
||||
|
||||
|
||||
|
||||
var verts = new List<Vector4>();
|
||||
var vdict = new Dictionary<Vector4, int>();
|
||||
var idata = new List<uint>();
|
||||
uint addVert(Vector4 v)
|
||||
{
|
||||
if (vdict.TryGetValue(v, out int i)) return (uint)i;
|
||||
var n = verts.Count;
|
||||
verts.Add(v);
|
||||
vdict[v] = n;
|
||||
return (uint)n;
|
||||
}
|
||||
foreach (var tri in tris)
|
||||
{
|
||||
idata.Add(addVert(tri.v1));
|
||||
idata.Add(addVert(tri.v2));
|
||||
idata.Add(addVert(tri.v3));
|
||||
}
|
||||
|
||||
|
||||
|
||||
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, verts.ToArray());
|
||||
vbbinding = new VertexBufferBinding(VertexBuffer, 16, 0);
|
||||
|
||||
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, idata.ToArray());
|
||||
indexcount = idata.Count;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Draw(DeviceContext context)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexed(indexcount, 0, 0);
|
||||
}
|
||||
|
||||
public void DrawInstanced(DeviceContext context, int count)
|
||||
{
|
||||
context.InputAssembler.InputLayout = InputLayout;
|
||||
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||
|
||||
context.DrawIndexedInstanced(indexcount, count, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (VertexBuffer != null)
|
||||
{
|
||||
VertexBuffer.Dispose();
|
||||
VertexBuffer = null;
|
||||
}
|
||||
if (IndexBuffer != null)
|
||||
{
|
||||
IndexBuffer.Dispose();
|
||||
IndexBuffer = null;
|
||||
}
|
||||
if (InputLayout != null)
|
||||
{
|
||||
InputLayout.Dispose();
|
||||
InputLayout = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user