-
Notifications
You must be signed in to change notification settings - Fork 8
/
KinemeGLCubeStructurePatch.m
247 lines (218 loc) · 6.22 KB
/
KinemeGLCubeStructurePatch.m
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
#import <OpenGL/gl.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/CGLMacro.h>
#import "KinemeGLCubeStructurePatch.h"
@implementation KinemeGLCubeStructurePatch : QCPatch
+ (QCPatchExecutionMode)executionModeWithIdentifier:(id)fp8
{
return 1;
}
+ (BOOL)allowsSubpatchesWithIdentifier:(id)fp8
{
return NO;
}
+ (BOOL)isSafe
{
return YES;
}
- (id)initWithIdentifier:(id)fp8
{
self=[super initWithIdentifier:fp8];
if(self)
{
[inputDefaultSize setDoubleValue:0.1];
[inputColor1 setRed:0.7 green:0.4 blue:0.4 alpha:0.9];
[inputColor2 setRed:0.2 green:0.8 blue:0.6 alpha:0.75];
[inputDepth setIndexValue:1]; // set normal read/write depth testing
[inputBlending setIndexValue:3]; // set Alpha blend mode by default
[[self userInfo] setObject:@"Kineme GL Cube Structure" forKey:@"name"];
}
return self;
}
- (void)cleanup:(QCOpenGLContext *)context
{
CGLContextObj cgl_ctx = [context CGLContextObj];
if(cube)
{
glDeleteLists(cube, 1);
cube = 0;
}
}
- (BOOL)execute:(QCOpenGLContext *)context time:(double)time arguments:(NSDictionary *)arguments
{
unsigned int count;
CGFloat red, green, blue, alpha;
CGFloat dRed,dGreen,dBlue,dAlpha;
QCStructure *pointStruct = [inputPoints structureValue];
count = [pointStruct count];
if(!pointStruct)
return YES; // no points -- do nothing
if(count == 0)
return YES; // no points -- do nothing
if([inputDefaultSize doubleValue] <= 0.0)
return YES; // invisible -- do nothing
[inputColor1 getRed:&red green:&green blue:&blue alpha:&alpha];
[inputColor2 getRed:&dRed green:&dGreen blue:&dBlue alpha:&dAlpha];
/* CGLMacros use 'cgl_ctx' */
CGLContextObj cgl_ctx = [context CGLContextObj];
[inputBlending setOnOpenGLContext:context];
[inputDepth setOnOpenGLContext:context];
[inputCulling setOnOpenGLContext:context];
float cubeSize = [inputDefaultSize doubleValue] * 0.5f;
if(cube == 0 || [inputDefaultSize wasUpdated])
{
// (re)build display list
if(cube == 0)
cube = glGenLists(1);
GLfloat vec[8][3] =
{
{+cubeSize,+cubeSize,+cubeSize},//0
{+cubeSize,+cubeSize,-cubeSize},//1
{+cubeSize,-cubeSize,+cubeSize},//2
{+cubeSize,-cubeSize,-cubeSize},//3
{-cubeSize,+cubeSize,+cubeSize},//4
{-cubeSize,+cubeSize,-cubeSize},//5
{-cubeSize,-cubeSize,+cubeSize},//6
{-cubeSize,-cubeSize,-cubeSize}//7
};
static const GLfloat normals[6][3] =
{
{0,1,0},
{0,-1,0},
{0,0,1},
{0,0,-1},
{-1,0,0},
{1,0,0}
};
glNewList(cube, GL_COMPILE);
{
glBegin(GL_QUADS);
glNormal3fv(normals[0]);
glVertex3fv(vec[0]);
glVertex3fv(vec[1]);
glVertex3fv(vec[5]);
glVertex3fv(vec[4]);
// bottom
glNormal3fv(normals[1]);
glVertex3fv(vec[6]);
glVertex3fv(vec[7]);
glVertex3fv(vec[3]);
glVertex3fv(vec[2]);
// front
glNormal3fv(normals[2]);
glVertex3fv(vec[4]);
glVertex3fv(vec[6]);
glVertex3fv(vec[2]);
glVertex3fv(vec[0]);
// back
glNormal3fv(normals[3]);
glVertex3fv(vec[1]);
glVertex3fv(vec[3]);
glVertex3fv(vec[7]);
glVertex3fv(vec[5]);
// left
glNormal3fv(normals[4]);
glVertex3fv(vec[4]);
glVertex3fv(vec[5]);
glVertex3fv(vec[7]);
glVertex3fv(vec[6]);
// right
glNormal3fv(normals[5]);
glVertex3fv(vec[2]);
glVertex3fv(vec[3]);
glVertex3fv(vec[1]);
glVertex3fv(vec[0]);
glEnd();
}
glEndList();
}
dRed -= red;
dRed /= count;
dGreen -= green;
dGreen /= count;
dBlue -= blue;
dBlue /= count;
dAlpha -= alpha;
dAlpha /= count;
Class QCStructureClass = [QCStructure class];
Class NSArrayClass = [NSArray class];
BOOL keyed = (count && [[pointStruct memberAtIndex:0] isKindOfClass:QCStructureClass] &&
[[pointStruct memberAtIndex:0] memberForKey:@"X"] != nil);
//glBegin(GL_QUADS);
float (*floatValue)() = (float (*)())[NSNumber instanceMethodForSelector:@selector(floatValue)];
for(id point in (GFList*)[pointStruct _list])
{
CGFloat outColor[4] = {red, green, blue, alpha};
glPushMatrix();
if([point isKindOfClass: QCStructureClass])
{
float x, y, z;
if(keyed)
{
id val;
if(val = [point memberForKey:@"R"])
//outColor[0] *= [val floatValue];
outColor[0] *= floatValue(val, nil);
if(val = [point memberForKey:@"G"])
//outColor[1] *= [val floatValue];
outColor[1] *= floatValue(val, nil);
if(val = [point memberForKey:@"B"])
//outColor[2] *= [val floatValue];
outColor[2] *= floatValue(val, nil);
if(val = [point memberForKey:@"A"])
//outColor[3] *= [val floatValue];
outColor[3] *= floatValue(val, nil);
x = floatValue([point memberForKey:@"X"],nil);
y = floatValue([point memberForKey:@"Y"],nil);
z = floatValue([point memberForKey:@"Z"],nil);
//x = [[point memberForKey:@"X"] floatValue];
//y = [[point memberForKey:@"Y"] floatValue];
//z = [[point memberForKey:@"Z"] floatValue];
}
else
{
id val;
if(val = [point memberAtIndex:3])
//outColor[0] *= [val floatValue];
outColor[0] *= floatValue(val, nil);
if(val = [point memberAtIndex:4])
//outColor[1] *= [val floatValue];
outColor[1] *= floatValue(val, nil);
if(val = [point memberAtIndex:5])
//outColor[2] *= [val floatValue];
outColor[2] *= floatValue(val, nil);
if(val = [point memberAtIndex:6])
//outColor[3] *= [val floatValue];
outColor[3] *= floatValue(val, nil);
x = floatValue([point memberAtIndex:0]);
y = floatValue([point memberAtIndex:1]);
z = floatValue([point memberAtIndex:2]);
//x = [[point memberAtIndex:0] floatValue];
//y = [[point memberAtIndex:1] floatValue];
//z = [[point memberAtIndex:2] floatValue];
}
glTranslatef(x, y, z);
}
else if( [point isKindOfClass:NSArrayClass] )
{
glTranslatef(floatValue([(NSArray *)point objectAtIndex:0]),
floatValue([(NSArray *)point objectAtIndex:1]),
floatValue([(NSArray *)point objectAtIndex:2]));
}
KIGLColor4v(outColor);
glCallList(cube);
glPopMatrix();
// sadly, this is about 15% faster than multiplication (which is ok, since we're using fast enumeration now
// anyway)
red += dRed;
green += dGreen;
blue += dBlue;
alpha += dAlpha;
}
//glEnd();
[inputCulling unsetOnOpenGLContext:context];
[inputDepth unsetOnOpenGLContext:context];
[inputBlending unsetOnOpenGLContext:context];
return YES;
}
@end