aboutsummaryrefslogtreecommitdiff
path: root/libexe/shaveSDKFUNCS.h
blob: b79064332518a8cff7e97b5ea6f512fe33065e0d (plain) (blame)
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
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
#ifndef shaveSDKFUNCS_h
#define shaveSDKFUNCS_h

// Shave and a Haircut
// (c) 2019 Epic Games
// US Patent 6720962

#ifdef DOUNICODE
#include "windows.h"
#endif

#include <stdio.h>
#include "shaveSDKTYPES.h"

#ifdef __cplusplus
#ifndef USECPP
extern "C" 
{
#endif
#endif

void			SHAVEfree_clump(void);
void			SHAVEinit_clump(void);

#ifdef DOUNICODE
void  SHAVEwrite_nodeDISK(wchar_t *filename);
#else
void SHAVEwrite_nodeDISK(char *filename);
#endif

int SHAVEis_it_loaded(void);

void MTbunch_of_hairs(int list_total, int *inlist,int slg,int pass, WFTYPE *outwf,CURVEINFO *cinfo);
void MTbunch_of_hairsINST(int list_total, int *inlist,int slg,int pass, WFTYPE *outwf,CURVEINFO *cinfo);

void SHAVEsplinelock(SHAVENODE *sn,WFTYPE *wf);
void SHAVEsplinelock_clear(SHAVENODE* sn);


void            SHAVEcalibrate( float x, float y );	// calibrate viwport screen offset (in pixels)

void            SHAVEmake_a_hair( int, int, int, int, WFTYPE * );

// this function will make a hair (or an instance) out of polygons
// params for SHAVEmake_a_hair
// int - pass number
// int - hair group (0-5)
// int - hair index
// int - number of hair segs to generate
// WFTYPE * - holder for strand(s) - don't malloc, make sure the .totalverts member
//            is set to 0 on first use

void            SHAVEgetobj( char *name, WFTYPE * wfdata );

// params for SHAVEgetobj
// char *  - file name (including path if any)
// WFTYPE * - data structure containing unsurfaced polys
//            don't malloc, just set the .totalverts member to 0 on first
//            use
// this function will probably not get used in the app, but it is here
// for the example, since we are starting with an obj file. Normally you
// you fill in the WFTYPE data members and pass them into SHAVExform yourself

void            SHAVEgetobj( char *name, WFTYPE * wfdata );

// get an objfile from disk and alloc/create WFTYPE from it


void            SHAVEmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE *, CURVEINFO * );

// generally used to make a hair


void            SHAVEmake_a_curveMT( int current_samp, int slg, int hairnum, int segs, WFTYPE *, CURVEINFO *, int threadID );

// same as above, but thread-safe

void            SHAVEmake_a_curveROOT( int current_samp, int slg, int hairnum, WFTYPE *, CURVEINFO * );

// this is a faster version of the above that you can use when you just need the general info in 'curveinfo'
// and the first point from the curve in WFTYPE

void            alloc_geomWF( WFTYPE * geom );

// this allocates a WFTYPE given the totalverts,totalfaces,totalfverts members

void            copy_geomWF( WFTYPE * dest_geom, WFTYPE * source_geom );

// this copys a one memfile to another, allocating the dest 
// (dest is assummed to be init and empty) 

void            init_geomWF( WFTYPE * geom );

// this initializes a WFTYPE structure

void            free_geomWF( WFTYPE * geom );

// this frees a WFTYPE structure

void            save_geomWF( WFTYPE * geom, char *filename );

int             SHAVErender_frame( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int deep_shadows );

// render the frame. the WFTYPES are occlusion (skin) geometry of the scene
// this version render's both cam and lights (remember to do a
// SHAVEclear_stack when you're done with the shadow buffs for cast
// shadows)

// these are for separating cam and shadow renders -- ALWAYS DO SHADOWS FIRST
int             SHAVErender_cam( WFTYPE * geom_open, WFTYPE * geom_close, int oversampling, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int xres, int yres, int dice );
int             SHAVErender_camNOBLUR( WFTYPE * geom_open, WFTYPE * geom_close, int oversampling, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int xres, int yres, int dice );

int             SHAVErender_shadows( WFTYPE * geom_open, WFTYPE * geom_close, int oversampling, int deep_shadows );


float           SHAVEilluminate_point( VERT wpos, int ShaveLightID );

