GZDoomBuilder 1.03:

Increased dynamic lights rendering performance (currently I'm getting around 25 FPS in Spawn's MAP01 with 32 dynamic lights and rendering distance set to 3000, was getting 4-6 FPS in GZDoomBuilder 1.02).
Several fixes in animated lights rendering (secondary light radius can now be smaller than primary light radius, Pulse Light's maximum radius was rendered twise bigger than in GZDoom).
This commit is contained in:
MaxED 2012-04-23 21:35:48 +00:00
parent 2358b785a1
commit dcf899a3c4
11 changed files with 243 additions and 113 deletions

View file

@ -507,9 +507,11 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Trackbar, Version=1.0.2486.37933, Culture=neutral, PublicKeyToken=503bf28f63ad27b4">
<Private>False</Private>
</Reference>
@ -703,15 +705,14 @@
<Compile Include="General\ErrorItem.cs" />
<Compile Include="General\ErrorLogger.cs" />
<Compile Include="General\SavePurpose.cs" />
<Compile Include="GZBuilder\Data\BoundingBox.cs" />
<Compile Include="GZBuilder\Data\GZDoomLight.cs" />
<Compile Include="GZBuilder\Data\ModelDefEntry.cs" />
<Compile Include="GZBuilder\Data\ThingBoundingBox.cs" />
<Compile Include="GZBuilder\GZGeneral.cs" />
<Compile Include="GZBuilder\IO\ModelDefParser.cs" />
<Compile Include="GZBuilder\md3\GZModel.cs" />
<Compile Include="GZBuilder\md3\MD3FormatException.cs" />
<Compile Include="GZBuilder\md3\ModelReader.cs" />
<Compile Include="GZBuilder\md3\Vertex.cs" />
<Compile Include="GZBuilder\Windows\DebugForm.cs">
<SubType>Form</SubType>
</Compile>

View file

@ -137,7 +137,7 @@ namespace CodeImp.DoomBuilder.Config
public bool VisualBilinear { get { return visualbilinear; } internal set { visualbilinear = value; } }
public int MouseSpeed { get { return mousespeed; } internal set { mousespeed = value; } }
public int MoveSpeed { get { return movespeed; } internal set { movespeed = value; } }
public float ViewDistance { get { return viewdistance; } internal set { viewdistance = value; } }
public float ViewDistance { get { return viewdistance; } internal set { viewdistance = value; } }
public bool InvertYAxis { get { return invertyaxis; } internal set { invertyaxis = value; } }
public string ScriptFontName { get { return scriptfontname; } internal set { scriptfontname = value; } }
public int ScriptFontSize { get { return scriptfontsize; } internal set { scriptfontsize = value; } }

View file

@ -0,0 +1,97 @@
using CodeImp.DoomBuilder.Rendering;
using SlimDX;
namespace CodeImp.DoomBuilder.GZBuilder.Data
{
public struct BoundingBoxSizes
{
public short MinX;
public short MaxX;
public short MinY;
public short MaxY;
public short MinZ;
public short MaxZ;
//we need some reference here
public BoundingBoxSizes(WorldVertex v) {
MinX = MaxX = (short)v.x;
MinY = MaxY = (short)v.y;
MinZ = MaxZ = (short)v.z;
}
}
public class BoundingBoxTools
{
//this creates array of vectors resembling bounding box
public static Vector3[] CalculateBoundingBox(BoundingBoxSizes bbs) {
//center
Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2);
//corners
Vector3 v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ);
Vector3 v2 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MinZ);
Vector3 v3 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MinZ);
Vector3 v4 = new Vector3(bbs.MaxX, bbs.MaxY, bbs.MinZ);
Vector3 v5 = new Vector3(bbs.MinX, bbs.MinY, bbs.MaxZ);
Vector3 v6 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MaxZ);
Vector3 v7 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MaxZ);
Vector3 v8 = new Vector3(bbs.MaxX, bbs.MaxY, bbs.MaxZ);
return new Vector3[] { v0, v1, v2, v3, v4, v5, v6, v7, v8 };
}
public static Vector3[] CalculateBoundingPlane(BoundingBoxSizes bbs) {
//mxd. looks like I need only these 2 points, so...
//center
Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2);
Vector3 v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ);
return new Vector3[] { v0, v1 };
}
/*public static Vector3[] CalculateBoundingPlane(BoundingBoxSizes bbs) {
if(bbs.MinX != bbs.MaxX && bbs.MinY != bbs.MaxY && bbs.MinZ != bbs.MaxZ)
return CalculateBoundingBox(bbs);
//center
Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2);
Vector3 v1, v2, v3, v4;
//corners
if (bbs.MinX == bbs.MaxX) {
v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ);
v2 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MinZ);
v3 = new Vector3(bbs.MinX, bbs.MinY, bbs.MaxZ);
v4 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MaxZ);
} else if (bbs.MinY == bbs.MaxY) {
v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ);
v2 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MinZ);
v3 = new Vector3(bbs.MinX, bbs.MinY, bbs.MaxZ);
v4 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MaxZ);
} else {
v1 = new Vector3(bbs.MinX, bbs.MinY, bbs.MinZ);
v2 = new Vector3(bbs.MaxX, bbs.MinY, bbs.MinZ);
v3 = new Vector3(bbs.MinX, bbs.MaxY, bbs.MinZ);
v4 = new Vector3(bbs.MaxX, bbs.MaxY, bbs.MinZ);
}
return new Vector3[] { v0, v1, v2, v3, v4 };
}*/
public static void UpdateBoundingBoxSizes(ref BoundingBoxSizes bbs, WorldVertex v) {
if (v.x < bbs.MinX)
bbs.MinX = (short)v.x;
else if (v.x > bbs.MaxX)
bbs.MaxX = (short)v.x;
if (v.z < bbs.MinZ)
bbs.MinZ = (short)v.z;
else if (v.z > bbs.MaxZ)
bbs.MaxZ = (short)v.z;
if (v.y < bbs.MinY)
bbs.MinY = (short)v.y;
else if (v.y > bbs.MaxY)
bbs.MaxY = (short)v.y;
}
}
}

