1 module isodi.properties;
2 
3 import raylib;
4 
5 import std.math;
6 import std.typecons;
7 
8 import isodi.resources;
9 
10 private alias PI = std.math.PI;
11 
12 
13 @safe:
14 
15 
16 /// Properties used to render the object.
17 struct Properties {
18 
19     /// Number of steps for height — this number of height steps results in height difference equivalent to the distance
20     /// between two neighboring blocks (of the same height).
21     int heightSteps = 10;
22 
23     /// Perspective of the viewer, used to correctly render models and other flat objects.
24     const(Perspective)* perspective;
25 
26     /// Transform matrix affecting the object.
27     Matrix transform = Matrix(
28         1, 0, 0, 0,
29         0, 1, 0, 0,
30         0, 0, 1, 0,
31         0, 0, 0, 1,
32     );
33 
34     /// Resource loader to be used by this object.
35     Rebindable!(const ResourceLoader) resources;
36 
37     /// Value each color channel will be multiplied by. (1, 1, 1, 1) does no changes.
38     Vector4 tint = Vector4(1, 1, 1, 1);
39 
40 }
41 
42 struct Perspective {
43 
44     /// Perspective angles, in radians.
45     float angleX, angleY;
46 
47     /// Update the perspective based on camera properties.
48     void fromCamera(Camera3D camera) {
49 
50         const pos = camera.target - camera.position;
51 
52         const sine = Vector2(
53             pos.x / sqrt(pos.x^^2 + pos.z^^2),
54             pos.x / sqrt(pos.x^^2 + pos.y^^2),
55         );
56 
57         // Set the angles
58         angleX = sgn(pos.z) * acos(sine.x) - PI_2;
59         angleY = PI_2 - sgn(pos.x) * asin(sine.y);
60 
61     }
62 
63 }