// calculate illumination for a point in space for a single lightsource (do shadow lookups)
// return is 0-1, light color and ambient is not factored in.

float           SHAVEilluminate_pointNOGEOM( VERT wpos, int ShaveLightID );

void            SHAVEwrite_targa( char filename[255], short width, short height, unsigned char *image );

// this is a helper function to write a buffer out to a targa32 file

void            SHAVEfetch_parms( SHAVEPARMS * shavep );

// this is used to see the shave engine's current params

void            SHAVEset_parms( SHAVEPARMS * shavep );

// this function injects shave parameters into shave memory

void            SHAVEmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * );

// obsolete

#ifdef DOUNICODE
void            SHAVEget_instance( wchar_t *objfilename, SHAVENODE * sn );
#else
void            SHAVEget_instance( char *objfilename, SHAVENODE * sn );
#endif

// insert an instance into the shavenode

void            SHAVEclear_instance( SHAVENODE * sn );

// clear the instance from the shavenode


// 
// functions for dealing with SHAVENODEs
//
//
void            SHAVEcopy_node( SHAVENODE * sn, SHAVENODE * snsource, long newID );
void            SHAVEfree_node( SHAVENODE * sn );
void            SHAVEinit_node( SHAVENODE * sn, long ID );
#ifdef DOUNICODE
void            SHAVEcreate_node( wchar_t *objfilename, SHAVENODE * sn );
#else
void            SHAVEcreate_node( char *objfilename, SHAVENODE * sn );
#endif

// originate a new node and create a default growth
#ifdef DOUNICODE
void            SHAVEread_hairDISK( wchar_t *hairfilename, SHAVENODE * sn );
#else
void            SHAVEread_hairDISK( char *hairfilename, SHAVENODE * sn );
#endif

// read hairfile from disk into the engine and shavenode
#ifdef DOUNICODE
void            SHAVEwrite_hairDISK( wchar_t *hairfilename, SHAVENODE * );
#else
void            SHAVEwrite_hairDISK( char *hairfilename, SHAVENODE * );
#endif
 // params for SHAVEwrite_hairDISK
 // char * - filename/path for hairfile

void            SHAVEfetch_node( SHAVENODE * sn );

// retrieve a shavenode from the engine

int             SHAVEinsert_uv_coords( WFTYPE *, SHAVENODE * );

// returns 1 if success - u and v are stored in x and y 
#ifdef DOUNICODE
void            SHAVExplant( wchar_t *objfilepath, SHAVENODE * sn );
#else
void            SHAVExplant( char *objfilepath, SHAVENODE * sn );
#endif

void            SHAVExplantNOMAT( char *objfilepath, SHAVENODE * sn );

// for topo changes

void            SHAVEinsert_color_texturefilename( int slg, char *texturefilename, int mapmethod, SHAVENODE * sn );

// slg : 0=hair 2=beard 3=eyebrow 4=eyelash 5=spline
// insert/replace texture file name (TGA 24)
// filename = '' means turn off texturing
// mapmethod :
// 0 = x projection (on rest model)
// 1 = y projection
// 2 = z projection 
// 3 = UV coords

void            SHAVEinsert_densiy_texturefilename( int slg, char *texturefilename, int mapmethod, SHAVENODE * sn );

// slg : 0=hair 2=beard 3=eyebrow 4=eyelash 5=spline
// insert/replace texture file name (TGA 24)
// filename = '' means turn off texturing
// mapmethod :
// 0 = x projection (on rest model)
// 1 = y projection
// 2 = z projection 
// 3 = UV coords

void            SHAVEinsert_cutmap_texturefilename( int slg, char *texturefilename, int mapmethod, SHAVENODE * sn );

// slg : 0=hair 2=beard 3=eyebrow 4=eyelash 5=spline
// insert/replace texture file name (TGA 24)
// filename = '' means turn off texturing
// mapmethod :
// 0 = x projection (on rest model)
// 1 = y projection
// 2 = z projection 
// 3 = UV coords

// direct engine query

unsigned long   SHAVEquery_shave_ID( void );

// this is used for keeping track of which engine is
// active. it's originally set with init_node
#ifdef DOUNICODE
wchar_t          *SHAVEquery_version( void );
#else
char           *SHAVEquery_version( void );
#endif

// this returns a string with the current version info on the lib

int             SHAVEfetch_guide( int vertno, SOFTGUIDE * sg );

