mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
things included in visual mode object picking
This commit is contained in:
parent
63197548a9
commit
ea7feec9e5
5 changed files with 170 additions and 38 deletions
|
@ -136,8 +136,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
if(newtarget.picked != null)
|
||||
{
|
||||
VisualGeometry prevgeo = null;
|
||||
VisualThing prevthing = null;
|
||||
if((target.picked != null) && (target.picked is VisualGeometry))
|
||||
prevgeo = (target.picked as VisualGeometry);
|
||||
else if(target.picked is VisualThing)
|
||||
prevthing = (target.picked as VisualThing);
|
||||
|
||||
// Geometry picked?
|
||||
if(newtarget.picked is VisualGeometry)
|
||||
|
@ -146,7 +149,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
if(pickedgeo.Sidedef != null)
|
||||
{
|
||||
if((prevgeo != null) && (prevgeo.Sidedef == null)) General.Interface.HideInfo();
|
||||
if((prevgeo == null) || (prevgeo.Sidedef == null)) General.Interface.HideInfo();
|
||||
General.Interface.ShowLinedefInfo(pickedgeo.Sidedef.Line);
|
||||
}
|
||||
else if(pickedgeo.Sidedef == null)
|
||||
|
@ -159,6 +162,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
General.Interface.HideInfo();
|
||||
}
|
||||
}
|
||||
// Thing picked?
|
||||
if(newtarget.picked is VisualThing)
|
||||
{
|
||||
VisualThing pickedthing = (newtarget.picked as VisualThing);
|
||||
|
||||
if(prevthing == null) General.Interface.HideInfo();
|
||||
General.Interface.ShowThingInfo(pickedthing.Thing);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -51,6 +51,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
private ImageData sprite;
|
||||
private float cageradius2;
|
||||
private Vector2D pos2d;
|
||||
private Vector3D boxp1;
|
||||
private Vector3D boxp2;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -80,24 +82,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// This builds the thing geometry. Returns false when nothing was created.
|
||||
public virtual bool Setup()
|
||||
{
|
||||
PixelColor sectorcolor = new PixelColor(255, 255, 255, 255);
|
||||
|
||||
if(sprite != null)
|
||||
{
|
||||
// Find the sector in which the thing resides
|
||||
Thing.DetermineSector();
|
||||
|
||||
PixelColor pc;
|
||||
if(Thing.Sector != null)
|
||||
{
|
||||
// Use sector brightness for color shading
|
||||
pc = new PixelColor(255, unchecked((byte)Thing.Sector.Brightness),
|
||||
sectorcolor = new PixelColor(255, unchecked((byte)Thing.Sector.Brightness),
|
||||
unchecked((byte)Thing.Sector.Brightness),
|
||||
unchecked((byte)Thing.Sector.Brightness));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Full brightness
|
||||
pc = new PixelColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
// Check if the texture is loaded
|
||||
isloaded = sprite.IsImageLoaded;
|
||||
|
@ -111,12 +108,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, pc.ToInt(), 0.0f, 1.0f);
|
||||
verts[1] = new WorldVertex(-radius, 0.0f, height, pc.ToInt(), 0.0f, 0.0f);
|
||||
verts[2] = new WorldVertex(+radius, 0.0f, height, pc.ToInt(), 1.0f, 0.0f);
|
||||
verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, sectorcolor.ToInt(), 0.0f, 1.0f);
|
||||
verts[1] = new WorldVertex(-radius, 0.0f, height, sectorcolor.ToInt(), 0.0f, 0.0f);
|
||||
verts[2] = new WorldVertex(+radius, 0.0f, height, sectorcolor.ToInt(), 1.0f, 0.0f);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, pc.ToInt(), 1.0f, 1.0f);
|
||||
verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, sectorcolor.ToInt(), 1.0f, 1.0f);
|
||||
SetVertices(verts);
|
||||
}
|
||||
else
|
||||
|
@ -129,12 +126,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, pc.ToInt(), 0.0f, 1.0f);
|
||||
verts[1] = new WorldVertex(-radius, 0.0f, height, pc.ToInt(), 0.0f, 0.0f);
|
||||
verts[2] = new WorldVertex(+radius, 0.0f, height, pc.ToInt(), 1.0f, 0.0f);
|
||||
verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, sectorcolor.ToInt(), 0.0f, 1.0f);
|
||||
verts[1] = new WorldVertex(-radius, 0.0f, height, sectorcolor.ToInt(), 0.0f, 0.0f);
|
||||
verts[2] = new WorldVertex(+radius, 0.0f, height, sectorcolor.ToInt(), 1.0f, 0.0f);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, pc.ToInt(), 1.0f, 1.0f);
|
||||
verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, sectorcolor.ToInt(), 1.0f, 1.0f);
|
||||
SetVertices(verts);
|
||||
}
|
||||
}
|
||||
|
@ -145,11 +142,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
SetPosition(pos);
|
||||
SetCageSize(info.Width, info.Height);
|
||||
SetCageColor(Thing.Color);
|
||||
|
||||
|
||||
// Keep info for object picking
|
||||
cageradius2 = info.Width * Angle2D.SQRT2;
|
||||
cageradius2 = cageradius2 * cageradius2;
|
||||
pos2d = Thing.Position;
|
||||
pos2d = pos;
|
||||
boxp1 = new Vector3D(pos.x - info.Width, pos.y - info.Width, pos.z);
|
||||
boxp2 = new Vector3D(pos.x + info.Width, pos.y + info.Width, pos.z + info.Height);
|
||||
|
||||
// Done
|
||||
return true;
|
||||
|
@ -200,7 +199,92 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// This performs an accurate test for object picking
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||
{
|
||||
return false;
|
||||
// TEST
|
||||
//u_ray = Line2D.GetNearestOnLine(from, to, pos2d);
|
||||
//return true;
|
||||
|
||||
Vector3D delta = to - from;
|
||||
float tfar = float.MaxValue;
|
||||
float tnear = float.MinValue;
|
||||
|
||||
// Ray-Box intersection code
|
||||
// See http://www.masm32.com/board/index.php?PHPSESSID=eee672d82a12b8b8f1871268f652be82&topic=9941.0
|
||||
|
||||
// Check X slab
|
||||
if(delta.x == 0.0f)
|
||||
{
|
||||
if(from.x > boxp2.x || from.x < boxp1.x)
|
||||
{
|
||||
// Ray is parallel to the planes & outside slab
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = 1.0f / delta.x;
|
||||
float t1 = (boxp1.x - from.x) * tmp;
|
||||
float t2 = (boxp2.x - from.x) * tmp;
|
||||
if(t1 > t2) General.Swap<float>(ref t1, ref t2);
|
||||
if(t1 > tnear) tnear = t1;
|
||||
if(t2 < tfar) tfar = t2;
|
||||
if(tnear > tfar || tfar < 0.0f)
|
||||
{
|
||||
// Ray missed box or box is behind ray
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check Y slab
|
||||
if(delta.y == 0.0f)
|
||||
{
|
||||
if(from.y > boxp2.y || from.y < boxp1.y)
|
||||
{
|
||||
// Ray is parallel to the planes & outside slab
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = 1.0f / delta.y;
|
||||
float t1 = (boxp1.y - from.y) * tmp;
|
||||
float t2 = (boxp2.y - from.y) * tmp;
|
||||
if(t1 > t2) General.Swap<float>(ref t1, ref t2);
|
||||
if(t1 > tnear) tnear = t1;
|
||||
if(t2 < tfar) tfar = t2;
|
||||
if(tnear > tfar || tfar < 0.0f)
|
||||
{
|
||||
// Ray missed box or box is behind ray
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check Z slab
|
||||
if(delta.z == 0.0f)
|
||||
{
|
||||
if(from.z > boxp2.z || from.z < boxp1.z)
|
||||
{
|
||||
// Ray is parallel to the planes & outside slab
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = 1.0f / delta.z;
|
||||
float t1 = (boxp1.z - from.z) * tmp;
|
||||
float t2 = (boxp2.z - from.z) * tmp;
|
||||
if(t1 > t2) General.Swap<float>(ref t1, ref t2);
|
||||
if(t1 > tnear) tnear = t1;
|
||||
if(t2 < tfar) tfar = t2;
|
||||
if(tnear > tfar || tfar < 0.0f)
|
||||
{
|
||||
// Ray missed box or box is behind ray
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set interpolation point
|
||||
u_ray = (tnear > 0.0f) ? tnear : tfar;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -1261,7 +1261,15 @@ namespace CodeImp.DoomBuilder
|
|||
#endregion
|
||||
|
||||
#region ================== Tools
|
||||
|
||||
|
||||
// This swaps two pointers
|
||||
public static void Swap<T>(ref T a, ref T b)
|
||||
{
|
||||
T t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
|
||||
// This clamps a value
|
||||
public static float Clamp(float value, float min, float max)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,12 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
public struct PixelColor
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const float BYTE_TO_FLOAT = 0.00392156862745098f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Statics
|
||||
|
||||
public static readonly PixelColor Transparent = new PixelColor(0, 0, 0, 0);
|
||||
|
@ -73,31 +79,31 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
|
||||
// Construct from color
|
||||
public static PixelColor FromColor(Color c)
|
||||
{
|
||||
return new PixelColor(c.A, c.R, c.G, c.B);
|
||||
}
|
||||
|
||||
|
||||
// Construct from int
|
||||
public static PixelColor FromInt(int c)
|
||||
{
|
||||
return FromColor(Color.FromArgb(c));
|
||||
}
|
||||
|
||||
|
||||
// Return the inverse color
|
||||
public PixelColor Inverse()
|
||||
{
|
||||
return new PixelColor((byte)(255 - a), (byte)(255 - r), (byte)(255 - g), (byte)(255 - b));
|
||||
}
|
||||
|
||||
|
||||
// Return the inverse color, but keep same alpha
|
||||
public PixelColor InverseKeepAlpha()
|
||||
{
|
||||
return new PixelColor(a, (byte)(255 - r), (byte)(255 - g), (byte)(255 - b));
|
||||
}
|
||||
|
||||
|
||||
// To int
|
||||
public int ToInt()
|
||||
{
|
||||
|
@ -109,43 +115,62 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
{
|
||||
return Color.FromArgb(a, r, g, b);
|
||||
}
|
||||
|
||||
|
||||
// To ColorRef (alpha-less)
|
||||
public int ToColorRef()
|
||||
{
|
||||
return ((int)r + ((int)b << 16) + ((int)g << 8));
|
||||
}
|
||||
|
||||
|
||||
// To ColorValue
|
||||
public Color4 ToColorValue()
|
||||
{
|
||||
return new Color4((float)a * 0.00392156862745098f,
|
||||
(float)r * 0.00392156862745098f,
|
||||
(float)g * 0.00392156862745098f,
|
||||
(float)b * 0.00392156862745098f);
|
||||
return new Color4((float)a * BYTE_TO_FLOAT,
|
||||
(float)r * BYTE_TO_FLOAT,
|
||||
(float)g * BYTE_TO_FLOAT,
|
||||
(float)b * BYTE_TO_FLOAT);
|
||||
}
|
||||
|
||||
|
||||
// This returns a new PixelColor with adjusted alpha
|
||||
public PixelColor WithAlpha(byte a)
|
||||
{
|
||||
return new PixelColor(this, a);
|
||||
}
|
||||
|
||||
|
||||
// This blends two colors with respect to alpha
|
||||
public PixelColor Blend(PixelColor a, PixelColor b)
|
||||
{
|
||||
PixelColor c = new PixelColor();
|
||||
float ba;
|
||||
|
||||
ba = (float)a.a * 0.003921568627450980392156862745098f;
|
||||
|
||||
ba = (float)a.a * BYTE_TO_FLOAT;
|
||||
c.r = (byte)((float)a.r * (1f - ba) + (float)b.r * ba);
|
||||
c.g = (byte)((float)a.g * (1f - ba) + (float)b.g * ba);
|
||||
c.b = (byte)((float)a.b * (1f - ba) + (float)b.b * ba);
|
||||
c.a = (byte)((float)a.a * (1f - ba) + ba);
|
||||
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// This modulates two colors
|
||||
public static PixelColor Modulate(PixelColor a, PixelColor b)
|
||||
{
|
||||
float aa = (float)a.a * BYTE_TO_FLOAT;
|
||||
float ar = (float)a.r * BYTE_TO_FLOAT;
|
||||
float ag = (float)a.g * BYTE_TO_FLOAT;
|
||||
float ab = (float)a.b * BYTE_TO_FLOAT;
|
||||
float ba = (float)b.a * BYTE_TO_FLOAT;
|
||||
float br = (float)b.r * BYTE_TO_FLOAT;
|
||||
float bg = (float)b.g * BYTE_TO_FLOAT;
|
||||
float bb = (float)b.b * BYTE_TO_FLOAT;
|
||||
PixelColor c = new PixelColor();
|
||||
c.a = (byte)((aa * ba) * 255.0f);
|
||||
c.r = (byte)((ar * br) * 255.0f);
|
||||
c.g = (byte)((ag * bg) * 255.0f);
|
||||
c.b = (byte)((ab * bb) * 255.0f);
|
||||
return c;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -592,6 +592,10 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
}
|
||||
}
|
||||
|
||||
// Add all the visible things
|
||||
foreach(VisualThing vt in visiblethings)
|
||||
pickables.Add(vt);
|
||||
|
||||
// Now we have a list of potential geometry that lies along the trace line.
|
||||
// We still don't know what geometry actually hits, but we ruled out that which doesn't get even close.
|
||||
// This is still too much for accurate intersection testing, so we do a fast reject pass first.
|
||||
|
|
Loading…
Reference in a new issue