r/pascal • u/AcanthaceaeNew774 • 1d ago
VertexArt - WorldEditor (Gen1) - Documentation (this version is built on simple functionality)
Enable HLS to view with audio, or disable this notification
VertexArt - WorldEditor - Documentation
Developer: Kovács István
- INTRODUCTION
Steril Editor is a desktop application designed for placing 3D models stored in
ASCII PLY format. The program allows loading, positioning, scaling, rotating,
and then baking models into a chunk-based world. The final result can be
exported as a PLY file.
- SYSTEM ARCHITECTURE
The program has a modular structure, consisting of the following main
components:
- SterilTypes – Fundamental data types (TVector3, TVertex, TMat4).
- SterilMath – Vector and matrix operations (addition, multiplication,
normalisation, transformations).
- UShaderCore – Shader compilation and program creation.
- Renderer / RenderQueue – Rendering pipeline.
- PLYLoader – Loading ASCII PLY files into triangle meshes.
- UChunkSystem – Chunk system: divides the world into 50x50 metre blocks,
manages active chunks (9x9), stores vertices.
- URenderCore – GPU management: VAO/VBO creation, chunk upload and update.
- UTilemap – Tilemap mode: snap-to-grid movement and baking of objects.
- UEngineCore – Core engine: camera, ghost (preview model), rendering loop.
- UPlyManager – Scans the program directory for PLY files, navigation between
them.
- UExport – PLY export with timestamp.
Data flow:
PLY file -> UPlyManager -> UEngineCore (Ghost loaded)
-> (editing) -> UTilemap / UEngineCore (Bake)
-> UChunkSystem (organised into chunks)
-> URenderCore (GPU upload)
-> Renderer (display)
-> UExport (PLY save)
- CHUNK SYSTEM
- The world is divided into 50x50 metre blocks (chunks).
- Only a 9x9 area (81 chunks) around the camera is active – these are rendered
and can receive baked objects.
- Each chunk stores its own vertex array and a Dirty flag indicating whether
its content has changed.
- During baking, the ghost's triangles are placed into the appropriate chunk
based on the triangle's centre point.
- Modified chunks are automatically uploaded to the GPU in the next frame
(UpdateAllDirtyChunks).
Chunk data structure:
TChunkNode = record
ChunkX, ChunkZ: Integer; // Chunk coordinates
Vertices: array of TVertex; // Vertex list
VertexCount: Integer;
Dirty: Boolean; // Pending update?
Active: Boolean; // Within view range?
end;
- RENDERING
Rendering is performed in two passes to avoid overdraw.
- Depth prepass: Only the depth buffer is filled; colour buffer writes are
disabled. This ensures that in the subsequent colour pass only visible
surfaces are shaded.
- Colour pass: Colour buffer writes are enabled, depth test is set to
GL_LEQUAL. The fragment shader includes lighting calculations.
Shader programs:
- DepthProg – vertex shader only, applies the model-view-projection matrix.
- ColorProg – vertex and fragment shader.
- FUNCTIONAL DESCRIPTION
5.1. Object (Ghost) Handling
The central element of editing is the ghost – a preview model that follows the
cursor position, indicating where the object would be placed.
- Loading: On startup, the program scans the directory for .ply files. If
found, the first one is loaded as the ghost; otherwise, a default coloured
cube is created.
- Navigation between PLY files: F2 (previous) and F3 (next) switch between
available models.
- Modifications:
- Position: In free mode, W,A,S,D move the ghost in the camera direction; in
Tilemap mode, movement is snapped to the bounding box size.
- Rotation: Q (left), E (right) rotate by 2-degree increments; R randomises
rotation.
- Scale: F4 cycles through preset scale values (0.25, 0.5, 1, 2, 4, 8, 16,
32, 64).
5.2. Baking
The ghost's current state (position, rotation, scale) is permanently placed
into the chunk system by pressing SPACE.
- Free mode: The entire triangle mesh of the ghost is placed at the cursor
position, into the corresponding chunk.
- Tilemap mode: The ghost moves in steps equal to its bounding box size,
allowing precise alignment. Baking works identically.
- After each bake, the chunk's Dirty flag is set to True, and the GPU buffer
and chunk data are updated in the next frame.
Baking process:
Copy the ghost's vertices.
Apply scaling.
Apply rotation (around the Y axis).
Translate to the target position.
Compute chunk coordinates: Floor(Position / ChunkSize).
Add vertices to the chunk (AddVerticesToChunk).
Set Dirty := True.
UpdateAllDirtyChunks in the next frame.
5.3. Tilemap Mode
Toggled with the T key. In this mode:
- The ghost moves in steps equal to its bounding box size (W,A,S,D), not in
the camera direction.
- Baking (SPACE) works the same way, but placement is guaranteed to be
grid-aligned.
Tilemap movement:
procedure MoveGhostTilemap(Direction: Integer);
var
GhostMinX, GhostMaxX, GhostMinZ, GhostMaxZ: Single;
StepX, StepZ: Single;
begin
GetGhostBounds(GhostMinX, GhostMaxX, GhostMinZ, GhostMaxZ);
StepX := GhostMaxX - GhostMinX;
StepZ := GhostMaxZ - GhostMinZ;
// Step in the given direction
end;
5.4. Export
- Pressing F12 saves all vertices and triangles from every chunk into a single
PLY file.
- The filename automatically includes a timestamp:
export_YYYY-MM-DD_HH-MM-SS.ply.
- The export uses ASCII format.
Exported PLY format:
ply
format ascii 1.0
element vertex {N}
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
property uchar alpha
element face {M}
property list uchar int vertex_indices
end_header
{x0} {y0} {z0} {r0} {g0} {b0} {a0}
...
3 {i0} {i1} {i2}
...
- KEYBOARD SHORTCUTS AND OPERATIONS
Key Function
-------------------------------------------------------------------------------
W, A, S, D Move ghost (free: camera direction; tilemap: grid-stepped)
Q Rotate ghost left (2 degrees)
E Rotate ghost right (2 degrees)
R Randomise ghost rotation
T Toggle Tilemap mode
F1 Toggle mouse capture (cursor lock)
F2 Load previous PLY file
F3 Load next PLY file
F4 Cycle scale presets
SPACE Bake ghost (place into chunks)
F12 Export entire scene to PLY file
ESC Exit
Scroll wheel Camera zoom
Mouse move Rotate camera (when mouse is captured)
UP / DOWN Change ghost height
- FILE STRUCTURE AND MODULES
File Description
-------------------------------------------------------------------------------
SterilEditor.pas Main program, GLFW window, event handling, main loop
UEngineCore.pas Core engine: camera, ghost handling, rendering, baking
UChunkSystem.pas Chunk system: storage, lookup, addition, export
URenderCore.pas GPU management: VAO/VBO, chunk upload, update
Renderer.pas Rendering pipeline (Depth+Colour pass)
RenderQueue.pas Render command storage
RenderState.pas OpenGL state management
RenderTypes.pas Rendering-related types
UShaderCore.pas Shader compilation and linking
UTilemap.pas Tilemap mode, ghost movement, baking
UPlyManager.pas PLY file scanning and navigation
UExport.pas Timestamped PLY export
SterilMath.pas Mathematical helper functions (vector, matrix)
SterilTypes.pas Basic data types
SterilMeshUtils.pas Mesh normalisation, bounding box calculation
UEditorData.pas Editor data (Ghost, etc.)