Add project files.
This commit is contained in:
commit
a9ae435321
52 files changed
+65378
No files matched your search
@@ -0,0 +1,117 @@
|
||||
// Minimal raylib viewer: shows how little code it takes to use a Hammer++ map in another app.
|
||||
// hmap_viewer [file.hmap] WASD + mouse (hold right button) to fly, Shift = fast
|
||||
//
|
||||
// Everything map-related is: loadCompiled() -> iterate batches -> trace()/pointContents().
|
||||
// Baked vertex lighting is already in Vertex::color, which raylib's default shader multiplies in.
|
||||
#include <hmap/hmap.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h" // MatrixIdentity
|
||||
|
||||
struct GpuBatch {
|
||||
Mesh mesh;
|
||||
int material;
|
||||
};
|
||||
|
||||
static Mesh toRaylib(const hmap::Batch& b) {
|
||||
Mesh m = {};
|
||||
size_t n = b.indices.size(); // expand to a non-indexed triangle list (no 16-bit index limit)
|
||||
m.vertexCount = (int)n;
|
||||
m.triangleCount = (int)(n / 3);
|
||||
m.vertices = (float*)MemAlloc((unsigned)(n * 3 * sizeof(float)));
|
||||
m.texcoords = (float*)MemAlloc((unsigned)(n * 2 * sizeof(float)));
|
||||
m.normals = (float*)MemAlloc((unsigned)(n * 3 * sizeof(float)));
|
||||
m.colors = (unsigned char*)MemAlloc((unsigned)(n * 4));
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
const hmap::Vertex& v = b.vertices[b.indices[i]];
|
||||
m.vertices[i * 3 + 0] = v.pos.x; m.vertices[i * 3 + 1] = v.pos.y; m.vertices[i * 3 + 2] = v.pos.z;
|
||||
m.normals[i * 3 + 0] = v.normal.x; m.normals[i * 3 + 1] = v.normal.y; m.normals[i * 3 + 2] = v.normal.z;
|
||||
m.texcoords[i * 2 + 0] = v.uv.x; m.texcoords[i * 2 + 1] = v.uv.y;
|
||||
m.colors[i * 4 + 0] = (unsigned char)(v.color & 0xff);
|
||||
m.colors[i * 4 + 1] = (unsigned char)((v.color >> 8) & 0xff);
|
||||
m.colors[i * 4 + 2] = (unsigned char)((v.color >> 16) & 0xff);
|
||||
m.colors[i * 4 + 3] = (unsigned char)((v.color >> 24) & 0xff);
|
||||
}
|
||||
UploadMesh(&m, false);
|
||||
return m;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
const char* path = argc > 1 ? argv[1] : "demo_runtime.hmap";
|
||||
hmap::CompiledMap map;
|
||||
hmap::Status st = hmap::loadCompiled(path, map); // works for source, compiled and mixed files
|
||||
if (!st) {
|
||||
std::fprintf(stderr, "cannot load %s: %s\n", path, st.message.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
InitWindow(1280, 720, "hmap viewer");
|
||||
SetTargetFPS(120);
|
||||
|
||||
std::vector<GpuBatch> gpu;
|
||||
for (const hmap::Batch& b : map.batches)
|
||||
if (!b.indices.empty()) gpu.push_back({toRaylib(b), b.material});
|
||||
Material mat = LoadMaterialDefault();
|
||||
|
||||
hmap::Vec3 pos(0, 100, 300);
|
||||
float yaw = 0, pitch = 0;
|
||||
for (const hmap::Entity& e : map.entities)
|
||||
if (e.classname == "info_player_start") { pos = e.origin + hmap::Vec3(0, 40, 0); yaw = e.angles.y; }
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
float dt = GetFrameTime();
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) {
|
||||
Vector2 d = GetMouseDelta();
|
||||
yaw -= d.x * 0.15f;
|
||||
pitch = std::fmax(-89.0f, std::fmin(89.0f, pitch - d.y * 0.15f));
|
||||
}
|
||||
float cy = std::cos(yaw * hmap::kDeg2Rad), sy = std::sin(yaw * hmap::kDeg2Rad);
|
||||
float cp = std::cos(pitch * hmap::kDeg2Rad), sp = std::sin(pitch * hmap::kDeg2Rad);
|
||||
hmap::Vec3 fwd(-sy * cp, sp, -cy * cp), right(cy, 0, -sy);
|
||||
float speed = (IsKeyDown(KEY_LEFT_SHIFT) ? 900.0f : 300.0f) * dt;
|
||||
hmap::Vec3 move;
|
||||
if (IsKeyDown(KEY_W)) move += fwd;
|
||||
if (IsKeyDown(KEY_S)) move -= fwd;
|
||||
if (IsKeyDown(KEY_D)) move += right;
|
||||
if (IsKeyDown(KEY_A)) move -= right;
|
||||
hmap::Vec3 next = pos + hmap::normalize(move) * speed;
|
||||
// collide against the BSP: stop at walls
|
||||
if (!map.trace(pos, next + hmap::normalize(move) * 12.0f).hit) pos = next;
|
||||
|
||||
hmap::TraceResult aim = map.trace(pos, pos + fwd * 4000.0f); // "what am I looking at?"
|
||||
|
||||
Camera3D cam = {};
|
||||
cam.position = {pos.x, pos.y, pos.z};
|
||||
cam.target = {pos.x + fwd.x, pos.y + fwd.y, pos.z + fwd.z};
|
||||
cam.up = {0, 1, 0};
|
||||
cam.fovy = 70;
|
||||
cam.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground({24, 26, 32, 255});
|
||||
BeginMode3D(cam);
|
||||
for (const GpuBatch& g : gpu) {
|
||||
const hmap::Material& hm = map.materials[(size_t)g.material];
|
||||
mat.maps[MATERIAL_MAP_DIFFUSE].color = {(unsigned char)(hm.color.x * 255), (unsigned char)(hm.color.y * 255),
|
||||
(unsigned char)(hm.color.z * 255), 255};
|
||||
DrawMesh(g.mesh, mat, MatrixIdentity());
|
||||
}
|
||||
for (const hmap::Entity& e : map.entities)
|
||||
DrawCubeWires({e.origin.x, e.origin.y, e.origin.z}, 12, 12, 12, e.classname.rfind("light", 0) == 0 ? YELLOW : SKYBLUE);
|
||||
if (aim.hit) DrawSphere({aim.point.x, aim.point.y, aim.point.z}, 3, RED);
|
||||
EndMode3D();
|
||||
DrawText(TextFormat("%s | %d batches %u tris | aim: %s | %d fps", path, (int)gpu.size(), map.stats.triangles,
|
||||
aim.hit ? TextFormat("%.0f units", aim.fraction * 4000.0f) : "nothing", GetFPS()),
|
||||
10, 10, 18, RAYWHITE);
|
||||
EndDrawing();
|
||||
}
|
||||
for (GpuBatch& g : gpu) UnloadMesh(g.mesh);
|
||||
MemFree(mat.maps);
|
||||
CloseWindow();
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user