things included in visual mode object picking

This commit is contained in:
codeimp 2008-12-15 15:54:22 +00:00
parent 63197548a9
commit ea7feec9e5
5 changed files with 170 additions and 38 deletions

View file

@ -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
{

View file

@ -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

View file

@ -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)
{

View file

@ -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
}
}

View file

@ -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.