// for fetching guides from the engine for display (read only)
// return is -1 if there is no guide emmited from vert # vertno

int             SHAVEfetch_guideNOISE( int vertno, SOFTGUIDE * sg );

// for fetching guides from the engine for display (read only)
// return is -1 if there is no guide emmited from vert # vertno


void            SOFTput_guide( int vertno, SOFTGUIDE * );

// this function will force an eval as well
// to re-validate lengths.

void            SOFTput_guideSELECTONLY( int vertno, SOFTGUIDE * guide );

// this function will only change the selections, no eval is done.

void            SHAVEput_guideNOCALC( int vertno, SOFTGUIDE * guide );

// will update vertices, selections, weights, etc, but will not eval.
//


// funcs for transforming the shavenode and generating dynamics .stat files:

void            SHAVEreset_engine( SHAVENODE * sn );

// set the current state to that of the rest hair
#ifdef DOUNICODE
void            SHAVExform( WFTYPE * objstructure, SHAVENODE * sn, int run_dyn, wchar_t *statfile );
#else
void            SHAVExform( WFTYPE * objstructure, SHAVENODE * sn, int run_dyn, char *statfile );
#endif

// core transformation and dynamics function

void            SHAVEset_state_between( SHAVENODE * sn, float uu, char *stat1, char *stat2 );

// set the current state to an inbetween of two statfiles 
#ifdef DOUNICODE
void            SHAVEset_state_between_and_glue( WFTYPE * wf, SHAVENODE * sn, float uu, wchar_t *stat1, wchar_t *stat2 );
#else
void            SHAVEset_state_between_and_glue( WFTYPE * wf, SHAVENODE * sn, float uu, char *stat1, char *stat2 );
#endif

// set the current state to an inbeetween of two statfiles
// and then glues the guides' roots to the wf 

void            SHAVEdump_stats( char *statname );

// this will dump shave's current 'hairstate' to a '.stat' file

void            SHAVEreplace_rest( SHAVENODE * sn );

// this function will jam the current hair position into the rest pose the
// engine must -already- be loaded with this SHAVENODE when you call this
// funciton so you must have just run an xform or something use this
// function -sparingly-, you'll mess up all kinds of stuff if you're
// running it on every frame.

void            SHAVEflush_state( SHAVENODE * sn );

// this restores a node to the engine in its current state


void            SHAVEupgrade_node( SHAVENODE * sn );

// this function essentially flushes the node through the engine for an upgrade to make it current
// protocall compatable
// recommend that you always do this right away once the node's data's been loaded from disk


void            SHAVErecomb_select( void );

// this function recombs the selected hair

void            SHAVEspline_recomb( SHAVENODE * node, WFTYPE * splines );


// render setup/destroy functions:

void            SHAVEclear_stack( void );	// clear the render stack

void            SHAVEclear_scene( void );

void            SHAVEadd_hairOPEN( SHAVENODE * sn );

// add a node to the stack for shutter open (a copy is made internally)
// Synchronous version.  You must call CLOSE for the same hair before
// calling OPEN on another one.

void            SHAVEadd_hairCLOSE( SHAVENODE * sn );

// add a node to the stack for shutter close (a copy is made internally)
// Synchronous version.

void            SHAVEadd_hairOPEN2( SHAVENODE * sn, int index );

// add a node to the stack for shutter open (a copy is made internally)
// Asynchronous version.  CLOSE2 must follow eventually, but not
// immediately: other OPEN2 calls can intervene.
// 'index' numbers start at 0 and must be contiguous.

void            SHAVEadd_hairCLOSE2( SHAVENODE * sn, int index );

// add a node to the stack for shutter close (a copy is made internally)
// Asynchronous version.  Note that you MUST call SHAVEset_stack_max after
// the last call to CLOSE2.

void            SHAVEset_stack_max( int index );

// Indicates the first unused index after a batch of OPEN2/CLOSE2 calls.

void            SHAVEmake_view_matrix( Matrix vm, VERT vv, VERT nn, VERT wpos, float fov );

// used for seting up a view matrix

int             SHAVEadd_light( float r, float g, float b, Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float fuzz, int shadsamps, float shadr, float shadg, float shadb, int trace, float nearClip );

// add a lightsource (spotlight)

int             SHAVEadd_point_light( float r, float g, float b, VERT wpos, int xres, int yres, float fuzz, int shadsamps, float shadr, float shadg, float shadb, int trace, float nearClip );

