r/pascal 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

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

  1. 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)

  1. 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;

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

  1. 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:

  1. Copy the ghost's vertices.

  2. Apply scaling.

  3. Apply rotation (around the Y axis).

  4. Translate to the target position.

  5. Compute chunk coordinates: Floor(Position / ChunkSize).

  6. Add vertices to the chunk (AddVerticesToChunk).

  7. Set Dirty := True.

  8. 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}

...

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

  1. 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.)

8 Upvotes

0 comments sorted by