View file

@ -30,7 +30,7 @@ namespace CodeImp.DoomBuilder.GZBuilder
public static int[] GZ_LIGHT_TYPES { get { return gz_lightTypes; } }
//version
public const string Version = "1.02";
public const string Version = "1.03";
//debug form
#if DEBUG

View file

@ -1,14 +0,0 @@
using System;
namespace ColladaDotNet.Pipeline.MD3 {
public class MD3FormatException : ApplicationException {
public MD3FormatException(string message)
: base(message) {
}
public MD3FormatException(string message, Exception ex)
: base(message, ex) {
}
}
}

View file

@ -63,7 +63,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
if (model.NUM_MESHES <= 0)
return null;
model.BoundingBox = CalculateBoundingBox(bbs);
model.BoundingBox = BoundingBoxTools.CalculateBoundingBox(bbs);
return model;
}
@ -173,7 +173,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
v.z = (float)br.ReadInt16() / 64 * mde.Scale.Z + mde.zOffset;
//bounding box
UpdateBoundingBoxSizes(ref bbs, v);
BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, v);
var lat = br.ReadByte() * (2 * Math.PI) / 255.0;
var lng = br.ReadByte() * (2 * Math.PI) / 255.0;
@ -278,7 +278,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
WorldVertex v = vertList[polyIndecesList[i]];
//bounding box
UpdateBoundingBoxSizes(ref bbs, v);
BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, v);
//uv
v.u = uvCoordsList[uvIndecesList[i]].X;
@ -337,7 +337,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
}
//this creates array of vectors resembling bounding box
private static Vector3[] CalculateBoundingBox(BoundingBoxSizes bbs) {
/*private static Vector3[] CalculateBoundingBox(BoundingBoxSizes bbs) {
//center
Vector3 v0 = new Vector3(bbs.MinX + (bbs.MaxX - bbs.MinX) / 2, bbs.MinY + (bbs.MaxY - bbs.MinY) / 2, bbs.MinZ + (bbs.MaxZ - bbs.MinZ) / 2);
@ -369,7 +369,7 @@ namespace ColladaDotNet.Pipeline.MD3 {
bbs.MinY = (short)v.y;
else if (v.y > bbs.MaxY)
bbs.MaxY = (short)v.y;
}
}*/
private static string ReadString(BinaryReader br, int len) {
var NAME = string.Empty;
@ -388,14 +388,4 @@ namespace ColladaDotNet.Pipeline.MD3 {
return NAME;
}
}
}
struct BoundingBoxSizes
{
public short MinX;
public short MaxX;
public short MinY;
public short MaxY;
public short MinZ;
public short MaxZ;
}