// add a lightsource (pointlight)


void            SHAVEset_cameraOPEN( Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip );

// sets the camera for the shutter open



void            SHAVEset_cameraCLOSE( Matrix vm, VERT wpos );

// sets the camera for the shutter close

int             SHAVEgetMAXPASSES( void );

// this function returns the maximum number of passes that are in all of the nodes
// added with add_hair. Should only get called AFTER all add_hair(s)
// service functions 

void            SHAVEinvert_matrix( Matrix in, Matrix out );

// inverts a 4x4 matrix

void            SHAVEgen_roots( void );

// this function will quickly cycle through all the hair generation
// at the roots only. this is usefull if your texture lookups are going to
// be faster en-masse.
// you will want to run this prior to the shadow and camera renders
// and intercept the points in the apply_texture() callback.
// (and build a lookup stack this way)

void            SHAVErib_dump_node( SHAVENODE * sn, FILE * fp, int curvesOK, int segs, int basis );

// dumps ASII rib to fp. if you're prman compliant render can't accepts
// riCurves then curvesOK should == 0, otherwise it should be 1.
// segs is the number of segments to create in a hair.
// instances will always get created as PointsPolygons.
// basis==0 linear
// basis==1 cubic
// this initializes everything shave - call it on entry

void            SHAVEinit( void );

// this cleans up everything shave - call it on exit

void            SHAVEcleanup( void );

// this function clears all texture and weight entries
// it's generally used for migrating over to a texture mode where shave
// handles textures and weights
// to one which is handled locally (in your package)

void            SHAVEclear_textures( SHAVENODE * sn );

void            SHAVEfast_eval( int onoff );	// 1==fast 0==render qual

// if you set this to 1 while generating display hairs, some noise octaves
// and some smoothsteps get knocked off, make_a_spline will generate faster

void            SHAVEdrag_mode( int onoff );	// this func is really only appropriate for soft

// it tells the collision engine not to rebuild the polyvoxels on this
// iteration of collision you only want it on while draging hair without
// moving any geom.  you should probably have it off for the first
// iteration of dragging to make sure everything's current

void            init_MEMFILE( MEMFILE * mf, long ID );
void            free_MEMFILE( MEMFILE * mf );
void            copy_MEMFILE( MEMFILE * out, MEMFILE * in );
void            alloc_MEMFILE( MEMFILE * mf );


void            SHAVEtrace_init( void );

// this function initializes the volumetric engine and tags voxels
// its the volumetric equiv of render_shadows

int             SHAVEtrace( float nearClip, float farClip, VERT rbase, VERT rdir, int shademe, VOXSAMP * vsamp );

// this function traces a ray (accross all the shavenodes you've added into
// the stack using add_hair use the 'apply_illumination' callbacks to apply
// falloffs and recieve shadows from your scene


// Set the limits to be used during tiling. 'memoryLimit' is in megabytes.
void SHAVEset_tile_limit(int memoryLimit, int transparencyDepth);


// begining of export stuff
//
// these functions are for building a full data set of all the hair that's
// on the stack you've already built using all the add_hair functions. this
// can be kind of a memory pig so don't keep that data around any longer
// than you have to
// 
// for example:
//
// HAIRTYPE exp;
// SHAVEinit_hairtype(&exp);
// SHAVEexport_hair(&exp);
//
// do your thing here with the hair information
//
// SHAVEfree_hairtype(&exp);
//
// all done and cleaned up
// (you could also do a SHAVEclear_stack() at this point)
//
int             SHAVEexport_instances( WFTYPE * );
int             SHAVEexport_hairtype( HAIRTYPE * );
int             SHAVEexport_iterator( HAIRTYPE * );
int             SHAVEexport_iteratorROOT( HAIRTYPE * );
int             SHAVEexport_poly_iterator( HAIRTYPE * ht );
void            SHAVEreset_iterator( void );

void            SHAVEinit_hairtype( HAIRTYPE * );
int             SHAVEalloc_hairtype( HAIRTYPE * );
void            SHAVEfree_hairtype( HAIRTYPE * );

void            SHAVErender_swatch( unsigned char *image, float *zbuff, int res, SHAVEPARMS * shavep );


//
// Delayed Read Archive support
//
#ifdef DOUNICODE
int             SHAVEexport_archive( wchar_t *fname, int voxres );
#else
int             SHAVEexport_archive( char *fname, int voxres );
#endif

