-
Notifications
You must be signed in to change notification settings - Fork 5
/
Prop2D.h
344 lines (297 loc) · 8.73 KB
/
Prop2D.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#pragma once
#include "common.h"
#include "Grid.h"
#include "Renderable.h"
#include "PrimDrawer.h"
#include "Layer.h"
#include "DrawBatch.h"
#include "Remote.h"
class AnimCurve;
class FragmentShader;
class Prop2D : public Prop, public Renderable {
public:
Vec2 loc;
Vec2 draw_offset;
Vec2 scl;
static const int MAX_GRID = 8;
Grid *grids[MAX_GRID]; // Set from the top and quit when null found
int grid_used_num;
Color color;
Prop2D *children[CHILDREN_ABS_MAX];
int children_num;
AnimCurve *anim_curve;
double anim_start_at; // from accum_time
bool xflip, yflip, uvrot;
FragmentShader *fragment_shader;
// scale anim
double seek_scl_time; // 0:not seeking
double seek_scl_started_at;
Vec2 seek_scl_target;
Vec2 seek_scl_orig;
float rot;
// rot anim
double seek_rot_time;
double seek_rot_started_at;
float seek_rot_target;
float seek_rot_orig;
// color anim
double seek_color_time;
double seek_color_started_at;
Color seek_color_target;
Color seek_color_orig;
PrimDrawer *prim_drawer;
// prop-size cache for fast culling
Vec2 max_rt_cache, min_lb_cache;
bool render_children_first;
bool use_additive_blend;
static VertexFormat *vf_single_sprite;
Tracker2D *tracker;
bool copy_mesh_at_draw;
// location sync skipping based on scoring
float loc_sync_score;
bool loc_changed;
LOCSYNCMODE locsync_mode;
Vec2 remote_vel;
int target_client_id; // >0 if used
float uv_margin;
int render_count;
static FragmentShader *default_fs;
Prop2D() : Prop(), Renderable() {
init();
}
Prop2D(Deck *dk, int index,Vec2 scl,Vec2 loc) : Prop(), Renderable() {
init();
setDeck(dk);
setIndex(index);
setScl(scl);
setLoc(loc);
}
void init() {
priority = id;
dimension = DIMENSION_2D;
color = Color(1,1,1,1);
children_num = 0;
loc.x = loc.y = 0;
draw_offset.x = draw_offset.y = 0;
scl.x = scl.y = 32;
anim_curve = NULL;
anim_start_at = 0;
grid_used_num = 0;
xflip = yflip = uvrot = false;
rot = 0;
seek_scl_time = seek_scl_started_at = 0;
seek_rot_time = seek_rot_started_at = 0;
seek_color_time = seek_color_started_at = 0;
fragment_shader = NULL;
prim_drawer = NULL;
max_rt_cache = Vec2(0,0);
min_lb_cache = Vec2(0,0);
render_children_first = false;
use_additive_blend = false;
tracker = NULL;
copy_mesh_at_draw = false; // set true for drawDBL
loc_sync_score = 0;
loc_changed=true;
locsync_mode = LOCSYNCMODE_DEFAULT;
target_client_id = 0;
uv_margin=0;
render_count=0;
}
virtual ~Prop2D(){
for(int i=0;i<grid_used_num;i++){
if(grids[i]) delete grids[i];
}
for(int i=0;i<children_num;i++){
if(children[i]) delete children[i];
}
if(prim_drawer) delete prim_drawer;
if(tracker) delete tracker;
}
virtual bool prop2DPoll(double dt){ return true;}
virtual bool propPoll(double dt);
virtual void onAnimFinished(){}
inline void setIndex( int ind){
index = ind;
}
inline void setScl(Vec2 s){
scl = s;
}
inline void setScl(float s) { scl.x = scl.y = s; }
inline void setScl(float x, float y ){
scl.x = x;
scl.y = y;
}
inline void seekScl(float x, float y, double time_sec ){
seek_scl_orig = scl;
seek_scl_started_at = accum_time;
seek_scl_time = time_sec;
seek_scl_target = Vec2(x,y);
}
inline bool isSeekingScl(){ return seek_scl_time != 0 && ( seek_scl_time + seek_scl_started_at > accum_time ); }
inline void setLoc( Vec2 p){
loc = p;
}
inline void setLoc( float x, float y ){
loc.x = x;
loc.y = y;
}
inline void setRot( float r ){ rot = r; }
inline void seekRot( float r, double time_sec ){
seek_rot_orig = rot;
seek_rot_started_at = accum_time;
seek_rot_time = time_sec;
seek_rot_target = r;
}
inline bool isSeekingRot(){ return seek_rot_time != 0 && (seek_rot_time + seek_rot_started_at > accum_time); }
inline bool addGrid( Grid *g ){
assert(g);
if( grid_used_num >= elementof(grids) ){
print("WARNING: too many grid in a prop");
return false;
}
grids[grid_used_num++] = g;
updateMinMaxSizeCache();
return true;
}
// Make sure set only one grid even when called many times
inline bool setGrid( Grid *g ) {
for(int i=0;i<grid_used_num;i++) {
if( grids[i] == g ) return false;
}
return addGrid(g);
}
inline Grid* getGrid(int index) {
assert(index>=0 && index < elementof(grids) ) ;
return grids[index];
}
inline void clearGrid() {
grid_used_num = 0; // object have to be freed by app
updateMinMaxSizeCache();
}
inline bool addChild( Prop2D *p ){
assert(p);
if( children_num >= elementof(children) ) {
assertmsg(false,"WARNING: too many children in a prop");
return false;
}
children[children_num++] = p;
updateMinMaxSizeCache();
return true;
}
inline Prop2D *getChild( int child_prop_id ) {
for(int i=0;i<children_num;i++) {
Prop2D *chp = (Prop2D*)children[i];
if( chp->id == child_prop_id ) {
return chp;
}
}
return NULL;
}
void clearChildren();
bool clearChild( Prop2D *p );
inline void setColor( Color c ){
color = c;
onColorChanged();
}
inline Color getColor() { return color; }
inline void setColor(float r, float g, float b, float a ){
setColor(Color(r,g,b,a));
}
inline void seekColor( Color c, double time_sec ) {
seek_color_orig = color;
seek_color_started_at = accum_time;
seek_color_time = time_sec;
seek_color_target = c;
}
inline bool isSeekingColor(){ return seek_color_time != 0 && (seek_color_time + seek_color_started_at > accum_time); }
inline void setAnim(AnimCurve *ac ){
assert(ac);
anim_curve = ac;
anim_start_at = accum_time;
}
inline void clearAnim() {
anim_curve = NULL;
}
inline void ensureAnim( AnimCurve *ac ) {
if( anim_curve != ac ) setAnim(ac);
}
inline void setUVRot( bool flg){ uvrot = flg; }
inline void setXFlip( bool flg){ xflip = flg; }
inline void setYFlip( bool flg){ yflip = flg; }
virtual void onIndexChanged(int previndex ){}
virtual void onColorChanged(){}
inline void setFragmentShader( FragmentShader *fs ){
fragment_shader = fs;
}
Prop *getNearestProp();
inline void ensurePrimDrawer(){
if(!prim_drawer ) prim_drawer = new PrimDrawer();
}
inline Prim *addLine(Vec2 from, Vec2 to, Color c, int width=1 ){
ensurePrimDrawer();
Prim *p = prim_drawer->addLine( from, to, c, width );
updateMinMaxSizeCache();
return p;
}
inline Prim *addRect( Vec2 from, Vec2 to, Color c ){
ensurePrimDrawer();
Prim *p = prim_drawer->addRect( from, to, c );
updateMinMaxSizeCache();
return p;
}
inline void clearPrims(){
if(prim_drawer)prim_drawer->clear();
}
inline int getPrimNum() {
if(prim_drawer) return prim_drawer->prim_num; else return 0;
}
inline Prim* getPrim(int index) { return prim_drawer->prims[index]; }
inline bool isCenterInside(Vec2 minloc, Vec2 maxloc){
return ( loc.x >= minloc.x && loc.x <= maxloc.x && loc.y >= minloc.y && loc.y <= maxloc.y );
}
void updateMinMaxSizeCache();
BLENDTYPE getBlendType() {
if( use_additive_blend ) return BLENDTYPE_ADD; else return BLENDTYPE_SRC_ALPHA;
}
inline bool hit( Vec2 at, float margin = 0 ){
return ( at.x >= loc.x - scl.x/2 - margin ) && ( at.x <= loc.x + scl.x/2 + margin) &&
( at.y >= loc.y - scl.y/2 - margin) && ( at.y <= loc.y + scl.y/2 + margin );
}
bool hitGrid(Vec2 at, float margin = 0);
virtual void render(Camera *cam, DrawBatchList *bl);
inline void getRect( Vec2 *min_out, Vec2 *max_out ) {
min_out->x = loc.x - scl.x/2;
min_out->y = loc.y - scl.y/2;
max_out->x = loc.x + scl.x/2;
max_out->y = loc.y + scl.y/2;
}
inline Vec2 getBottomLeft() {
if( grid_used_num > 0 ) return loc; else return loc - scl/2;
}
inline Layer *getParentLayer() {
return (Layer*) parent_group;
}
inline Viewport *getViewport() {
return getParentLayer()->viewport;
}
virtual void onTrack( RemoteHead *rh, Prop2D *parentprop );
Prim *getPrimById( int prim_id ) {
if( prim_drawer ) {
return prim_drawer->getPrimById(prim_id);
} else {
return NULL;
}
}
void deletePrim( int prim_id ) {
if( prim_drawer ) prim_drawer->deletePrim(prim_id);
}
static void drawToDBL( Layer *l, DrawBatchList *bl,FragmentShader *fs, bool additive_blend, Deck *dk, int index, Color col, Vec2 loc, Vec2 scl, float rot );
void setLocSyncMode(LOCSYNCMODE mode ) { locsync_mode = mode; }
bool isInView( Vec2 *minv, Vec2 *maxv, Camera *cam );
void setTargetClient( Client *cl ) {
target_client_id = cl->id;
for(int i=0;i<children_num;i++) {
children[i]->setTargetClient(cl);
}
}
};