View file

@ -151,6 +151,15 @@ namespace CodeImp.DoomBuilder.Geometry
return true;
}
//mxd
public bool IntersectPoint(Vector2D point) {
for (int i = 0; i < lines.Length; i++) {
if (lines[i].GetSideOfLine(point) < 0)
return false;
}
return true;
}
#endregion
}
}

View file

@ -83,7 +83,9 @@ namespace CodeImp.DoomBuilder.Rendering
private Dictionary<Texture, List<VisualGeometry>> litGeometry;
private Dictionary<ModelDefEntry, List<VisualThing>> thingsWithModel;
//dbg
int geoSkipped = 0;
//int geoSkipped = 0;
//int totalGeo = 0;
//int totalThings = 0;
// Crosshair
private FlatVertex[] crosshairverts;
@ -498,6 +500,7 @@ namespace CodeImp.DoomBuilder.Rendering
thingsbydistance = new BinaryHeap<VisualThing>();
//mxd
thingsWithModel = new Dictionary<ModelDefEntry, List<VisualThing>>();
litGeometry = new Dictionary<Texture, List<VisualGeometry>>();
for(int i = 0; i < RENDER_PASSES; i++)
{
@ -512,6 +515,8 @@ namespace CodeImp.DoomBuilder.Rendering
//dbg
//GZBuilder.GZGeneral.ClearTrace();
//geoSkipped = 0;
//totalGeo = 0;
//totalThings = 0;
}
}
@ -531,9 +536,6 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.SetRenderState(RenderState.TextureFactor, -1);
graphics.Shaders.World3D.Begin();
//mxd
litGeometry = new Dictionary<Texture, List<VisualGeometry>>();
// SOLID PASS
world = Matrix.Identity;
ApplyMatrices3D();
@ -579,7 +581,7 @@ namespace CodeImp.DoomBuilder.Rendering
geometry = null;
//dbg
//GZBuilder.GZGeneral.TraceLine("Skipped "+geoSkipped+" geometries");
//GZBuilder.GZGeneral.TraceLine("Affected by lights: "+totalGeo+"; skipped: "+geoSkipped+"; total things:"+totalThings);
//GZBuilder.GZGeneral.TraceInHeader("FPS:" + calculateFrameRate());
}
@ -885,9 +887,6 @@ namespace CodeImp.DoomBuilder.Rendering
int i, count;
Vector4 lpr;
//dbg
//int gcount = 0;
graphics.Device.SetRenderState(RenderState.SourceBlend, Blend.One);
graphics.Device.SetRenderState(RenderState.DestinationBlend, Blend.BlendFactor);
@ -898,9 +897,6 @@ namespace CodeImp.DoomBuilder.Rendering
i = 0;
count = 0;
//dbg
//gcount++;
graphics.Device.SetStreamSource(0, g.Sector.GeometryBuffer, 0, WorldVertex.Stride);
//normal lights
@ -909,13 +905,18 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
for (i = 0; i < count; i++) {
lpr = lights[i].LightPositionAndRadius;
if (lpr.W == 0)
continue;
graphics.Shaders.World3D.LightColor = lights[i].LightColor;
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
graphics.Shaders.World3D.ApplySettings();
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
if (checkBBoxIntersection(g.BoundingBox, lights[i].BoundingBox)) {
//dbg
//totalGeo++;
lpr = lights[i].LightPositionAndRadius;
if (lpr.W == 0)
continue;
graphics.Shaders.World3D.LightColor = lights[i].LightColor;
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
graphics.Shaders.World3D.ApplySettings();
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
}
}
}
@ -925,13 +926,18 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
for (i = lightOffsets[0]; i < count; i++) {
lpr = lights[i].LightPositionAndRadius;
if (lpr.W == 0)
continue;
graphics.Shaders.World3D.LightColor = lights[i].LightColor;
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
graphics.Shaders.World3D.ApplySettings();
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
if (checkBBoxIntersection(g.BoundingBox, lights[i].BoundingBox)) {
//dbg
//totalGeo++;
lpr = lights[i].LightPositionAndRadius;
if (lpr.W == 0)
continue;
graphics.Shaders.World3D.LightColor = lights[i].LightColor;
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
graphics.Shaders.World3D.ApplySettings();
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
}
}
}
@ -941,14 +947,19 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.ReverseSubtract);
for (i = lightOffsets[0] + lightOffsets[1]; i < count; i++) {
lpr = lights[i].LightPositionAndRadius;
if (lpr.W == 0)
continue;
Color4 lc = lights[i].LightColor;
graphics.Shaders.World3D.LightColor = new Color4(1.0f, (lc.Green + lc.Blue) / 2, (lc.Red + lc.Blue) / 2, (lc.Green + lc.Red) / 2);
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
graphics.Shaders.World3D.ApplySettings();
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
if (checkBBoxIntersection(g.BoundingBox, lights[i].BoundingBox)) {
//dbg
//totalGeo++;
lpr = lights[i].LightPositionAndRadius;
if (lpr.W == 0)
continue;
Color4 lc = lights[i].LightColor;
graphics.Shaders.World3D.LightColor = new Color4(1.0f, (lc.Green + lc.Blue) / 2, (lc.Red + lc.Blue) / 2, (lc.Green + lc.Red) / 2);
graphics.Shaders.World3D.LightPositionAndRadius = lights[i].LightPositionAndRadius;
graphics.Shaders.World3D.ApplySettings();
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, g.VertexOffset, g.Triangles);
}
}
}
}
@ -957,8 +968,6 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Shaders.World3D.EndPass();
graphics.Device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
//graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, alphaBlendEnabled); //disable AlphaBlending which is turned on in shader
//dbg
//GZBuilder.GZGeneral.TraceLine("Lit " + gcount + " geometries; Lights: [" + lightOffsets[0] + ";" + lightOffsets[1] + ";" + lightOffsets[2] + "]" + Environment.NewLine + "Models count: " + thingsWithModel.Count);
}
@ -987,8 +996,6 @@ namespace CodeImp.DoomBuilder.Rendering
// Determine the shader pass we want to use for this object
int wantedshaderpass = ((((t == highlighted) && showhighlight) || (t.Selected && showselection)) ? highshaderpass : shaderpass);
//dbg
//GZBuilder.GZGeneral.Trace("Rendering mesh with "+wantedshaderpass+" pass."+Environment.NewLine);
// Switch shader pass?
if (currentshaderpass != wantedshaderpass) {
@ -1075,8 +1082,6 @@ namespace CodeImp.DoomBuilder.Rendering
{
highlighted = obj;
}
// This collects a visual sector's geometry for rendering
public void AddSectorGeometry(VisualGeometry g)
@ -1084,14 +1089,6 @@ namespace CodeImp.DoomBuilder.Rendering
// Must have a texture and vertices
if((g.Texture != null) && (g.Triangles > 0))
{
//mxd
/*double angle = Math.Acos(Vector3D.DotProduct(g.Normal, Vector3D.FromAngleXYZ(General.Map.VisualCamera.AngleXY, General.Map.VisualCamera.AngleZ).GetNormal()));
//GZBuilder.GZGeneral.TraceLine("angle=" + angle);
if (angle < 0.78f) { //if angle between geometry normal and camera normal is greater than 135 deg.
geoSkipped++;
return;
}*/
// Texture group not yet collected?
if(!geometry[g.RenderPassInt].ContainsKey(g.Texture))
{
@ -1110,14 +1107,13 @@ namespace CodeImp.DoomBuilder.Rendering
//mxd. gater lights
if (General.Settings.GZDrawLights && !fullbrightness && t.LightType != -1) {
t.UpdateLightRadius();
//dbg
//GZBuilder.GZGeneral.TraceLine("LightRadius = "+t.LightRadius);
if (t.LightRadius > 0) {
t.CalculateCameraDistance3D(D3DDevice.V3(cameraposition));
//t.CameraDistance3D is actually squared distance, hence (t.LightRadius * t.LightRadius)
if (t.CameraDistance3D < (t.LightRadius * t.LightRadius) || isThingOnScreen(t.BoundingBox)) { //always render light if camera is within it's radius
//dbg
//GZBuilder.GZGeneral.Trace("Light is on screen.");
if (t.LightType == (int)GZDoomLightType.FLICKER || t.LightType == (int)GZDoomLightType.PULSE || t.LightType == (int)GZDoomLightType.RANDOM)
t.UpdateBoundingBox(t.LightRadius, t.LightRadius * 2);
thingsWithLight.Add(t);
}
}
@ -1125,13 +1121,8 @@ namespace CodeImp.DoomBuilder.Rendering
} else if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected) && t.Thing.IsModel) {
ModelDefEntry mde = GZBuilder.GZGeneral.ModelDefEntries[t.Thing.Type];
if (!isThingOnScreen(t.BoundingBox)) {
//dbg
//GZBuilder.GZGeneral.Trace("Model is not on screen");
if (!isThingOnScreen(t.BoundingBox))
return;
}
//dbg
//GZBuilder.GZGeneral.Trace("Model is on screen");
if (!thingsWithModel.ContainsKey(mde))
thingsWithModel.Add(mde, new List<VisualThing>());
@ -1164,17 +1155,53 @@ namespace CodeImp.DoomBuilder.Rendering
Vector3D camNormal = Vector3D.FromAngleXYZ(General.Map.VisualCamera.AngleXY, General.Map.VisualCamera.AngleZ);
Vector3D thingNormal = D3DDevice.V3D(bbox[0]) - cameraposition; //bbox[0] is always thing center
if (Vector3D.DotProduct(camNormal, thingNormal) < 0)
return false;
if (Vector3D.DotProduct(camNormal, thingNormal) < 0) { //behind camera plane
//GZBuilder.GZGeneral.TraceLine("Skipped geo. Vector3D.DotProduct(camNormal, thingNormal) < 0");
return false;
}
int len = bbox.Length;
Vector3 screenPos;
int behingCount = 0;
int leftCount = 0;
int rightCount = 0;
int topCount = 0;
int bottomCount = 0;
for (int i = 0; i < len; i++) {
//check visibility
screenPos = Vector3.Project(bbox[i], 0, 0, 1, 1, PROJ_NEAR_PLANE, General.Settings.ViewDistance, worldviewproj);
if (screenPos.X > 0 && screenPos.X < 1 && screenPos.Y > 0 && screenPos.Y < 1)
return true;
if (screenPos.Z < 0)
behingCount++;
if (screenPos.X < 0)
leftCount++;
else if (screenPos.X > 1)
rightCount++;
if (screenPos.Y < 0)
topCount++;
else if (screenPos.Y > 1)
bottomCount++;
}
if (behingCount == len || leftCount == len || rightCount == len || topCount == len || bottomCount == len)
return false; //Not on screen
return true;
}
//mxd
private static bool checkBBoxIntersection(Vector3[] bbox1, Vector3[] bbox2) {
Vector3 dist = bbox1[0] - bbox2[0];
Vector3 halfSize1 = bbox1[0] - bbox1[1];
Vector3 halfSize2 = bbox2[0] - bbox2[1];
if (halfSize1.X + halfSize2.X >= Math.Abs(dist.X) && halfSize1.Y + halfSize2.Y >= Math.Abs(dist.Y) && halfSize1.Z + halfSize2.Z >= Math.Abs(dist.Z))
return true;
return false;
}
@ -1229,9 +1256,9 @@ namespace CodeImp.DoomBuilder.Rendering
}
//dbg
private int lastTick, lastFrameRate, frameRate;
//private int lastTick, lastFrameRate, frameRate;
private int calculateFrameRate() {
/*private int calculateFrameRate() {
if (System.Environment.TickCount - lastTick >= 1000) {
lastFrameRate = frameRate;
frameRate = 0;
@ -1239,7 +1266,7 @@ namespace CodeImp.DoomBuilder.Rendering
}
frameRate++;
return lastFrameRate;
}
}*/
#endregion
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 173 KiB

View file

@ -36,6 +36,9 @@ using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Rendering;
//mxd
using CodeImp.DoomBuilder.GZBuilder.Data;
#endregion
namespace CodeImp.DoomBuilder.VisualModes
@ -80,6 +83,7 @@ namespace CodeImp.DoomBuilder.VisualModes
private int vertexoffset;
//mxd
private Vector3[] boundingBox;
//private Vector3D normal;
#endregion
@ -94,6 +98,7 @@ namespace CodeImp.DoomBuilder.VisualModes
internal Color4 ModColor4 { get { return modcolor4; } }
//mxd
internal Vector3[] BoundingBox { get { return boundingBox; } }
//internal Vector3D Normal { get { return normal; } }
/// <summary>
@ -161,8 +166,10 @@ namespace CodeImp.DoomBuilder.VisualModes
vertices = new WorldVertex[verts.Count];
verts.CopyTo(vertices, 0);
triangles = vertices.Length / 3;
//mxd
CalculateNormalsAndShading();
if(sector != null) sector.NeedsUpdateGeo = true;
}
@ -170,6 +177,9 @@ namespace CodeImp.DoomBuilder.VisualModes
protected void CalculateNormalsAndShading() {
int startIndex;
Vector3 U, V;
BoundingBoxSizes bbs = new BoundingBoxSizes(vertices[0]);
for (int i = 0; i < triangles; i++) {
startIndex = i * 3;
WorldVertex p1 = vertices[startIndex];
@ -200,8 +210,13 @@ namespace CodeImp.DoomBuilder.VisualModes
vertices[startIndex] = p1;
vertices[startIndex + 1] = p2;
vertices[startIndex + 2] = p3;
BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, p1);
BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, p2);
BoundingBoxTools.UpdateBoundingBoxSizes(ref bbs, p3);
}
// normal = new Vector3D(vertices[0].nx, vertices[0].ny, vertices[0].nz).GetNormal();
if (triangles > 0)
boundingBox = BoundingBoxTools.CalculateBoundingPlane(bbs);
}
// This compares for sorting by sector