int             SHAVEinit_hairstack_from_archive( char *fname );
int             SHAVEinit_hairstack_from_mem_archive( MEMFILE * mem );

void            SHAVEimport_archive_voxel( char *fname, int voxelX, int voxelY, int voxelZ, HAIRTYPE * outhair, int isShadow	// 2.7v51
	 );

void            SHAVEimport_mem_archive_voxel( MEMFILE * mem, int voxelX, int voxelY, int voxelZ, HAIRTYPE * outhair, int isShadow	// 2.7v51
	 );

void            SHAVEimport_archive_voxel_by_node( char *fname, int voxelX, int voxelY, int voxelZ, HAIRTYPE * outhair, UVSETS * uvSet,	// 3.0v15
												   int isShadow,	// 2.7v51
												   int stack_index );

void            SHAVEimport_mem_archive_voxel_by_node( MEMFILE * mem, int voxelX, int voxelY, int voxelZ, HAIRTYPE * outhair, UVSETS * uvSet,	// 3.0v15
													   int isShadow,	// 2.7v51
													   int stack_index );

void            SHAVEfree_UV( UVSETS * uv );
void            SHAVEinit_UV( UVSETS * uv );

int             SHAVEimport_archive_voxel_bbox( char *fname, int voxelX, int voxelY, int voxelZ, VERT * bboxMin, VERT * bboxMax );	// returns 1 if the voxel contains hair
int             SHAVEimport_mem_archive_voxel_bbox( MEMFILE * mem, int voxelX, int voxelY, int voxelZ, VERT * bboxMin, VERT * bboxMax );	// returns 1 if the voxel contains hair

void            SHAVEadd_occlusions( WFTYPE * wf );
void			SHAVEmult_vox_size(float mult);

// end of export stuff


// uv sets stuff for softimage
void            SHAVEclear_uvsets( SHAVENODE * sn );	// this clears all uv sets from the shavenode
int             SHAVEadd_uvset( SHAVENODE * sn, WFTYPE * uvset );	// this adds a set to the node and returns an index

												 // to be later refferenced in SHAVEPARMS->uv_link[xxx]


//
// Hair Styling
//

// Begin a brush stroke.
// Screen coords are normalized to the range 0.0-1.0 in both directions.
void            SHAVEsculpt_setup( BRUSH_MODE mode, VERT eye_point, VERT view_dir, VERT up_dir, VERT mouse_down_screen, VERT mouse_down_world );

// Update a stroke in-progress.
// Screen coords are normalized to the range 0.0-1.0 in both directions.
void            SHAVEsculpt_iterate( VERT mouse_drag_screen, VERT mouse_drag_world, VERT mouse_drag_relative_screen, VERT mouse_drag_relative_world );

// Complete a stroke.
void            SHAVEsculpt_finish(  );


void            SHAVEcut( VERT eye_point, VERT view_dir, VERT mouse_down_screen, VERT mouse_down_world );

void            SHAVEattenuate(  );
void            SHAVEpop_selected(  );
void            SHAVEpop_zero_sized(  );
void            SHAVErecomb(  );
void            SHAVEtoggle_collision(  );
void            SHAVElock(  );
void            SHAVEunlock(  );
void            SHAVEundo(  );

void            SHAVEreplace_rest_interactive(  );
void            SHAVEselect_grow(  );
void            SHAVEselect_inverse(  );
void            SHAVEselect_rotate_up(  );
void            SHAVEselect_hide(  );
void            SHAVEselect_unhide(  );
void            SHAVEmerge_selection( void );
void            SHAVEsplit_selection( void );


// Multi-threading

//
// Initializes a group of 'maxThreads' threads, returning a handle to
// the thread group.
//
// If you are using the threads for pure processing (i.e. no device I/O, no
// interprocess communication or anything else that might involve waiting)
// then you need at most as many threads as there are processors and
// processing cores on your system, otherwise you're just adding needless
// overhead.
//
void           *SHAVEstart_thread_group( int maxThreads );

//
// Executes function 'func' within a thread, passing a thread ID as the
// function's first argument, and 'data' as its second.  If all threads are
// busy, SHAVEstart_thread will wait for one to become available.
//
void            SHAVEstart_thread( void *groupHandle, ThreadFunc func, void *data );

// 
// Waits for all currently active threads to complete.
//
void            SHAVEwait_thread_group( void *groupHandle );

