1 /*
2     Inochi2D Part extended with layer information
3 
4     Copyright © 2020, Inochi2D Project
5     Distributed under the 2-Clause BSD License, see LICENSE file.
6     
7     Authors: Luna Nielsen
8 */
9 module creator.ext.nodes.excamera;
10 import inochi2d.core.nodes.part;
11 import inochi2d.core.nodes;
12 import inochi2d.core;
13 import inochi2d.fmt.serialize;
14 import std.stdio : writeln;
15 import inochi2d.math;
16 import inochi2d.core.dbg;
17 
18 @TypeId("Camera")
19 class ExCamera : Node {
20 protected:
21     vec2 viewport = vec2(1920, 1080);
22 
23     override
24     void serializeSelf(ref InochiSerializer serializer) {
25         super.serializeSelf(serializer);
26         serializer.putKey("viewport");
27         serializer.serializeValue(viewport.vector);
28     }
29 
30     override
31     SerdeException deserializeFromFghj(Fghj data) {
32         auto err = super.deserializeFromFghj(data);
33         if (err) return err;
34 
35         if (!data["viewport"].isEmpty) data["viewport"].deserializeValue(viewport.vector);
36         return null;
37     }
38 
39     override
40     string typeId() {
41         return "Camera";
42     }
43 
44     /**
45         Initial bounds size
46     */
47     override
48     vec4 getInitialBoundsSize() {
49         auto tr = transform;
50         auto vpHalfSize = (viewport/2)*transform.scale;
51         vec3 topLeft = vec3(
52             tr.translation.x-vpHalfSize.x, 
53             tr.translation.y-vpHalfSize.y,
54             0
55         );
56         vec3 bottomRight = vec3(
57             tr.translation.x+vpHalfSize.x, 
58             tr.translation.y+vpHalfSize.y,
59             0
60         );
61 
62         return vec4(topLeft.xy, bottomRight.xy);
63     }
64 
65     override
66     void drawBounds() {
67         auto tr = transform;
68         auto vpHalfSize = viewport/2;
69 
70         vec3 topLeft = vec3(-vpHalfSize.x, -vpHalfSize.y, 0);
71         vec3 bottomRight = vec3(+vpHalfSize.x, +vpHalfSize.y, 0);
72         vec3 topRight = vec3(bottomRight.x, topLeft.y, 0);
73         vec3 bottomLeft = vec3(topLeft.x, bottomRight.y, 0);
74 
75         inDbgSetBuffer([
76             topLeft, topRight,
77             topRight, bottomRight,
78             bottomRight, bottomLeft,
79             bottomLeft, topLeft
80         ]);
81 
82         inDbgLineWidth(2);
83         inDbgDrawLines(vec4(0, 0, 0, 1), transform.matrix);
84         inDbgLineWidth(1);
85         inDbgDrawLines(vec4(1, 1, 1, 1), transform.matrix);
86     }
87 
88 public:
89     this() { super(); }
90     this(Node parent) { super(parent); }
91     this(vec2 viewport) { 
92         super();
93         this.viewport = viewport;
94     }
95 
96     /**
97         Gets Inochi2D camera for this camera
98     */
99     Camera getCamera() {
100         vec2 scale = transform().scale;
101 
102         Camera cam = new Camera();
103         cam.position = transform().translation.xy*vec2(-1, -1);
104         cam.rotation = -transform().rotation.z;
105         cam.scale = vec2(1/scale.x, 1/scale.y);
106         return cam;
107     }
108 
109     /**
110         Gets the viewport for this camera
111     */
112     ref vec2 getViewport() {
113         return viewport;
114     }
115 
116 }
117 
118 void incRegisterExCamera() {
119     inRegisterNodeType!ExCamera();
120 }