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
|
// Shave and a Haircut
// (c) 2019 Epic Games
// US Patent 6720962
#ifndef GUIDE_MAX_SEGS
#define SHAVE_NUM_PARAMETERS 60
#ifdef COMPILE_GPU
// will need this for the kernal #include "mathstuff.c"
#endif
#define GUIDE_MAX_SEGS 60
// interpolation method
#define MESH_GROWTH 2
#define SPLINE_GROWTH 1
#define NONE 0
// params
#define ROOTFRIZZ 0
#define FRIZZFREQX 1
#define KINK 2
#define KINKFREQX 3
#define SPEC 4
#define KSPEC 5
#define DIFFUSE 6
#define AMBIENT 7
#define BASERAD 20 /*h.thickness*slider[20] */
#define LENMAP 29
#define TIPFRIZZ 24
#define FRIZZFREQY 30
#define FRIZZFREQZ 31
#define FRIZZANIM 32
#define FRIZZANIMSPEED 33
#define KINKROOT 38
#define KINKFREQY 34
#define KINKFREQZ 35
#define RANDSCALE 36
#define MULT_RANDSCALE 42
#define SCALE 41
#define TIPRAD 37 // h.thicknesstip * slider[37]
#define BASERAD 20 // h.thicknesstip * slider[37]
#define MESS 47
#define FLYAWAY 48
#define CLUMP_STRENGTH 49
#define CLUMP_COLOR_STRENGTH 51
#define CLUMP_ROT_STRENGTH 50
#define CLUMP_ROT_OFFSET 52
#define RANDOMIZE 53
#define CLUMP_FLATNESS 54
#define ROOT_THICKNESS 20
#define TIP_THICKNESS 37
#define ROOT_COLOR_R 17
#define ROOT_COLOR_G 18
#define ROOT_COLOR_B 19
#define TIP_COLOR_R 9 // are root and tip inverted?
#define TIP_COLOR_G 10
#define TIP_COLOR_B 11
#define HUE_VARIATION 12
#define VALUE_VARIATION 39
#define CUTLENGTH 29
#define DIFFUSE 6
#define SPEC 4
#define KSPEC 5
#define CLUMP_RANDOMIZE 53
#define CLUMP_SCRUFFLE 55
#define DENSITY 28
#define DREADCOUNT 25 // mult
#define DREADTIP 27 // mult
#define DREADROOT 26 // mult
#define OFFSET 45 // mult
#define ASPECT 46 // mult
#define MULTASP 44 // mult
#ifdef OPENCL
#define SHAVEPARMS void
#define BUNCHROOT void
#ifdef WIN32
#define FLOAT_PTR uint
#define UCHAR_PTR uint
#define INT_PTR uint
#define ROOTPT_PTR uint
#define NEWGUIDES_PTR uint
#define VERT_PTR uint
#endif
#ifdef WIN64
#define FLOAT_PTR ulong
#define UCHAR_PTR ulong
#define INT_PTR ulong
#define ROOTPT_PTR ulong
#define NEWGUIDES_PTR ulong
#define VERT_PTR ulong
#endif
#else
#define FLOAT_PTR float*
#define UCHAR_PTR unsigned char*
#define INT_PTR int*
#define ROOTPT_PTR ROOTPT*
#define NEWGUIDES_PTR NEWGUIDES*
#define VERT_PTR VERT*
#endif
typedef struct {
// this is just like ROOTPT, except the allocation is static
// it is for use in the GPU kernal because there are no mallocs
int id;
int killme;
VERT resthv;
VERT bary;
int pntid1;
int pntid2;
int pntid3;
int closest_clump;
float distance;
float baked_tex[SHAVE_NUM_PARAMS];
float flip;
float restlength; // added 9/14
} STATICROOTPT;
typedef struct {
int id; // 0
int killme; // sizeof(int)
VERT resthv; // sizeof(int)*2
VERT bary; // sizeof(int)*2+sizeof(VERT)
int pntid1; // sizeof(int)*2+sizeof(VERT)*2
int pntid2; // sizeof(int)*2+sizeof(VERT)*2+sizof(int)
int pntid3; // sizeof(int)*2+sizeof(VERT)*2+sizof(int)*2
int closest_clump; // sizeof(int)*2+sizeof(VERT)*2+sizof(int)*3
float distance; // sizeof(int)*2+sizeof(VERT)*2+sizof(int)*4
int total_tex;
//sized by total_tex
UCHAR_PTR tex_link;
//sized by total_tex
FLOAT_PTR baked_tex; // // sizeof(int)*2+sizeof(VERT)*2+sizof(int)*4+sizeof(float)
float flip; // sizeof(int)*2+sizeof(VERT)*2+sizof(int)*4+sizeof(float)+sizeof(float)*60
// total size: sizeof(int)*2+sizeof(VERT)*2+sizof(int)*4+sizeof(float)+sizeof(float)*60+sizeof(float)
int baked_tex_index;
int tex_link_index;
float restlength;
} ROOTPT;
#ifndef OPENCL // not used inside the kernal
typedef struct {
INT_PTR list; // sizeof (int) * list_total;
int list_total;
int slg;
ROOTPT_PTR root; // see ROOTPT * list_total - note:rootpt's baked_tex and tex_link are linked lists sized by total_tex
int threadID;
int list_index;
int root_index;
} BUNCHROOT;
#endif
typedef struct {
VERT *hv; // 0
VERT *resthv; // sizeof (VERT)*guide_segs
VERT *velocity; // (sizeof (VERT)*guide_segs)*2
VERT *noisev; // (sizeof (VERT)*guide_segs)*3
VERT rest_handle; // (sizeof (VERT)*guide_segs)*4
VERT rest_normal; // (sizeof (VERT)*guide_segs)*4+sizeof(VERT);
VERT handle; // (sizeof (VERT)*guide_segs)*4+sizeof(VERT)*2;
VERT normal; // (sizeof (VERT)*guide_segs)*4+sizeof(VERT)*3;
float uu; // (sizeof (VERT)*guide_segs)*4+sizeof(VERT)*4;
float vv; // (sizeof (VERT)*guide_segs)*4+sizeof(VERT)*4+sizeof(float);
// total size = (sizeof (VERT)*guide_segs)*4+sizeof(VERT)*4+sizeof(float)*2
int hv_index; // sizeof (VERT) * k->guide_segs
int resthv_index; // sizeof (VERT) * k->guide_segs
int velocity_index; // sizeof (VERT) * k->guide_segs
int noisev_index; // sizeof (VERT) * k->guide_segs
int smoothing_group; // add 9/14
int splitmerge; // add 9/14
VERT rootcolor;// added 9/15
VERT tipcolor;// added 9/15
int killme;
} NEWGUIDES;
typedef struct {
// it's the same as newguide, just a static version of it so we
// can use it in a kernal
VERT hv[GUIDE_MAX_SEGS];
VERT resthv[GUIDE_MAX_SEGS];
VERT velocity[GUIDE_MAX_SEGS];
VERT noisev[GUIDE_MAX_SEGS];
float uu;
float vv;
VERT rest_handle,rest_normal;
VERT handle,normal;
int smoothing_group; // added 9/14
int splitmerge; // add 9/14
VERT rootcolor;
VERT tipcolor;
int killme;
} STATICGUIDE;
typedef struct {
Matrix zero2world[GUIDE_MAX_SEGS];
Matrix world2zero[GUIDE_MAX_SEGS];
VERT pos[GUIDE_MAX_SEGS];
} BASEMATRIXK;
typedef struct {
// READ_ONLY kernal doesn't write into here
// these are nodewise parameters, they all get set for you in SHAVEallocate_kernal
// you don't need to set any of these, they all get set for you in SHAVEallocate_kernal
// but reffer to this file for what thos allocation sizes are
int multiplier; // 0
int segs; // this is not used for sizing, it is only a parameter
int interpolation_type; // need this for allocation - meshgrowth, spline growth, none
int total_guides;
int total_clumps;
int total_roots; // total number of hairs in the system (though we may only generate a subset from the hairlist)
int guide_segs; // actually not segs, but guide verts
int enable_interpolation;
int hairlist_size;
//sized by hairlist_size
INT_PTR hairlist;
int dirty;
int instancing_status;
int tipfade;
int rand_seed_offset;
int squirrel;
float slider_val[SHAVE_NUM_PARAMS]; // 16*sizeof(int)
float geom_shadow;// 16*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)
float multrot; // 17*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)
float multrot_phase; // 18*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)
float multrot_offset; // 19*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)
float flyaway_percent; // 20*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)
VERT spec_tint; // 21*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)
VERT spec_tint2; // 22*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)+sizeof(VERT)
// newguide_size = (sizeof (VERT)*guide_segs)*4+sizeof(VERT)*4+sizeof(float)*2
//sized by total_guides
NEWGUIDES *guides; // 22*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)+sizeof(VERT)*2
//sized by total_roots
ROOTPT *hair_roots; // 22*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)+sizeof(VERT)*2+newguide_size*total_guides
//sized by total_clumps
ROOTPT *clump_roots; // 22*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)+sizeof(VERT)*2+newguide_size*total_guides
//sized by hairlist_size
NEWGUIDES *return_hair; // 22*sizeof(int) + SHAVE_NUM_PARAMS*sizeof(int)+sizeof(VERT)*2
//VERT_PTR multiplier_offsets; // multiplier*sizeof(VERT)
//VERT_PTR multiplier_root_colors; // multiplier *sizeof (VERT)
//VERT_PTR multiplier_tip_colors; // multiplier *sizeof (VERT)
// offsets in GPU arrays that we use instead of corresponding pointers
int hairlist_index;
int return_hair_index;
int guides_index;
int hair_roots_index;
int clump_roots_index;
float noise[20][20][20];
float RESTBOUND;
SHAVENODE shavenode;
float time; // added 9/1
float ext_forces;
} MINIKERNAL;
#endif
#ifndef OPENCL
// you can ignore all of these accept SHAVEallocate_kernal and SHAVEfree_kernal for now
extern void free_guide(NEWGUIDES *k);
extern void MTmake_a_bunchROOT( int list_total, int *list, MINIKERNAL *m, int threadID );
extern void SHAVEallocate_kernal(MINIKERNAL *in,SHAVEPARMS *shavep, int haircount,int hairsegs);
extern void SHAVEfree_kernal(MINIKERNAL *in);
extern void SHAVEinit_kernal(MINIKERNAL *in);
extern void SHAVEupdate_kernal(MINIKERNAL *in,SHAVEPARMS *shavep);
extern void the_kernal (MINIKERNAL *m,STATICGUIDE *ret,STATICROOTPT *pt,int hairnum);
#endif
|