// 
// Waits for all currently busy threads to complete, then destroys the
// thread group.
//
void            SHAVEend_thread_group( void *groupHandle );

//
// Destroys the thread group immediately, without waiting for busy threads
// to complete.
//
void            SHAVEabort_thread_group( void *groupHandle );

//
// Returns the number of available processors in the local system.
//
int             SHAVEnum_processors(  );

//
// Tell Shave the max number of threads, excluding the main thread, to use
// internally.
//
void            SHAVEset_max_threads( int n );


// Mutex (Mutual Exclusion) Functions
//
// Used to ensure that only one thread accesses a given resource at a time.

//
// Initialize a mutex.
//
#ifndef XSI_SOFT3D_ONLY
void            SHAVEmutex_create( ShaveMutex * mutex );

//
// Free up any resources used by a mutex.
//
void            SHAVEmutex_destroy( ShaveMutex * mutex );
#endif
// Softimage doesn't need those mutex and those function don't exist
// anyway!
#ifdef XSI_SOFT3D_ONLY

inline void SHAVEmutex_create( ShaveMutex * )
{
}
inline void SHAVEmutex_destroy( ShaveMutex * )
{
}

#endif

//
// Lock a mutex.  If it's currently locked by someone else, wait
// for it to come free first.
//
void            SHAVEmutex_lock( ShaveMutex * mutex );

//
// Unlock a mutex.
//
void            SHAVEmutex_unlock( ShaveMutex * mutex );

//
// Create a condition variable.
//
void            SHAVEcond_create( ShaveCond * cond );

//
// Destroy a condition variable.
//
void            SHAVEcond_destroy( ShaveCond * cond );

//
// Signal the condition. If there are threads waiting on it one (and only
// one) will be activated.
//
void            SHAVEcond_signal( ShaveCond * cond );

//
// Wait for the condition to be signalled.
//
void            SHAVEcond_wait( ShaveCond * cond, ShaveMutex * mutex );

// What renderer are we using? Currently only needed before calling
// SHAVEexport_archive.
void			SHAVEset_render_host(SHAVE_RENDER_HOST type);

//
// on/off native lighting
//
void			SHAVEset_native(int onOff);
void			SHAVEactivateGI(int);

//  Return the demo license string
//
const char*     SHAVEdemo_license(int *duration);

//  Return the # of days remaining in the demo license.
//  0 if expired
//  -1 if there is no demo license on this machine.
//
int             SHAVEdemo_remaining();

// Additional Shave functions that need to be exported.

extern int MAYAquery_shave_ID( void );
extern void     MAYAset_state( MEMFILE *, MEMFILE *, float uu, char *stat1, char *stat2 );
extern void     MAYAset_stateglue( WFTYPE *, MEMFILE *, MEMFILE *, float uu, char *stat1, char *stat2 );
extern void     MAYAset_stateMEM( MEMFILE * node, MEMFILE * state, float uu, MEMFILE * stat1, MEMFILE * stat2 );
extern void     MAYAflush_state( MEMFILE * node, MEMFILE * state );
extern void     MAYAxplant( char *xfile );
extern void     MAYAxplantNOMAT( char *xfile );
extern void     MAYArefresh( char *objfilename, MEMFILE *, MEMFILE *, SHAVEPARMS * );
extern void     MAYAwrite_hairDISK( char *hairfilename );
extern void     MAYAread_hairDISK( char *hairfilename, MEMFILE *, MEMFILE * );

extern void		MAYAread_hairMEM( MEMFILE *,MEMFILE *);
extern void     MAYAxform2( WFTYPE * objfile, MEMFILE * node, MEMFILE * node_state, int run_dyn, char *stat, SHAVEPARMS * shavep );
extern void     MAYAxform( WFTYPE * objfile, MEMFILE *, MEMFILE *, int run_dyn, char *statfile );
extern void     MAYAmake_a_hair( int current_samp, int slg, int hairnum, int segs, WFTYPE *, CURVEINFO * cinfo );
extern void     MAYAmake_view_matrix( Matrix vm, VERT vv, VERT nn, VERT wpos, float fov );
extern void     MAYAclear_scene( void );
extern void     MAYAclear_scene( void );
extern void     MAYAinit_scene( void );
extern int      MAYAadd_light( float r, float g, float b, Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip, float fuzz, int shadsamps, float shadred, float shadgreen, float shadblue, int trace, int type );
extern void     MAYAset_cameraOPEN( Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip );
extern void     MAYAset_cameraCLOSE( Matrix vm, VERT wpos );
extern void     MAYAadd_hairOPEN( MEMFILE * hairdataREST, MEMFILE * hairstateOPEN );
extern void     MAYAadd_hairCLOSE( MEMFILE * hairstateCLOSE, SHAVEPARMS * sparms );

