mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Port SelectionBox to C.
This commit is contained in:
parent
c92b53bc79
commit
05d0c8f635
@ -276,7 +276,6 @@
|
||||
<Compile Include="Selections\AxisLinesRenderer.cs" />
|
||||
<Compile Include="Selections\PickedPosRenderer.cs" />
|
||||
<Compile Include="Selections\SelectionBox.cs" />
|
||||
<Compile Include="Selections\SelectionBoxComparer.cs" />
|
||||
<Compile Include="Selections\SelectionManager.cs" />
|
||||
<Compile Include="Singleplayer\FallingPhysics.cs" />
|
||||
<Compile Include="Singleplayer\FoliagePhysics.cs" />
|
||||
|
@ -1,11 +1,12 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Selections {
|
||||
|
||||
public class SelectionBox {
|
||||
internal class SelectionBox {
|
||||
|
||||
public byte ID;
|
||||
public Vector3I Min, Max;
|
||||
@ -75,4 +76,40 @@ namespace ClassicalSharp.Selections {
|
||||
v.X = x2; v.Y = y2; v.Z = z2; vertices[index++] = v;
|
||||
}
|
||||
}
|
||||
|
||||
internal class SelectionBoxComparer : IComparer<SelectionBox> {
|
||||
|
||||
public int Compare(SelectionBox a, SelectionBox b) {
|
||||
// Reversed comparison order because we need to render back to front for alpha blending.
|
||||
return a.MinDist == b.MinDist
|
||||
? b.MaxDist.CompareTo(a.MaxDist)
|
||||
: b.MinDist.CompareTo(a.MinDist);
|
||||
}
|
||||
|
||||
internal void Intersect(SelectionBox box, Vector3 origin) {
|
||||
Vector3I min = box.Min, max = box.Max;
|
||||
float closest = float.PositiveInfinity, furthest = float.NegativeInfinity;
|
||||
// Bottom corners
|
||||
UpdateDist(origin, min.X, min.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, min.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, min.Y, max.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, min.X, min.Y, max.Z, ref closest, ref furthest);
|
||||
// Top corners
|
||||
UpdateDist(origin, min.X, max.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, max.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, max.Y, max.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, min.X, max.Y, max.Z, ref closest, ref furthest);
|
||||
box.MinDist = closest; box.MaxDist = furthest;
|
||||
}
|
||||
|
||||
|
||||
static void UpdateDist(Vector3 p, float x2, float y2, float z2,
|
||||
ref float closest, ref float furthest) {
|
||||
float dx = x2 - p.X, dy = y2 - p.Y, dz = z2 - p.Z;
|
||||
float dist = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
if (dist < closest) closest = dist;
|
||||
if (dist > furthest) furthest = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Selections {
|
||||
|
||||
internal class SelectionBoxComparer : IComparer<SelectionBox> {
|
||||
|
||||
public int Compare(SelectionBox a, SelectionBox b) {
|
||||
// Reversed comparison order because we need to render back to front for alpha blending.
|
||||
return a.MinDist == b.MinDist ? b.MaxDist.CompareTo(a.MaxDist)
|
||||
: b.MinDist.CompareTo(a.MinDist);
|
||||
}
|
||||
|
||||
internal void Intersect(SelectionBox box, Vector3 origin) {
|
||||
Vector3I min = box.Min, max = box.Max;
|
||||
float closest = float.PositiveInfinity, furthest = float.NegativeInfinity;
|
||||
// Bottom corners
|
||||
UpdateDist(origin, min.X, min.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, min.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, min.Y, max.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, min.X, min.Y, max.Z, ref closest, ref furthest);
|
||||
// Top corners
|
||||
UpdateDist(origin, min.X, max.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, max.Y, min.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, max.X, max.Y, max.Z, ref closest, ref furthest);
|
||||
UpdateDist(origin, min.X, max.Y, max.Z, ref closest, ref furthest);
|
||||
box.MinDist = closest; box.MaxDist = furthest;
|
||||
}
|
||||
|
||||
static void UpdateDist(Vector3 p, float x2, float y2, float z2,
|
||||
ref float closest, ref float furthest) {
|
||||
float dist = Utils.DistanceSquared(p.X, p.Y, p.Z, x2, y2, z2);
|
||||
if (dist < closest) closest = dist;
|
||||
if (dist > furthest) furthest = dist;
|
||||
}
|
||||
}
|
||||
}
|
@ -81,14 +81,7 @@ namespace ClassicalSharp {
|
||||
float cosA = (float)Math.Cos(angle), sinA = (float)Math.Sin(angle);
|
||||
return new Vector3(cosA * v.X + sinA * v.Y, -sinA * v.X + cosA * v.Y, v.Z);
|
||||
}
|
||||
|
||||
/// <summary> Returns the square of the euclidean distance between two points. </summary>
|
||||
public static float DistanceSquared(float x1, float y1, float z1, float x2, float y2, float z2) {
|
||||
float dx = x2 - x1, dy = y2 - y1, dz = z2 - z1;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Returns a normalised vector that faces in the direction
|
||||
/// described by the given yaw and pitch. </summary>
|
||||
public static Vector3 GetDirVector(double yawRad, double pitchRad) {
|
||||
|
@ -106,10 +106,10 @@ void BordersRenderer_DrawX(Int32 x, Int32 z1, Int32 z2, Int32 y1, Int32 y2, Int3
|
||||
if (y2 > endY) y2 = endY;
|
||||
|
||||
Real32 u2 = (Real32)z2 - (Real32)z1, v2 = (Real32)y2 - (Real32)y1;
|
||||
v.Y = (Real32)y1; v.Z = (Real32)z1; v.U = 0.0f; v.V = v2; *ptr = v; ptr++;
|
||||
v.Y = (Real32)y2; v.V = 0.0f; *ptr = v; ptr++;
|
||||
v.Z = (Real32)z2; v.U = u2; *ptr = v; ptr++;
|
||||
v.Y = (Real32)y1; v.V = v2; *ptr = v; ptr++;
|
||||
v.Y = (Real32)y1; v.Z = (Real32)z1; v.U = 0.0f; v.V = v2; *ptr++ = v;
|
||||
v.Y = (Real32)y2; v.V = 0.0f; *ptr++ = v;
|
||||
v.Z = (Real32)z2; v.U = u2; *ptr++ = v;
|
||||
v.Y = (Real32)y1; v.V = v2; *ptr++ = v;
|
||||
}
|
||||
}
|
||||
*vertices = ptr;
|
||||
@ -130,10 +130,10 @@ void BordersRenderer_DrawZ(Int32 z, Int32 x1, Int32 x2, Int32 y1, Int32 y2, Int3
|
||||
if (y2 > endY) y2 = endY;
|
||||
|
||||
Real32 u2 = (Real32)x2 - (Real32)x1, v2 = (Real32)y2 - (Real32)y1;
|
||||
v.X = (Real32)x1; v.Y = (Real32)y1; v.U = 0.0f; v.V = v2; *ptr = v; ptr++;
|
||||
v.Y = (Real32)y2; v.V = 0.0f; *ptr = v; ptr++;
|
||||
v.X = (Real32)x2; v.U = u2; *ptr = v; ptr++;
|
||||
v.Y = (Real32)y1; v.V = v2; *ptr = v; ptr++;
|
||||
v.X = (Real32)x1; v.Y = (Real32)y1; v.U = 0.0f; v.V = v2; *ptr++ = v;
|
||||
v.Y = (Real32)y2; v.V = 0.0f; *ptr++ = v;
|
||||
v.X = (Real32)x2; v.U = u2; *ptr++ = v;
|
||||
v.Y = (Real32)y1; v.V = v2; *ptr++ = v;
|
||||
}
|
||||
}
|
||||
*vertices = ptr;
|
||||
@ -154,10 +154,10 @@ void BordersRenderer_DrawY(Int32 x1, Int32 z1, Int32 x2, Int32 z2, Real32 y, Int
|
||||
if (z2 > endZ) z2 = endZ;
|
||||
|
||||
Real32 u2 = (Real32)x2 - (Real32)x1, v2 = (Real32)z2 - (Real32)z1;
|
||||
v.X = (Real32)x1 + offset; v.Z = (Real32)z1 + offset; v.U = 0.0f; v.V = 0.0f; *ptr = v; ptr++;
|
||||
v.Z = (Real32)z2 + offset; v.V = v2; *ptr = v; ptr++;
|
||||
v.X = (Real32)x2 + offset; v.U = u2; *ptr = v; ptr++;
|
||||
v.Z = (Real32)z1 + offset; v.V = 0.0f; *ptr = v; ptr++;
|
||||
v.X = (Real32)x1 + offset; v.Z = (Real32)z1 + offset; v.U = 0.0f; v.V = 0.0f; *ptr++ = v;
|
||||
v.Z = (Real32)z2 + offset; v.V = v2; *ptr++ = v;
|
||||
v.X = (Real32)x2 + offset; v.U = u2; *ptr++ = v;
|
||||
v.Z = (Real32)z1 + offset; v.V = 0.0f; *ptr++ = v;
|
||||
}
|
||||
}
|
||||
*vertices = ptr;
|
||||
|
@ -2,8 +2,6 @@
|
||||
#include "TerrainAtlas.h"
|
||||
#include "Constants.h"
|
||||
|
||||
#define AddVertex *ptr = v; ptr++
|
||||
|
||||
/* Performance critical, use macro to ensure always inlined. */
|
||||
#define ApplyTint \
|
||||
if (Drawer_Tinted) {\
|
||||
@ -23,10 +21,10 @@ void Drawer_XMin(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
|
||||
|
||||
VertexP3fT2fC4b* ptr = *vertices;
|
||||
VertexP3fT2fC4b v; v.X = Drawer_X1; v.Col = col;
|
||||
v.Y = Drawer_Y2; v.Z = Drawer_Z2 + (count - 1); v.U = u2; v.V = v1; AddVertex;
|
||||
v.Z = Drawer_Z1; v.U = u1; AddVertex;
|
||||
v.Y = Drawer_Y1; v.V = v2; AddVertex;
|
||||
v.Z = Drawer_Z2 + (count - 1); v.U = u2; AddVertex;
|
||||
v.Y = Drawer_Y2; v.Z = Drawer_Z2 + (count - 1); v.U = u2; v.V = v1; *ptr++ = v;
|
||||
v.Z = Drawer_Z1; v.U = u1; *ptr++ = v;
|
||||
v.Y = Drawer_Y1; v.V = v2; *ptr++ = v;
|
||||
v.Z = Drawer_Z2 + (count - 1); v.U = u2; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
@ -40,10 +38,10 @@ void Drawer_XMax(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
|
||||
|
||||
VertexP3fT2fC4b* ptr = *vertices;
|
||||
VertexP3fT2fC4b v; v.X = Drawer_X2; v.Col = col;
|
||||
v.Y = Drawer_Y2; v.Z = Drawer_Z1; v.U = u1; v.V = v1; AddVertex;
|
||||
v.Z = Drawer_Z2 + (count - 1); v.U = u2; AddVertex;
|
||||
v.Y = Drawer_Y1; v.V = v2; AddVertex;
|
||||
v.Z = Drawer_Z1; v.U = u1; AddVertex;
|
||||
v.Y = Drawer_Y2; v.Z = Drawer_Z1; v.U = u1; v.V = v1; *ptr++ = v;
|
||||
v.Z = Drawer_Z2 + (count - 1); v.U = u2; *ptr++ = v;
|
||||
v.Y = Drawer_Y1; v.V = v2; *ptr++ = v;
|
||||
v.Z = Drawer_Z1; v.U = u1; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
@ -57,10 +55,10 @@ void Drawer_ZMin(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
|
||||
|
||||
VertexP3fT2fC4b* ptr = *vertices;
|
||||
VertexP3fT2fC4b v; v.Z = Drawer_Z1; v.Col = col;
|
||||
v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y1; v.U = u2; v.V = v2; AddVertex;
|
||||
v.X = Drawer_X1; v.U = u1; AddVertex;
|
||||
v.Y = Drawer_Y2; v.V = v1; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y1; v.U = u2; v.V = v2; *ptr++ = v;
|
||||
v.X = Drawer_X1; v.U = u1; *ptr++ = v;
|
||||
v.Y = Drawer_Y2; v.V = v1; *ptr++ = v;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
@ -74,10 +72,10 @@ void Drawer_ZMax(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
|
||||
|
||||
VertexP3fT2fC4b* ptr = *vertices;
|
||||
VertexP3fT2fC4b v; v.Z = Drawer_Z2; v.Col = col;
|
||||
v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y2; v.U = u2; v.V = v1; AddVertex;
|
||||
v.X = Drawer_X1; v.U = u1; AddVertex;
|
||||
v.Y = Drawer_Y1; v.V = v2; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.Y = Drawer_Y2; v.U = u2; v.V = v1; *ptr++ = v;
|
||||
v.X = Drawer_X1; v.U = u1; *ptr++ = v;
|
||||
v.Y = Drawer_Y1; v.V = v2; *ptr++ = v;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
@ -91,10 +89,10 @@ void Drawer_YMin(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
|
||||
|
||||
VertexP3fT2fC4b* ptr = *vertices;
|
||||
VertexP3fT2fC4b v; v.Y = Drawer_Y1; v.Col = col;
|
||||
v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z2; v.U = u2; v.V = v2; AddVertex;
|
||||
v.X = Drawer_X1; v.U = u1; AddVertex;
|
||||
v.Z = Drawer_Z1; v.V = v1; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z2; v.U = u2; v.V = v2; *ptr++ = v;
|
||||
v.X = Drawer_X1; v.U = u1; *ptr++ = v;
|
||||
v.Z = Drawer_Z1; v.V = v1; *ptr++ = v;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
@ -108,9 +106,9 @@ void Drawer_YMax(Int32 count, PackedCol col, TextureLoc texLoc, VertexP3fT2fC4b*
|
||||
|
||||
VertexP3fT2fC4b* ptr = *vertices;
|
||||
VertexP3fT2fC4b v; v.Y = Drawer_Y2; v.Col = col;
|
||||
v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z1; v.U = u2; v.V = v1; AddVertex;
|
||||
v.X = Drawer_X1; v.U = u1; AddVertex;
|
||||
v.Z = Drawer_Z2; v.V = v2; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; AddVertex;
|
||||
v.X = Drawer_X2 + (count - 1); v.Z = Drawer_Z1; v.U = u2; v.V = v1; *ptr++ = v;
|
||||
v.X = Drawer_X1; v.U = u1; *ptr++ = v;
|
||||
v.Z = Drawer_Z2; v.V = v2; *ptr++ = v;
|
||||
v.X = Drawer_X2 + (count - 1); v.U = u2; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
@ -165,10 +165,10 @@ void EnvRenderer_DrawSkyY(Int32 x1, Int32 z1, Int32 x2, Int32 z2, Int32 y, Int32
|
||||
z2 = z1 + axisSize;
|
||||
if (z2 > endZ) z2 = endZ;
|
||||
|
||||
v.X = (Real32)x1; v.Z = (Real32)z1; *vertices = v; vertices++;
|
||||
v.Z = (Real32)z2; *vertices = v; vertices++;
|
||||
v.X = (Real32)x2; *vertices = v; vertices++;
|
||||
v.Z = (Real32)z1; *vertices = v; vertices++;
|
||||
v.X = (Real32)x1; v.Z = (Real32)z1; *vertices++ = v;
|
||||
v.Z = (Real32)z2; *vertices++ = v;
|
||||
v.X = (Real32)x2; *vertices++ = v;
|
||||
v.Z = (Real32)z1; *vertices++ = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,10 +190,10 @@ void EnvRenderer_DrawCloudsY(Int32 x1, Int32 z1, Int32 x2, Int32 z2, Int32 y, In
|
||||
|
||||
Real32 u1 = (Real32)x1 / 2048.0f + offset, u2 = (Real32)x2 / 2048.0f + offset;
|
||||
Real32 v1 = (Real32)z1 / 2048.0f + offset, v2 = (Real32)z2 / 2048.0f + offset;
|
||||
v.X = (Real32)x1; v.Z = (Real32)z1; v.U = u1; v.V = v1; *vertices = v; vertices++;
|
||||
v.Z = (Real32)z2; v.V = v2; *vertices = v; vertices++;
|
||||
v.X = (Real32)x2; v.U = u2; *vertices = v; vertices++;
|
||||
v.Z = (Real32)z1; v.V = v1; *vertices = v; vertices++;
|
||||
v.X = (Real32)x1; v.Z = (Real32)z1; v.U = u1; v.V = v1; *vertices++ = v;
|
||||
v.Z = (Real32)z2; v.V = v2; *vertices++ = v;
|
||||
v.X = (Real32)x2; v.U = u2; *vertices++ = v;
|
||||
v.Z = (Real32)z1; v.V = v1; *vertices++ = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ void Gfx_Clear(void);
|
||||
void Gfx_ClearColour(PackedCol col);
|
||||
void Gfx_SetDepthTest(bool enabled);
|
||||
void Gfx_SetDepthTestFunc(Int32 compareFunc);
|
||||
void Gfx_SetColourWrite(bool enabled);
|
||||
void Gfx_SetColourWriteMask(bool r, bool g, bool b, bool a);
|
||||
void Gfx_SetDepthWrite(bool enabled);
|
||||
|
||||
/* Creates a vertex buffer that can have its data dynamically updated. */
|
||||
|
@ -47,24 +47,27 @@ void PickedPosRenderer_Render(Real64 delta) {
|
||||
}
|
||||
|
||||
void PickedPosRenderer_XQuad(Real32 x, Real32 z1, Real32 y1, Real32 z2, Real32 y2) {
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x, y1, z1, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x, y2, z1, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x, y2, z2, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x, y1, z2, pickedPos_col); pickedPos_ptr++;
|
||||
}
|
||||
|
||||
void PickedPosRenderer_ZQuad(Real32 z, Real32 x1, Real32 y1, Real32 x2, Real32 y2) {
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x1, y1, z, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x1, y2, z, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x2, y2, z, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x2, y1, z, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b v; v.X = x; v.Col = pickedPos_col;
|
||||
v.Y = y1; v.Z = z1; *pickedPos_ptr++ = v;
|
||||
v.Y = y2; *pickedPos_ptr++ = v;
|
||||
v.Z = z2; *pickedPos_ptr++ = v;
|
||||
v.Y = y1; *pickedPos_ptr++ = v;
|
||||
}
|
||||
|
||||
void PickedPosRenderer_YQuad(Real32 y, Real32 x1, Real32 z1, Real32 x2, Real32 z2) {
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x1, y, z1, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x1, y, z2, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x2, y, z2, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b_Set(pickedPos_ptr, x2, y, z1, pickedPos_col); pickedPos_ptr++;
|
||||
VertexP3fC4b v; v.Y = y; v.Col = pickedPos_col;
|
||||
v.X = x1; v.Z = z1; *pickedPos_ptr++ = v;
|
||||
v.Z = z2; *pickedPos_ptr++ = v;
|
||||
v.X = x2; *pickedPos_ptr++ = v;
|
||||
v.Z = z1; *pickedPos_ptr++ = v;
|
||||
}
|
||||
|
||||
void PickedPosRenderer_ZQuad(Real32 z, Real32 x1, Real32 y1, Real32 x2, Real32 y2) {
|
||||
VertexP3fC4b v; v.Z = z; v.Col = pickedPos_col;
|
||||
v.X = x1; v.Y = y1; *pickedPos_ptr++ = v;
|
||||
v.Y = y2; *pickedPos_ptr++ = v;
|
||||
v.X = x2; *pickedPos_ptr++ = v;
|
||||
v.Y = y1; *pickedPos_ptr++ = v;
|
||||
}
|
||||
|
||||
void PickedPosRenderer_UpdateState(PickedPos* selected) {
|
||||
|
@ -456,7 +456,7 @@ void StatusScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
Widget_Render(&screen->Status, delta);
|
||||
|
||||
if (!Game_ClassicMode && Gui_Active == NULL) {
|
||||
if (StatusScreen_HacksChanged(screen)) { StatusScreen_UpdateHackState(screen, false); }
|
||||
if (StatusScreen_HacksChanged(screen)) { StatusScreen_UpdateHackState(screen); }
|
||||
StatusScreen_DrawPosition(screen);
|
||||
Widget_Render(&screen->HackStates, delta);
|
||||
}
|
||||
@ -974,7 +974,7 @@ bool HUDScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
if (key == playerListKey && handles) {
|
||||
if (!screen->ShowingList && !ServerConnection_IsSinglePlayer) {
|
||||
screen->WasShowingList = true;
|
||||
ContextRecreated();
|
||||
HUDScreen_ContextRecreated(screen);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
#include "SelectionBox.h"
|
||||
#include "ExtMath.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "GraphicsCommon.h"
|
||||
#include "Event.h"
|
||||
#include "Funcs.h"
|
||||
|
||||
void SelectionBox_Make(SelectionBox* box, Vector3I* p1, Vector3I* p2, PackedCol col) {
|
||||
box->ID = 0;
|
||||
box->MinDist = 0.0f; box->MaxDist = 0.0f;
|
||||
Vector3I_Min(&box->Min, p1, p2);
|
||||
Vector3I_Max(&box->Max, p1, p2);
|
||||
box->Col = col;
|
||||
}
|
||||
/* Data for a selection box. */
|
||||
typedef struct SelectionBox_ {
|
||||
Vector3I Min, Max;
|
||||
PackedCol Col;
|
||||
Real32 MinDist, MaxDist;
|
||||
} SelectionBox;
|
||||
|
||||
void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4b** lineVertices) {
|
||||
Real32 offset = box->MinDist < 32.0f * 32.0f ? (1.0f / 32.0f) : (1.0f / 16.0f);
|
||||
@ -46,27 +50,197 @@ void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4
|
||||
void SelectionBox_VerQuad(VertexP3fC4b** vertices, PackedCol col,
|
||||
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2) {
|
||||
VertexP3fC4b* ptr = *vertices;
|
||||
VertexP3fC4b_Set(ptr, x1, y1, z1, col); ptr++;
|
||||
VertexP3fC4b_Set(ptr, x1, y2, z1, col); ptr++;
|
||||
VertexP3fC4b_Set(ptr, x2, y2, z2, col); ptr++;
|
||||
VertexP3fC4b_Set(ptr, x2, y1, z2, col); ptr++;
|
||||
VertexP3fC4b v; v.Col = col;
|
||||
|
||||
v.X = x1; v.Y = y1; v.Z = z1; *ptr++ = v;
|
||||
v.Y = y2; *ptr++ = v;
|
||||
v.X = x2; v.Z = z2; *ptr++ = v;
|
||||
v.Y = y1; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
void SelectionBox_HorQuad(VertexP3fC4b** vertices, PackedCol col,
|
||||
Real32 x1, Real32 z1, Real32 x2, Real32 z2, Real32 y) {
|
||||
VertexP3fC4b* ptr = *vertices;
|
||||
VertexP3fC4b_Set(ptr, x1, y, z1, col); ptr++;
|
||||
VertexP3fC4b_Set(ptr, x1, y, z2, col); ptr++;
|
||||
VertexP3fC4b_Set(ptr, x2, y, z2, col); ptr++;
|
||||
VertexP3fC4b_Set(ptr, x2, y, z1, col); ptr++;
|
||||
VertexP3fC4b v; v.Y = y; v.Col = col;
|
||||
|
||||
v.X = x1; v.Z = z1; *ptr++ = v;
|
||||
v.Z = z2; *ptr++ = v;
|
||||
v.X = x2; *ptr++ = v;
|
||||
v.Z = z1; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
void SelectionBox_Line(VertexP3fC4b** vertices, PackedCol col,
|
||||
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2) {
|
||||
VertexP3fC4b* ptr = *vertices;
|
||||
VertexP3fC4b_Set(ptr, x1, y1, z1, col); ptr++;
|
||||
VertexP3fC4b_Set(ptr, x2, y2, z2, col); ptr++;
|
||||
VertexP3fC4b* ptr = *vertices;
|
||||
VertexP3fC4b v; v.Col = col;
|
||||
|
||||
v.X = x1; v.Y = y1; v.Z = z1; *ptr++ = v;
|
||||
v.X = x2; v.Y = y2; v.Z = z2; *ptr++ = v;
|
||||
*vertices = ptr;
|
||||
}
|
||||
|
||||
|
||||
Int32 SelectionBox_Compare(SelectionBox* a, SelectionBox* b) {
|
||||
Real32 aDist, bDist;
|
||||
if (a->MinDist == b->MinDist) {
|
||||
aDist = a->MaxDist; bDist = b->MaxDist;
|
||||
} else {
|
||||
aDist = a->MinDist; bDist = b->MinDist;
|
||||
}
|
||||
|
||||
/* Reversed comparison order result, because we need to render back to front for alpha blending */
|
||||
if (aDist < bDist) return 1;
|
||||
if (aDist > bDist) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SelectionBox_UpdateDist(Vector3 p, Real32 x2, Real32 y2, Real32 z2, Real32* closest, Real32* furthest) {
|
||||
Real32 dx = x2 - p.X, dy = y2 - p.Y, dz = z2 - p.Z;
|
||||
Real32 dist = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
if (dist < *closest) *closest = dist;
|
||||
if (dist > *furthest) *furthest = dist;
|
||||
}
|
||||
|
||||
void SelectionBox_Intersect(SelectionBox* box, Vector3 origin) {
|
||||
Vector3I min = box->Min, max = box->Max;
|
||||
Real32 closest = MATH_POS_INF, furthest = -MATH_POS_INF;
|
||||
/* Bottom corners */
|
||||
SelectionBox_UpdateDist(origin, min.X, min.Y, min.Z, &closest, &furthest);
|
||||
SelectionBox_UpdateDist(origin, max.X, min.Y, min.Z, &closest, &furthest);
|
||||
SelectionBox_UpdateDist(origin, max.X, min.Y, max.Z, &closest, &furthest);
|
||||
SelectionBox_UpdateDist(origin, min.X, min.Y, max.Z, &closest, &furthest);
|
||||
/* Top corners */
|
||||
SelectionBox_UpdateDist(origin, min.X, max.Y, min.Z, &closest, &furthest);
|
||||
SelectionBox_UpdateDist(origin, max.X, max.Y, min.Z, &closest, &furthest);
|
||||
SelectionBox_UpdateDist(origin, max.X, max.Y, max.Z, &closest, &furthest);
|
||||
SelectionBox_UpdateDist(origin, min.X, max.Y, max.Z, &closest, &furthest);
|
||||
box->MinDist = closest; box->MaxDist = furthest;
|
||||
}
|
||||
|
||||
|
||||
#define SELECTIONS_MAX 256
|
||||
#define SELECTIONS_VERTICES 24
|
||||
#define SELECTIONS_MAX_VERTICES SELECTIONS_MAX * SELECTIONS_VERTICES
|
||||
|
||||
UInt32 selections_count;
|
||||
SelectionBox selections_list[SELECTIONS_MAX];
|
||||
UInt8 selections_ids[SELECTIONS_MAX];
|
||||
GfxResourceID selections_VB, selections_LineVB;
|
||||
bool selections_allocated;
|
||||
|
||||
void Selections_Add(UInt8 id, Vector3I p1, Vector3I p2, PackedCol col) {
|
||||
SelectionBox sel;
|
||||
Vector3I_Min(&sel.Min, &p1, &p2);
|
||||
Vector3I_Max(&sel.Max, &p1, &p2);
|
||||
sel.Col = col;
|
||||
|
||||
Selections_Remove(id);
|
||||
selections_list[selections_count] = sel;
|
||||
selections_ids[selections_count] = id;
|
||||
selections_count++;
|
||||
}
|
||||
|
||||
void Selections_Remove(UInt8 id) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < selections_count; i++) {
|
||||
if (selections_ids[i] != id) continue;
|
||||
|
||||
for (; i < selections_count - 1; i++) {
|
||||
selections_list[i] = selections_list[i + 1];
|
||||
selections_ids[i] = selections_ids[i + 1];
|
||||
}
|
||||
|
||||
selections_count--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Selections_ContextLost(void) {
|
||||
Gfx_DeleteVb(&selections_VB);
|
||||
Gfx_DeleteVb(&selections_LineVB);
|
||||
}
|
||||
|
||||
void Selections_ContextRecreated(void) {
|
||||
if (!selections_allocated) return;
|
||||
selections_VB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES);
|
||||
selections_LineVB = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FC4B, SELECTIONS_MAX_VERTICES);
|
||||
}
|
||||
|
||||
void Selections_QuickSort(Int32 left, Int32 right) {
|
||||
UInt8* values = selections_ids; UInt8 value;
|
||||
SelectionBox* keys = selections_list; SelectionBox key;
|
||||
while (left < right) {
|
||||
Int32 i = left, j = right;
|
||||
SelectionBox* pivot = &keys[(i + j) / 2];
|
||||
|
||||
/* partition the list */
|
||||
while (i <= j) {
|
||||
while (SelectionBox_Compare(pivot, &keys[i]) > 0) i++;
|
||||
while (SelectionBox_Compare(pivot, &keys[j]) < 0) j--;
|
||||
QuickSort_Swap_KV_Maybe();
|
||||
}
|
||||
/* recurse into the smaller subset */
|
||||
QuickSort_Recurse(Selections_QuickSort)
|
||||
}
|
||||
}
|
||||
|
||||
void Selections_Render(Real64 delta) {
|
||||
if (selections_count == 0 || Gfx_LostContext) return;
|
||||
/* TODO: Proper selection box sorting. But this is very difficult because
|
||||
we can have boxes within boxes, intersecting boxes, etc. Probably not worth it. */
|
||||
Vector3 camPos = Game_CurrentCameraPos;
|
||||
UInt32 i;
|
||||
for (i = 0; i < selections_count; i++) {
|
||||
SelectionBox_Intersect(&selections_list[i], camPos);
|
||||
}
|
||||
Selections_QuickSort(0, selections_count - 1);
|
||||
|
||||
if (!selections_allocated) { /* lazy init as most servers don't use this */
|
||||
Selections_ContextRecreated();
|
||||
selections_allocated = true;
|
||||
}
|
||||
|
||||
VertexP3fC4b vertices[SELECTIONS_MAX_VERTICES]; VertexP3fC4b* ptr = vertices;
|
||||
VertexP3fC4b lineVertices[SELECTIONS_MAX_VERTICES]; VertexP3fC4b* linePtr = lineVertices;
|
||||
for (i = 0; i < selections_count; i++) {
|
||||
SelectionBox_Render(&selections_list[i], &ptr, &linePtr);
|
||||
}
|
||||
|
||||
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FC4B);
|
||||
GfxCommon_UpdateDynamicVb_Lines(selections_LineVB, lineVertices,
|
||||
selections_count * SELECTIONS_VERTICES);
|
||||
|
||||
Gfx_SetDepthWrite(false);
|
||||
Gfx_SetAlphaBlending(true);
|
||||
GfxCommon_UpdateDynamicVb_IndexedTris(selections_VB, vertices,
|
||||
selections_count * SELECTIONS_VERTICES);
|
||||
Gfx_SetDepthWrite(true);
|
||||
Gfx_SetAlphaBlending(false);
|
||||
}
|
||||
|
||||
void Selections_Init(void) {
|
||||
Event_RegisterVoid(&GfxEvents_ContextLost, NULL, Selections_ContextLost);
|
||||
Event_RegisterVoid(&GfxEvents_ContextRecreated, NULL, Selections_ContextRecreated);
|
||||
}
|
||||
|
||||
void Selections_Reset(void) {
|
||||
selections_count = 0;
|
||||
}
|
||||
|
||||
void Selections_Free(void) {
|
||||
Selections_ContextLost();
|
||||
Event_UnregisterVoid(&GfxEvents_ContextLost, NULL, Selections_ContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, NULL, Selections_ContextRecreated);
|
||||
}
|
||||
|
||||
IGameComponent Selections_MakeComponent(void) {
|
||||
IGameComponent comp = IGameComponent_MakeEmpty();
|
||||
comp.Init = Selections_Init;
|
||||
comp.Free = Selections_Free;
|
||||
comp.Reset = Selections_Reset;
|
||||
comp.OnNewMap = Selections_Reset;
|
||||
return comp;
|
||||
}
|
@ -1,35 +1,13 @@
|
||||
#ifndef CC_SELECTIONBOX_H
|
||||
#define CC_SELECTIONBOX_H
|
||||
#include "Typedefs.h"
|
||||
#include "PackedCol.h"
|
||||
#include "Vectors.h"
|
||||
#include "VertexStructs.h"
|
||||
#include "GameStructs.h"
|
||||
#include "Vectors.h"
|
||||
/* Describes a selection box, and contains methods related to the selection box.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
/* Data for a selection box. */
|
||||
typedef struct SelectionBox_ {
|
||||
/* ID of this selection box.*/
|
||||
UInt8 ID;
|
||||
/* Minimum corner of the box. */
|
||||
Vector3I Min;
|
||||
/* Maximum corner of the box. */
|
||||
Vector3I Max;
|
||||
/* Colour of this box. */
|
||||
PackedCol Col;
|
||||
/* Closest distance to player of any of the eight corners of the box. */
|
||||
Real32 MinDist;
|
||||
/* Furthest distance to player of any of the eight corners of the box. */
|
||||
Real32 MaxDist;
|
||||
} SelectionBox;
|
||||
|
||||
|
||||
/* Constructs a selection box. */
|
||||
void SelectionBox_Make(SelectionBox* box, Vector3I* p1, Vector3I* p2, PackedCol col);
|
||||
/* Constructs the vertices and line vertices for a selection box. */
|
||||
void SelectionBox_Render(SelectionBox* box, VertexP3fC4b** vertices, VertexP3fC4b** lineVertices);
|
||||
|
||||
/* Draws a vertical quad. */
|
||||
void SelectionBox_VerQuad(VertexP3fC4b** vertices, PackedCol col,
|
||||
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2);
|
||||
@ -39,4 +17,9 @@ void SelectionBox_HorQuad(VertexP3fC4b** vertices, PackedCol col,
|
||||
/* Draws a line between two points. */
|
||||
void SelectionBox_Line(VertexP3fC4b** vertices, PackedCol col,
|
||||
Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2);
|
||||
|
||||
IGameComponent Selections_MakeComponent(void);
|
||||
void Selections_Render(Real64 delta);
|
||||
void Selections_Add(UInt8 id, Vector3I p1, Vector3I p2, PackedCol col);
|
||||
void Selections_Remove(UInt8 id);
|
||||
#endif
|
@ -151,15 +151,15 @@ void WeatherRenderer_Render(Real64 deltaTime) {
|
||||
Real32 x1 = (Real32)x, y1 = (Real32)y, z1 = (Real32)z;
|
||||
Real32 x2 = (Real32)(x + 1), y2 = (Real32)(y + height), z2 = (Real32)(z + 1);
|
||||
|
||||
v.X = x1; v.Y = y1; v.Z = z1; v.U = 0.0f; v.V = v1; *ptr = v; ptr++;
|
||||
v.Y = y2; v.V = v2; *ptr = v; ptr++;
|
||||
v.X = x2; v.Z = z2; v.U = 1.0f; *ptr = v; ptr++;
|
||||
v.Y = y1; v.V = v1; *ptr = v; ptr++;
|
||||
v.X = x1; v.Y = y1; v.Z = z1; v.U = 0.0f; v.V = v1; *ptr++ = v;
|
||||
v.Y = y2; v.V = v2; *ptr++ = v;
|
||||
v.X = x2; v.Z = z2; v.U = 1.0f; *ptr++ = v;
|
||||
v.Y = y1; v.V = v1; *ptr++ = v;
|
||||
|
||||
v.Z = z1; *ptr = v; ptr++;
|
||||
v.Y = y2; v.V = v2; *ptr = v; ptr++;
|
||||
v.X = x1; v.Z = z2; v.U = 0.0f; *ptr = v; ptr++;
|
||||
v.Y = y1; v.V = v1; *ptr = v; ptr++;
|
||||
v.Z = z1; *ptr++ = v;
|
||||
v.Y = y2; v.V = v2; *ptr++ = v;
|
||||
v.X = x1; v.Z = z2; v.U = 0.0f; *ptr++ = v;
|
||||
v.Y = y1; v.V = v1; *ptr++ = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1993,7 +1993,7 @@ Int32 PlayerListWidget_GetGroupCount(PlayerListWidget* widget, UInt16 id, Int32
|
||||
Int32 PlayerListWidget_PlayerCompare(UInt16 x, UInt16 y) {
|
||||
UInt8 xRank = TabList_GroupRanks[x];
|
||||
UInt8 yRank = TabList_GroupRanks[y];
|
||||
if (xRank != yRank) return (xRank < yRank ? 1 : -1);
|
||||
if (xRank != yRank) return (xRank < yRank ? -1 : 1);
|
||||
|
||||
UInt8 xNameBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String xName = String_InitAndClearArray(xNameBuffer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user