mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-26 04:30:52 +00:00
Add support for points in wireframe meshes
This allows rendering of a vertex directly, rather than just as an edge endpoint. They're currently drawn as small '+' signs. A round dot would be better, but the code is passing a list of line segments around, so this is simpler.
This commit is contained in:
parent
a42584834b
commit
df823f4c09
@ -19,7 +19,8 @@ using System.Diagnostics;
|
||||
namespace CommonUtil {
|
||||
public class RawData {
|
||||
/// <summary>
|
||||
/// Extracts an integer from the data stream.
|
||||
/// Extracts an integer from the data stream. Integers less than 4 bytes wide
|
||||
/// are not sign-extended.
|
||||
/// </summary>
|
||||
/// <param name="data">Raw data stream.</param>
|
||||
/// <param name="offset">Start offset.</param>
|
||||
|
@ -327,20 +327,24 @@ namespace PluginCommon {
|
||||
/// <summary>
|
||||
/// Holds raw vertex/edge/normal data collected from a 2D or 3D wireframe mesh. We use
|
||||
/// a left-handed coordinate system (+Z goes into the screen). If the project being
|
||||
/// disassembled uses different definitions for the axes, it's probably best to convert.
|
||||
/// 2D data should use X/Y with Z=0.
|
||||
/// disassembled uses different definitions for the axes, it's probably best to convert
|
||||
/// them in the visualizer. 2D data should use X/Y with Z=0.
|
||||
///
|
||||
/// All objects will have vertices and edges. Face normals are optional.
|
||||
/// All objects will have vertices. Most will have edges, some will have points. Face
|
||||
/// normals are optional.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The face-normal stuff is designed specifically for Elite. Besides being one of the
|
||||
/// very few 6502-based games to use backface culling, it extended the concept to allow
|
||||
/// convex shapes to have protrusions.
|
||||
///
|
||||
/// Points are included primarily for the benefit of AVG games like Battlezone.
|
||||
///
|
||||
/// We favor multiple arrays over compound objects for this interface to avoid making
|
||||
/// such objects part of the plugin interface.
|
||||
///
|
||||
/// TODO(maybe): specify colors for edges. Not widely used?
|
||||
/// TODO(maybe): specify colors for points and edges. Not widely used? Could be handy for
|
||||
/// color AVG games like Tempest.
|
||||
/// </remarks>
|
||||
public interface IVisualizationWireframe {
|
||||
// Each function returns the specified data. Do not modify the returned arrays.
|
||||
@ -349,6 +353,7 @@ namespace PluginCommon {
|
||||
float[] GetVerticesY();
|
||||
float[] GetVerticesZ();
|
||||
|
||||
int[] GetPoints();
|
||||
IntPair[] GetEdges();
|
||||
|
||||
float[] GetNormalsX();
|
||||
|
@ -28,7 +28,8 @@ namespace PluginCommon {
|
||||
/// </summary>
|
||||
public static class Util {
|
||||
/// <summary>
|
||||
/// Extracts an integer from the data stream.
|
||||
/// Extracts an integer from the data stream. Integers shorter than 4 bytes are
|
||||
/// not sign-extended.
|
||||
/// </summary>
|
||||
/// <param name="data">Raw data stream.</param>
|
||||
/// <param name="offset">Start offset.</param>
|
||||
|
@ -39,6 +39,7 @@ namespace PluginCommon {
|
||||
private List<float> mVerticesY = new List<float>();
|
||||
private List<float> mVerticesZ = new List<float>();
|
||||
|
||||
private List<int> mPoints = new List<int>();
|
||||
private List<IntPair> mEdges = new List<IntPair>();
|
||||
|
||||
private List<float> mNormalsX = new List<float>();
|
||||
@ -72,6 +73,16 @@ namespace PluginCommon {
|
||||
return mVerticesX.Count - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a point to the list.
|
||||
/// </summary>
|
||||
/// <param name="index">Vertex index.</param>
|
||||
/// <returns>Point index. Indices start at zero and count up.</returns>
|
||||
public int AddPoint(int index) {
|
||||
mPoints.Add(index);
|
||||
return mPoints.Count - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an edge to the list. The referenced vertices do not need to be defined
|
||||
/// before calling.
|
||||
@ -172,6 +183,14 @@ namespace PluginCommon {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check points
|
||||
foreach (int vi in mPoints) {
|
||||
if (vi < 0 || vi >= vertexCount) {
|
||||
msg = "invalid point (index=" + vi + "; count=" + vertexCount + ")";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check edges
|
||||
foreach (IntPair ip in mEdges) {
|
||||
if (ip.Val0 < 0 || ip.Val0 >= vertexCount ||
|
||||
@ -248,6 +267,10 @@ namespace PluginCommon {
|
||||
return mVerticesZ.ToArray();
|
||||
}
|
||||
|
||||
public int[] GetPoints() {
|
||||
return mPoints.ToArray();
|
||||
}
|
||||
|
||||
public IntPair[] GetEdges() {
|
||||
return mEdges.ToArray();
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ namespace SourceGen {
|
||||
}
|
||||
|
||||
private List<Vertex> mVertices = new List<Vertex>();
|
||||
private List<Vertex> mPoints = new List<Vertex>();
|
||||
private List<Edge> mEdges = new List<Edge>();
|
||||
private List<Face> mFaces = new List<Face>();
|
||||
private double mBigMag = -1.0;
|
||||
@ -105,7 +106,8 @@ namespace SourceGen {
|
||||
|
||||
//
|
||||
// Start by extracting data from the visualization object. Everything stored
|
||||
// there is loaded into this object.
|
||||
// there is loaded into this object. The VisWireframe validator will have
|
||||
// ensured that all the indices are in range.
|
||||
//
|
||||
|
||||
float[] normalsX = visWire.GetNormalsX();
|
||||
@ -141,6 +143,11 @@ namespace SourceGen {
|
||||
HasIndex(excludedVertices, i)));
|
||||
}
|
||||
|
||||
int[] points = visWire.GetPoints();
|
||||
for (int i = 0; i < points.Length; i++) {
|
||||
wireObj.mPoints.Add(wireObj.mVertices[i]);
|
||||
}
|
||||
|
||||
IntPair[] edges = visWire.GetEdges();
|
||||
int[] excludedEdges = visWire.GetExcludedEdges();
|
||||
for (int i = 0; i < edges.Length; i++) {
|
||||
@ -229,7 +236,8 @@ namespace SourceGen {
|
||||
/// <param name="doPersp">Perspective or othographic projection?</param>
|
||||
/// <param name="doBfc">Perform backface culling?</param>
|
||||
/// <returns>List a of line segments, which could be empty if backface culling
|
||||
/// was especially successful.</returns>
|
||||
/// was especially successful. All segment coordinates are in the range
|
||||
/// [-1,1].</returns>
|
||||
public List<LineSeg> Generate(int eulerX, int eulerY, int eulerZ,
|
||||
bool doPersp, bool doBfc) {
|
||||
List<LineSeg> segs = new List<LineSeg>(mEdges.Count);
|
||||
@ -293,6 +301,29 @@ namespace SourceGen {
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Vertex point in mPoints) {
|
||||
// There are no "point faces" at the moment, so no BFC is applied.
|
||||
Vector3 trv = rotMat.Multiply(point.Vec);
|
||||
double xc, yc;
|
||||
if (doPersp) {
|
||||
double zc = trv.Z * scale;
|
||||
xc = (trv.X * scale * zadj) / (zadj + zc);
|
||||
yc = (trv.Y * scale * zadj) / (zadj + zc);
|
||||
} else {
|
||||
xc = trv.X * scale;
|
||||
yc = trv.Y * scale;
|
||||
}
|
||||
|
||||
// Zero-length line segments don't do anything. Try a '+'.
|
||||
const double dist = 1 / 64.0;
|
||||
double x0 = Math.Max(-1.0, xc - dist);
|
||||
double x1 = Math.Min(xc + dist, 1.0);
|
||||
segs.Add(new LineSeg(x0, yc, x1, yc));
|
||||
double y0 = Math.Max(-1.0, yc - dist);
|
||||
double y1 = Math.Min(yc + dist, 1.0);
|
||||
segs.Add(new LineSeg(xc, y0, xc, y1));
|
||||
}
|
||||
|
||||
foreach (Edge edge in mEdges) {
|
||||
if (doBfc) {
|
||||
// To be visible, vertices and edges must either not specify any
|
||||
|
Loading…
Reference in New Issue
Block a user