//extern int MAYArender_frame(WFTYPE *geom_open, WFTYPE *geom_close, int oversampling, unsigned char *image, float *zbuff,int clipx0,int clipy0,int clipx1,int clipy1,int deep_shadows);
extern void     MAYAadd_hairOPEN2( MEMFILE * hairdataREST, MEMFILE * hairstateOPEN, int index );
extern void     MAYAadd_hairCLOSE2( MEMFILE * hairstateCLOSE, SHAVEPARMS * sparms, int index );
extern int      MAYArender_shadows( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, int deep_shadows );
extern int      MAYArender_cam( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int xres, int yres, int dice );
extern void     MAYAwrite_targa( char filename[255], short width, short height, unsigned char *image );
extern int      SOFTfetch_guideNOISESPACE( int vertno, SOFTGUIDE * );
extern int      SOFTfetch_guide( int vertno, SOFTGUIDE * );
extern void     SOFTput_guide( int vertno, SOFTGUIDE * );
extern void     SOFTput_guideNOCALC( int vertno, SOFTGUIDE * );
extern void     SOFTset_vert_parm( int vertno, int chan, float value );
extern void     MAYAset_parms( SHAVEPARMS * shavep );
extern void     MAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * );
extern void     MAYAxformNOSTAT( WFTYPE * objfile, MEMFILE *, MEMFILE *, int run_dyn );
extern void     SOFTcomb_select( VERT direction );
extern void     SOFTscale_select( float factor );
extern void     SOFTpop_zero( void );
extern void     SOFTlock_select( void );
extern void     SOFTunlock_select( void );
extern void     SOFTget_instance( char *objfilename );
extern void     SOFTattenuate_len( void );
extern void     SOFTcut_select( void );
extern void     SOFTsplit_select( void );
extern void     SOFTmerge_select( void );
extern void     SOFTshatter_select( void );
extern void     MAYAfetch_parms( SHAVEPARMS * shavep );
extern void     MAYAdump_stats( char *statname );
extern void     MAYAfech_node( MEMFILE *, MEMFILE *, SHAVEPARMS * shavep );
extern void     SOFTset_vert_parm( int vertno, int chan, float value );
extern float    SOFTget_vert_parm( int vertno, int chan );
extern void     MAYAset_parms( SHAVEPARMS * shavep );
extern void     MAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * );
extern void     MAYAxformNOSTAT( WFTYPE * objfile, MEMFILE *, MEMFILE *, int run_dyn );
extern void     MAYAmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE *, CURVEINFO * );
extern void     MAYAmake_a_curveROOT( int current_samp, int slg, int hairnum, WFTYPE *, CURVEINFO * );
#ifdef DOUNICODE
extern wchar_t *   MAYAquery_version( void );
#else
extern char *   MAYAquery_version( void );
#endif
extern void     MAYAdo_external_forces( int );	// 1 or 0
extern void     MAYAset_gravity_vector( VERT );
extern int      MAYAinsert_uv_coords( WFTYPE * );
extern void     MAYAfetch_node( MEMFILE * a, MEMFILE * b, SHAVEPARMS * shavep );
extern void     SOFTpop_select( float scale );
extern void     clear_shave_engine( void );
extern void 	SOFTreset_noisespace( void );
extern void		SOFTreset_rest(int recalc_restlen);
extern void     XSI_EstimateHairProbability( int slg, unsigned long in_ulFaceIndex, double *out_pdProbability );
extern int      XSI_GetRenderHairTriangle( int currsamp, int slg, int ind, int *out_prim, int *out_pva, int *out_pvb, int *out_pvc, float *out_pbarya, float *out_pbaryb );
void			SOFTclear_instance( void );
VERT            SHAVEapply_GI( VERT vv, CURVEINFO * ci );
void            SHAVEset_verbose( int onoff );	// this func is really only appropriate for soft

#ifdef __cplusplus
#ifndef USECPP
}
#endif
#endif

#endif