View file

@ -266,9 +266,9 @@ namespace CodeImp.DoomBuilder.VisualModes
if (thing.IsModel) {
updateBoundingBoxForModel();
} else if (lightType != -1 && lightRadius > thing.Size) {
updateBoundingBox(lightRadius, lightRadius);
UpdateBoundingBox(lightRadius, lightRadius * 2);
} else {
updateBoundingBox((int)thing.Size, thingHeight);
UpdateBoundingBox((int)thing.Size, thingHeight);
}
}
@ -332,12 +332,12 @@ namespace CodeImp.DoomBuilder.VisualModes
int light_id = Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, thing.Type);
if (light_id != -1) {
updateLight(light_id);
updateBoundingBox(lightRadius, lightRadius);
UpdateBoundingBox(lightRadius, lightRadius * 2);
} else {
if (thing.IsModel) {
updateBoundingBoxForModel();
} else {
updateBoundingBox((int)thing.Size, thingHeight);
UpdateBoundingBox((int)thing.Size, thingHeight);
}
lightType = -1;
lightRadius = -1;
@ -358,7 +358,7 @@ namespace CodeImp.DoomBuilder.VisualModes
if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[0]) {
n = 0;
lightRenderStyle = (int)GZDoomLightRenderStyle.NORMAL;
//lightColor.Alpha used in shader to perform some cations based on light type
//lightColor.Alpha used in shader to perform some calculations based on light type
lightColor = new Color4(1.0f, (float)thing.Args[0] / 255, (float)thing.Args[1] / 255, (float)thing.Args[2] / 255);
} else if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[1]) {
n = 10;
@ -377,6 +377,12 @@ namespace CodeImp.DoomBuilder.VisualModes
lightRadiusMin = thing.Args[3] * 2; //works... that.. way in GZDoom
if (lightType > 0)
lightRadiusMax = thing.Args[4] * 2;
if (lightRadiusMin > lightRadiusMax) { //swap them
int lrm = lightRadiusMin;
lightRadiusMin = lightRadiusMax;
lightRadiusMax = lrm;
}
}
} else { //it's one of vavoom lights
lightRenderStyle = (int)GZDoomLightRenderStyle.NORMAL;
@ -412,7 +418,7 @@ namespace CodeImp.DoomBuilder.VisualModes
//pulse
if (lightType == (int)GZDoomLightType.PULSE) {
lightDelta = (float)Math.Sin(time / (100.0f * thing.Angle * 2.3f)); //just playing by the eye here...
lightRadius = Math.Abs((int)(lightRadiusMin + diff + diff * lightDelta));
lightRadius = Math.Abs((int)(lightRadiusMin + diff/2 + diff/2 * lightDelta));
//flicker
} else if (lightType == (int)GZDoomLightType.FLICKER) {
@ -433,24 +439,23 @@ namespace CodeImp.DoomBuilder.VisualModes
lightRadius = lightRadiusMin + new Random().Next(0, diff);
lightDelta = delta;
}
//return lightRadius;
}
//mxd. update bounding box
private void updateBoundingBox(int width, int height) {
public void UpdateBoundingBox(int width, int height) {
boundingBox = new Vector3[9];
boundingBox[0] = Center;
int h2 = height / 2;
boundingBox[1] = new Vector3(position_v3.X - width, position_v3.Y - width, position_v3.Z);
boundingBox[2] = new Vector3(position_v3.X + width, position_v3.Y - width, position_v3.Z);
boundingBox[3] = new Vector3(position_v3.X - width, position_v3.Y + width, position_v3.Z);
boundingBox[4] = new Vector3(position_v3.X + width, position_v3.Y + width, position_v3.Z);
boundingBox[1] = new Vector3(position_v3.X - width, position_v3.Y - width, Center.Z - h2);
boundingBox[2] = new Vector3(position_v3.X + width, position_v3.Y - width, Center.Z - h2);
boundingBox[3] = new Vector3(position_v3.X - width, position_v3.Y + width, Center.Z - h2);
boundingBox[4] = new Vector3(position_v3.X + width, position_v3.Y + width, Center.Z - h2);
boundingBox[5] = new Vector3(position_v3.X - width, position_v3.Y - width, position_v3.Z + height);
boundingBox[6] = new Vector3(position_v3.X + width, position_v3.Y - width, position_v3.Z + height);
boundingBox[7] = new Vector3(position_v3.X - width, position_v3.Y + width, position_v3.Z + height);
boundingBox[8] = new Vector3(position_v3.X + width, position_v3.Y + width, position_v3.Z + height);
boundingBox[5] = new Vector3(position_v3.X - width, position_v3.Y - width, Center.Z + h2);
boundingBox[6] = new Vector3(position_v3.X + width, position_v3.Y - width, Center.Z + h2);
boundingBox[7] = new Vector3(position_v3.X - width, position_v3.Y + width, Center.Z + h2);
boundingBox[8] = new Vector3(position_v3.X + width, position_v3.Y + width, Center.Z + h2);
}
//mxd. update bounding box from model bounding box