bbblitz3d.cpp 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230
  1. #include "std.h"
  2. #ifdef PRO
  3. #include "bbblitz3d.h"
  4. #include "bbgraphics.h"
  5. #include "../blitz3d/blitz3d.h"
  6. #include "../blitz3d/world.h"
  7. #include "../blitz3d/texture.h"
  8. #include "../blitz3d/brush.h"
  9. #include "../blitz3d/camera.h"
  10. #include "../blitz3d/sprite.h"
  11. #include "../blitz3d/meshmodel.h"
  12. #include "../blitz3d/loader_x.h"
  13. #include "../blitz3d/loader_3ds.h"
  14. #include "../blitz3d/loader_b3d.h"
  15. #include "../blitz3d/md2model.h"
  16. #include "../blitz3d/q3bspmodel.h"
  17. #include "../blitz3d/meshutil.h"
  18. #include "../blitz3d/pivot.h"
  19. #include "../blitz3d/planemodel.h"
  20. #include "../blitz3d/terrain.h"
  21. #include "../blitz3d/listener.h"
  22. #include "../blitz3d/cachedtexture.h"
  23. gxScene *gx_scene;
  24. extern gxFileSystem *gx_filesys;
  25. static int tri_count;
  26. static World *world;
  27. static set<Brush*> brush_set;
  28. static set<Texture*> texture_set;
  29. static set<Entity*> entity_set;
  30. static Listener *listener;
  31. static bool stats_mode;
  32. //converts 0...255 color to 0...1
  33. static const float ctof=1.0f/255.0f;
  34. //degrees to radians and back
  35. static const float dtor=0.0174532925199432957692369076848861f;
  36. static const float rtod=1/dtor;
  37. static Vector projected,tformed;
  38. static ObjCollision picked;
  39. extern float stats3d[10];
  40. static Loader_X loader_x;
  41. static Loader_3DS loader_3ds;
  42. static Loader_B3D loader_b3d;
  43. static map<string,Transform> loader_mat_map;
  44. static inline void debug3d(){
  45. if( debug && !gx_scene ) RTEX( "3D Graphics mode not set" );
  46. }
  47. static inline void debugTexture( Texture *t ){
  48. if( debug && !texture_set.count( t ) ) RTEX( "Texture does not exist" );
  49. }
  50. static inline void debugBrush( Brush *b ){
  51. if( debug && !brush_set.count( b ) ) RTEX( "Brush does not exist" );
  52. }
  53. static inline void debugEntity( Entity *e ){
  54. if( debug && !entity_set.count(e) ) RTEX( "Entity does not exist" );
  55. }
  56. static inline void debugParent( Entity *e ){
  57. if( debug ){
  58. debug3d();
  59. if( e && !entity_set.count(e) ) RTEX( "Parent entity does not exist" );
  60. }
  61. }
  62. static inline void debugMesh( MeshModel *m ){
  63. if( debug ){
  64. debugEntity(m);if( !m->getMeshModel() ) RTEX( "Entity is not a mesh" );
  65. }
  66. }
  67. static inline void debugObject( Object *o ){
  68. if( debug ){
  69. debugEntity(o);if( !o->getObject() ) RTEX( "Entity is not an object" );
  70. }
  71. }
  72. static inline void debugColl( Object *o,int index ){
  73. if( debug ){
  74. debugObject(o);
  75. if( index<1 || index>o->getCollisions().size() ) RTEX( "Collision index out of range" );
  76. }
  77. }
  78. static inline void debugCamera( Camera *c ){
  79. if( debug ){
  80. debugEntity(c);if( !c->getCamera() ) RTEX( "Entity is not a camera" );
  81. }
  82. }
  83. static inline void debugLight( Light *l ){
  84. if( debug ){
  85. debugEntity(l);if( !l->getLight() ) RTEX( "Entity is not a light" );
  86. }
  87. }
  88. static inline void debugModel( Model *m ){
  89. if( debug ){
  90. debugEntity(m);if( !m->getModel() ) RTEX( "Entity is not a model" );
  91. }
  92. }
  93. static inline void debugSprite( Sprite *s ){
  94. if( debug ){
  95. debugModel(s);if( !s->getSprite() ) RTEX( "Entity is not a sprite" );
  96. }
  97. }
  98. static inline void debugMD2( MD2Model *m ){
  99. if( debug ){
  100. debugModel(m);if( !m->getMD2Model() ) RTEX( "Entity is not an MD2 Model" );
  101. }
  102. }
  103. static inline void debugBSP( Q3BSPModel *m ){
  104. if( debug ){
  105. debugModel(m);if( !m->getBSPModel() ) RTEX( "Entity is not a BSP Model" );
  106. }
  107. }
  108. static inline void debugTerrain( Terrain *t ){
  109. if( debug ){
  110. debugModel(t);if( !t->getTerrain() ) RTEX( "Entity is not a terrain" );
  111. }
  112. }
  113. static inline void debugSegs( int n ){
  114. if( debug ){
  115. debug3d();
  116. if( n<3 || n>50 ) RTEX( "Illegal number of segments" );
  117. }
  118. }
  119. static inline void debugVertex( Surface *s,int n ){
  120. if( debug ){
  121. debug3d();
  122. if( n<0 || n>=s->numVertices() ) RTEX( "Vertex index out of range" );
  123. }
  124. }
  125. static inline void debugVertex( Surface *s,int n,int t ){
  126. if( debug ){
  127. debug3d();
  128. if( n<0 || n>=s->numVertices() ) RTEX( "Vertex index out of range" );
  129. if( t<0 || t>1 ) RTEX( "Texture coordinate set out of range" );
  130. }
  131. }
  132. static Entity *loadEntity( string t,int hint ){
  133. t=tolower(t);
  134. int n=t.rfind( "." );if( n==string::npos ) return 0;
  135. string ext=t.substr( n+1 );
  136. MeshLoader *l;
  137. if( ext=="x" ) l=&loader_x;
  138. else if( ext=="3ds" ) l=&loader_3ds;
  139. else if( ext=="b3d" ) l=&loader_b3d;
  140. else return 0;
  141. const Transform &conv=loader_mat_map[ext];
  142. CachedTexture::setPath( filenamepath( t ) );
  143. Entity *e=l->load( t,conv,hint );
  144. CachedTexture::setPath( "" );
  145. return e;
  146. }
  147. static void collapseMesh( MeshModel *mesh,Entity *e ){
  148. while( e->children() ){
  149. collapseMesh( mesh,e->children() );
  150. }
  151. if( Model *p=e->getModel() ){
  152. if( MeshModel *t=p->getMeshModel() ){
  153. t->transform( e->getWorldTform() );
  154. mesh->add( *t );
  155. }
  156. }
  157. delete e;
  158. }
  159. static void insert( Entity *e ){
  160. if( debug ) entity_set.insert( e );
  161. e->setVisible(true);
  162. e->setEnabled(true);
  163. e->getObject()->reset();
  164. for( Entity *p=e->children();p;p=p->successor() ){
  165. insert( p );
  166. }
  167. }
  168. static Entity *insertEntity( Entity *e,Entity *p ){
  169. e->setParent( p );
  170. insert( e );
  171. return e;
  172. }
  173. static void erase( Entity *e ){
  174. for( Entity *p=e->children();p;p=p->successor() ){
  175. erase( p );
  176. }
  177. if( e->getListener() ) listener=0;
  178. if( debug ) entity_set.erase( e );
  179. }
  180. static Entity *findChild( Entity *e,const string &t ){
  181. if( e->getName()==t ) return e;
  182. for( Entity *p=e->children();p;p=p->successor() ){
  183. if( Entity *q=findChild(p,t) ) return q;
  184. }
  185. return 0;
  186. }
  187. ///////////////////////////
  188. // GLOBAL WORLD COMMANDS //
  189. ///////////////////////////
  190. void bbLoaderMatrix( BBStr *ext,float xx,float xy,float xz,float yx,float yy,float yz,float zx,float zy,float zz ){
  191. loader_mat_map.erase( *ext );
  192. loader_mat_map[*ext]=Transform(Matrix(Vector(xx,xy,xz),Vector(yx,yy,yz),Vector(zx,zy,zz)));
  193. delete ext;
  194. }
  195. int bbHWTexUnits(){
  196. debug3d();
  197. return gx_scene->hwTexUnits();
  198. }
  199. int bbGfxDriverCaps3D(){
  200. debug3d();
  201. return gx_scene->gfxDriverCaps3D();
  202. }
  203. void bbHWMultiTex( int enable ){
  204. debug3d();
  205. gx_scene->setHWMultiTex( !!enable );
  206. }
  207. void bbWBuffer( int enable ){
  208. debug3d();
  209. gx_scene->setWBuffer( !!enable );
  210. }
  211. void bbDither( int enable ){
  212. debug3d();
  213. gx_scene->setDither( !!enable );
  214. }
  215. void bbAntiAlias( int enable ){
  216. debug3d();
  217. gx_scene->setAntialias( !!enable );
  218. }
  219. void bbWireFrame( int enable ){
  220. debug3d();
  221. gx_scene->setWireframe( !!enable );
  222. }
  223. void bbAmbientLight( float r,float g,float b ){
  224. debug3d();
  225. Vector t( r*ctof,g*ctof,b*ctof );
  226. gx_scene->setAmbient( &(t.x) );
  227. }
  228. void bbClearCollisions(){
  229. debug3d();
  230. world->clearCollisions();
  231. }
  232. void bbCollisions( int src_type,int dest_type,int method,int response ){
  233. debug3d();
  234. world->addCollision( src_type,dest_type,method,response );
  235. }
  236. static int update_ms;
  237. void bbUpdateWorld( float elapsed ){
  238. debug3d();
  239. #ifndef BETA
  240. world->update( elapsed );
  241. return;
  242. #endif
  243. update_ms=gx_runtime->getMilliSecs();
  244. world->update( elapsed );
  245. update_ms=gx_runtime->getMilliSecs()-update_ms;
  246. }
  247. void bbCaptureWorld(){
  248. debug3d();
  249. world->capture();
  250. }
  251. void bbRenderWorld( float tween ){
  252. debug3d();
  253. #ifndef BETA
  254. tri_count=gx_scene->getTrianglesDrawn();
  255. world->render( tween );
  256. tri_count=gx_scene->getTrianglesDrawn()-tri_count;
  257. return;
  258. #endif
  259. int tris=gx_scene->getTrianglesDrawn();
  260. int render_ms=gx_runtime->getMilliSecs();
  261. world->render( tween );
  262. render_ms=gx_runtime->getMilliSecs()-render_ms;
  263. extern int bbKeyHit(int);
  264. extern void bbDelay(int);
  265. bbDelay(0);
  266. if( bbKeyHit( 0x57 ) ){
  267. stats_mode=!stats_mode;
  268. }
  269. if( bbKeyHit( 0x58 ) ){
  270. static int n;
  271. string t="screenshot"+itoa(++n)+".bmp";
  272. bbSaveBuffer( bbBackBuffer(),d_new BBStr(t) );
  273. }
  274. if( !stats_mode ) return;
  275. tris=gx_scene->getTrianglesDrawn()-tris;
  276. static int time;
  277. int frame_ms=gx_runtime->getMilliSecs()-time;
  278. time+=frame_ms;
  279. int fps=frame_ms ? 1000/frame_ms : 1000;
  280. int ups=update_ms ? 1000/update_ms : 1000;
  281. int rps=render_ms ? 1000/render_ms : 1000;
  282. string t_fps="000"+itoa(fps);t_fps=t_fps.substr( t_fps.size()-4 );
  283. string t_ups="000"+itoa(ups);t_ups=t_ups.substr( t_ups.size()-4 );
  284. string t_rps="000"+itoa(rps);t_rps=t_rps.substr( t_rps.size()-4 );
  285. string t_tris="00000"+itoa(tris);t_tris=t_tris.substr( t_tris.size()-6 );
  286. string t="FPS:"+t_fps+" UPS:"+t_ups+" RPS:"+t_rps+" TRIS:"+t_tris;
  287. bbText( 0,bbGraphicsHeight()-bbFontHeight(),d_new BBStr(t),0,0 );
  288. }
  289. int bbTrisRendered(){
  290. return tri_count;
  291. }
  292. float bbStats3D( int n ){
  293. return stats3d[n];
  294. }
  295. //////////////////////
  296. // TEXTURE COMMANDS //
  297. //////////////////////
  298. //Note: modify canvas->backup() to NOT release backup image!
  299. //
  300. Texture * bbLoadTexture( BBStr *file,int flags ){
  301. debug3d();
  302. Texture *t=d_new Texture( *file,flags );delete file;
  303. if( !t->getCanvas(0) ){ delete t;return 0; }
  304. texture_set.insert( t );
  305. return t;
  306. }
  307. Texture * bbLoadAnimTexture( BBStr *file,int flags,int w,int h,int first,int cnt ){
  308. debug3d();
  309. Texture *t=d_new Texture( *file,flags,w,h,first,cnt );
  310. delete file;
  311. if( !t->getCanvas(0) ){
  312. delete t;
  313. return 0;
  314. }
  315. texture_set.insert( t );
  316. return t;
  317. }
  318. Texture * bbCreateTexture( int w,int h,int flags,int frames ){
  319. if( debug ){
  320. debug3d();
  321. if( frames<=0 ){
  322. RTEX( "Illegal number of texture frames" );
  323. }
  324. }
  325. Texture *t=d_new Texture( w,h,flags,frames );
  326. texture_set.insert( t );
  327. return t;
  328. }
  329. void bbFreeTexture( Texture *t ){
  330. if( !t ) return;
  331. debugTexture(t);
  332. if( texture_set.erase( t ) ) delete t;
  333. }
  334. void bbTextureBlend( Texture *t,int blend ){
  335. debugTexture(t);
  336. t->setBlend( blend );
  337. }
  338. void bbTextureCoords( Texture *t,int flags ){
  339. debugTexture(t);
  340. t->setFlags( flags );
  341. }
  342. void bbScaleTexture( Texture *t,float u_scale,float v_scale ){
  343. debugTexture(t);
  344. t->setScale( 1/u_scale,1/v_scale );
  345. }
  346. void bbRotateTexture( Texture *t,float angle ){
  347. debugTexture(t);
  348. t->setRotation( -angle*dtor );
  349. }
  350. void bbPositionTexture( Texture *t,float u_pos,float v_pos ){
  351. debugTexture(t);
  352. t->setPosition( -u_pos,-v_pos );
  353. }
  354. int bbTextureWidth( Texture *t ){
  355. debugTexture(t);
  356. return t->getCanvas(0)->getWidth();
  357. }
  358. int bbTextureHeight( Texture *t ){
  359. debugTexture(t);
  360. return t->getCanvas(0)->getHeight();
  361. }
  362. BBStr *bbTextureName( Texture *t ){
  363. debugTexture(t);
  364. CachedTexture *c=t->getCachedTexture();
  365. return c ? d_new BBStr( c->getName().c_str() ) : d_new BBStr("");
  366. }
  367. void bbSetCubeFace( Texture *t,int face ){
  368. debugTexture(t);
  369. if( gxCanvas *c=t->getCanvas( 0 ) ){
  370. c->setCubeFace(face);
  371. }
  372. }
  373. void bbSetCubeMode( Texture *t,int mode ){
  374. debugTexture(t);
  375. if( gxCanvas *c=t->getCanvas( 0 ) ){
  376. c->setCubeMode( mode );
  377. }
  378. }
  379. gxCanvas *bbTextureBuffer( Texture *t,int frame ){
  380. //v1.04
  381. debugTexture(t);
  382. if( gxCanvas *c=t->getCanvas( frame ) ){
  383. if( c->getDepth() ) return c;
  384. }
  385. return 0;
  386. /*
  387. //v1.03 crashes if t->getCanvas returns null!
  388. debugTexture(t);
  389. gxCanvas *c=t->getCanvas( frame );
  390. if( c->getDepth() ) return c;
  391. return 0;
  392. */
  393. }
  394. void bbClearTextureFilters(){
  395. debug3d();
  396. Texture::clearFilters();
  397. }
  398. void bbTextureFilter( BBStr *t,int flags ){
  399. debug3d();
  400. Texture::addFilter( *t,flags );
  401. delete t;
  402. }
  403. ////////////////////
  404. // BRUSH COMMANDS //
  405. ////////////////////
  406. Brush * bbCreateBrush( float r,float g,float b ){
  407. debug3d();
  408. Brush *br=d_new Brush();
  409. br->setColor( Vector( r*ctof,g*ctof,b*ctof ) );
  410. brush_set.insert( br );
  411. return br;
  412. }
  413. Brush * bbLoadBrush( BBStr *file,int flags,float u_scale,float v_scale ){
  414. debug3d();
  415. Texture t( *file,flags );
  416. delete file;if( !t.getCanvas(0) ) return 0;
  417. if( u_scale!=1 || v_scale!=1 ) t.setScale( 1/u_scale,1/v_scale );
  418. Brush *br=bbCreateBrush( 255,255,255 );
  419. br->setTexture( 0,t,0 );
  420. delete file;
  421. return br;
  422. }
  423. void bbFreeBrush( Brush *b ){
  424. if( !b ) return;
  425. debugBrush(b);
  426. if( brush_set.erase( b ) ) delete b;
  427. }
  428. void bbBrushColor( Brush *br,float r,float g,float b ){
  429. debugBrush(br);
  430. br->setColor( Vector( r*ctof,g*ctof,b*ctof ) );
  431. }
  432. void bbBrushAlpha( Brush *b,float alpha ){
  433. debugBrush(b);
  434. b->setAlpha( alpha );
  435. }
  436. void bbBrushShininess( Brush *b,float n ){
  437. debugBrush(b);
  438. b->setShininess( n );
  439. }
  440. void bbBrushTexture( Brush *b,Texture *t,int frame,int index ){
  441. debugBrush(b);
  442. debugTexture(t);
  443. b->setTexture( index,*t,frame );
  444. }
  445. Texture *bbGetBrushTexture( Brush *b,int index ){
  446. debugBrush(b);
  447. Texture *tex=d_new Texture(b->getTexture(index));
  448. texture_set.insert( tex );
  449. return tex;
  450. }
  451. void bbBrushBlend( Brush *b,int blend ){
  452. debugBrush(b);
  453. b->setBlend( blend );
  454. }
  455. void bbBrushFX( Brush *b,int fx ){
  456. debugBrush(b);
  457. b->setFX( fx );
  458. }
  459. ///////////////////
  460. // MESH COMMANDS //
  461. ///////////////////
  462. Entity * bbCreateMesh( Entity *p ){
  463. debugParent(p);
  464. MeshModel *m=d_new MeshModel();
  465. return insertEntity( m,p );
  466. }
  467. Entity * bbLoadMesh( BBStr *f,Entity *p ){
  468. debugParent(p);
  469. Entity *e=loadEntity( f->c_str(),MeshLoader::HINT_COLLAPSE );
  470. delete f;
  471. if( !e ) return 0;
  472. MeshModel *m=d_new MeshModel();
  473. collapseMesh( m,e );
  474. return insertEntity( m,p );
  475. }
  476. Entity * bbLoadAnimMesh( BBStr *f,Entity *p ){
  477. debugParent(p);
  478. Entity *e=loadEntity( f->c_str(),0 );
  479. delete f;
  480. if( !e ) return 0;
  481. if( Animator *anim=e->getObject()->getAnimator() ){
  482. anim->animate( 1,0,0,0 );
  483. }
  484. return insertEntity( e,p );
  485. }
  486. Entity * bbCreateCube( Entity *p ){
  487. debugParent(p);
  488. Entity *e=MeshUtil::createCube( Brush() );
  489. return insertEntity( e,p );
  490. }
  491. Entity * bbCreateSphere( int segs,Entity *p ){
  492. if( debug ){ debugParent(p);if( segs<2 || segs>100 ) RTEX( "Illegal number of segments" ); }
  493. Entity *e=MeshUtil::createSphere( Brush(),segs );
  494. return insertEntity( e,p );
  495. }
  496. Entity * bbCreateCylinder( int segs,int solid,Entity *p ){
  497. if( debug ){ debugParent(p);if( segs<3 || segs>100 ) RTEX( "Illegal number of segments" ); }
  498. Entity *e=MeshUtil::createCylinder( Brush(),segs,!!solid );
  499. return insertEntity( e,p );
  500. }
  501. Entity * bbCreateCone( int segs,int solid,Entity *p ){
  502. if( debug ){ debugParent(p);if( segs<3 || segs>100 ) RTEX( "Illegal number of segments" ); }
  503. Entity *e=MeshUtil::createCone( Brush(),segs,!!solid );
  504. return insertEntity( e,p );
  505. }
  506. Entity * bbCopyMesh( MeshModel *m,Entity *p ){
  507. debugMesh(m);
  508. debugParent(p);
  509. MeshModel *t=d_new MeshModel();
  510. t->add( *m );
  511. return insertEntity( t,p );
  512. }
  513. void bbScaleMesh( MeshModel *m,float x,float y,float z ){
  514. debugMesh(m);
  515. m->transform( scaleMatrix(x,y,z) );
  516. }
  517. void bbRotateMesh( MeshModel *m,float x,float y,float z ){
  518. debugMesh(m);
  519. m->transform( rotationMatrix(x*dtor,y*dtor,z*dtor) );
  520. }
  521. void bbPositionMesh( MeshModel *m,float x,float y,float z ){
  522. debugMesh(m);
  523. m->transform( Vector(x,y,z) );
  524. }
  525. void bbFitMesh( MeshModel *m,float x,float y,float z,float w,float h,float d,int uniform ){
  526. debugMesh(m);
  527. Box box( Vector(x,y,z) );
  528. box.update( Vector(x+w,y+h,z+d) );
  529. const Box &curr_box=m->getBox();
  530. float x_scale=box.width()/curr_box.width();
  531. float y_scale=box.height()/curr_box.height();
  532. float z_scale=box.depth()/curr_box.depth();
  533. Transform t;
  534. if( uniform ){
  535. if( x_scale<y_scale && x_scale<z_scale ){
  536. y_scale=z_scale=x_scale;
  537. }else if( y_scale<x_scale && y_scale<z_scale ){
  538. x_scale=z_scale=y_scale;
  539. }else{
  540. x_scale=y_scale=z_scale;
  541. }
  542. }
  543. t.m.i.x=x_scale;
  544. t.m.j.y=y_scale;
  545. t.m.k.z=z_scale;
  546. t.v=box.centre() - t.m * curr_box.centre();
  547. m->transform( t );
  548. }
  549. void bbFlipMesh( MeshModel *m ){
  550. debugMesh(m);
  551. m->flipTriangles();
  552. }
  553. void bbPaintMesh( MeshModel *m,Brush *b ){
  554. if( debug ){ debugMesh(m);debugBrush(b); }
  555. m->paint( *b );
  556. }
  557. void bbAddMesh( MeshModel *src,MeshModel *dest ){
  558. if( debug ){
  559. debugMesh(src);debugMesh(dest);
  560. if( src==dest ) RTEX( "A mesh cannot be added to itself" );
  561. }
  562. dest->add( *src );
  563. }
  564. void bbUpdateNormals( MeshModel *m ){
  565. debugMesh(m);
  566. m->updateNormals();
  567. }
  568. void bbLightMesh( MeshModel *m,float r,float g,float b,float range,float x,float y,float z ){
  569. debugMesh(m);
  570. MeshUtil::lightMesh( m,Vector(x,y,z),Vector(r*ctof,g*ctof,b*ctof),range );
  571. }
  572. float bbMeshWidth( MeshModel *m ){
  573. debugMesh(m);
  574. return m->getBox().width();
  575. }
  576. float bbMeshHeight( MeshModel *m ){
  577. debugMesh(m);
  578. return m->getBox().height();
  579. }
  580. float bbMeshDepth( MeshModel *m ){
  581. debugMesh(m);
  582. return m->getBox().depth();
  583. }
  584. int bbMeshesIntersect( MeshModel *a,MeshModel *b ){
  585. if( debug ){ debugMesh(a);debugMesh(b); }
  586. return a->intersects( *b );
  587. }
  588. int bbCountSurfaces( MeshModel *m ){
  589. debugMesh(m);
  590. return m->getSurfaces().size();
  591. }
  592. Surface * bbGetSurface( MeshModel *m,int index ){
  593. if( debug ){
  594. debugMesh(m);
  595. if( index<1 || index>m->getSurfaces().size() ){
  596. RTEX( "Surface Index out of range" );
  597. }
  598. }
  599. return m->getSurfaces()[index-1];
  600. }
  601. void bbMeshCullBox( MeshModel *m,float x,float y,float z,float width,float height,float depth ){
  602. if( debug ){
  603. debugMesh( m );
  604. }
  605. m->setCullBox( Box( Vector(x,y,z),Vector(x+width,y+height,z+depth) ) );
  606. }
  607. //////////////////////
  608. // SURFACE COMMANDS //
  609. //////////////////////
  610. Surface * bbFindSurface( MeshModel *m,Brush *b ){
  611. if( debug ){ debugMesh(m);debugBrush(b); }
  612. return m->findSurface(*b);
  613. }
  614. Surface * bbCreateSurface( MeshModel *m,Brush *b ){
  615. if( debug ){ debugMesh(m);if( b ) debugBrush(b); }
  616. Surface *s=b ? m->createSurface( *b ) : m->createSurface( Brush() );
  617. return s;
  618. }
  619. Brush *bbGetSurfaceBrush( Surface *s ){
  620. Brush *br=d_new Brush( s->getBrush() );
  621. brush_set.insert( br );
  622. return br;
  623. }
  624. Brush *bbGetEntityBrush( Model *m ){
  625. debugModel(m);
  626. Brush *br=d_new Brush( m->getBrush() );
  627. brush_set.insert( br );
  628. return br;
  629. }
  630. void bbClearSurface( Surface *s,int verts,int tris ){
  631. s->clear( !!verts,!!tris );
  632. }
  633. void bbPaintSurface( Surface *s,Brush *b ){
  634. debugBrush(b);
  635. s->setBrush(*b);
  636. }
  637. int bbAddVertex( Surface *s,float x,float y,float z,float tu,float tv,float tw ){
  638. Surface::Vertex v;
  639. v.coords=Vector(x,y,z);
  640. v.color=0xffffffff;
  641. v.tex_coords[0][0]=v.tex_coords[1][0]=tu;
  642. v.tex_coords[0][1]=v.tex_coords[1][1]=tv;
  643. s->addVertex( v );
  644. return s->numVertices()-1;
  645. }
  646. int bbAddTriangle( Surface *s,int v0,int v1,int v2 ){
  647. Surface::Triangle t;
  648. t.verts[0]=v0;t.verts[1]=v1;t.verts[2]=v2;
  649. s->addTriangle( t );
  650. return s->numTriangles()-1;
  651. }
  652. void bbVertexCoords( Surface *s,int n,float x,float y,float z ){
  653. s->setCoords( n,Vector(x,y,z) );
  654. }
  655. void bbVertexNormal( Surface *s,int n,float x,float y,float z ){
  656. s->setNormal( n,Vector(x,y,z) );
  657. }
  658. void bbVertexColor( Surface *s,int n,float r,float g,float b,float a ){
  659. if(r<0)r=0;else if(r>255)r=255;
  660. if(g<0)g=0;else if(g>255)g=255;
  661. if(b<0)b=0;else if(b>255)b=255;
  662. a*=255;if(a<0)a=0;else if(a>255)a=255;
  663. s->setColor( n,(int(a)<<24)|(int(r)<<16)|(int(g)<<8)|int(b) );
  664. }
  665. void bbVertexTexCoords( Surface *s,int n,float u,float v,float w,int set ){
  666. s->setTexCoords( n,Vector(u,v,w),set );
  667. }
  668. int bbCountVertices( Surface *s ){
  669. return s->numVertices();
  670. }
  671. int bbCountTriangles( Surface *s ){
  672. return s->numTriangles();
  673. }
  674. float bbVertexX( Surface *s,int n ){
  675. debugVertex(s,n);
  676. return s->getVertex(n).coords.x;
  677. }
  678. float bbVertexY( Surface *s,int n ){
  679. debugVertex(s,n);
  680. return s->getVertex(n).coords.y;
  681. }
  682. float bbVertexZ( Surface *s,int n ){
  683. debugVertex(s,n);
  684. return s->getVertex(n).coords.z;
  685. }
  686. float bbVertexNX( Surface *s,int n ){
  687. debugVertex(s,n);
  688. return s->getVertex(n).normal.x;
  689. }
  690. float bbVertexNY( Surface *s,int n ){
  691. debugVertex(s,n);
  692. return s->getVertex(n).normal.y;
  693. }
  694. float bbVertexNZ( Surface *s,int n ){
  695. debugVertex(s,n);
  696. return s->getVertex(n).normal.z;
  697. }
  698. float bbVertexRed( Surface *s,int n ){
  699. debugVertex(s,n);
  700. return (s->getVertex(n).color&0xff0000)>>16;
  701. }
  702. float bbVertexGreen( Surface *s,int n ){
  703. debugVertex(s,n);
  704. return (s->getVertex(n).color&0xff00)>>8;
  705. }
  706. float bbVertexBlue( Surface *s,int n ){
  707. debugVertex(s,n);
  708. return s->getVertex(n).color&0xff;
  709. }
  710. float bbVertexAlpha( Surface *s,int n ){
  711. debugVertex(s,n);
  712. return ((s->getVertex(n).color&0xff000000)>>24)/255.0f;
  713. }
  714. float bbVertexU( Surface *s,int n,int t ){
  715. debugVertex(s,n,t);
  716. return s->getVertex(n).tex_coords[t][0];
  717. }
  718. float bbVertexV( Surface *s,int n,int t ){
  719. debugVertex(s,n,t);
  720. return s->getVertex(n).tex_coords[t][1];
  721. }
  722. float bbVertexW( Surface *s,int n,int t ){
  723. debugVertex(s,n,t);
  724. return 1;
  725. }
  726. int bbTriangleVertex( Surface *s,int n,int v ){
  727. return s->getTriangle(n).verts[v];
  728. }
  729. /////////////////////
  730. // CAMERA COMMANDS //
  731. /////////////////////
  732. Entity * bbCreateCamera( Entity *p ){
  733. debugParent(p);
  734. int x,y,w,h;
  735. gx_canvas->getViewport( &x,&y,&w,&h );
  736. Camera *c=d_new Camera();
  737. c->setViewport( x,y,w,h );
  738. return insertEntity( c,p );
  739. }
  740. void bbCameraZoom( Camera *c,float zoom ){
  741. debugCamera(c);
  742. c->setZoom( zoom );
  743. }
  744. void bbCameraRange( Camera *c,float nr,float fr ){
  745. debugCamera(c);
  746. c->setRange( nr,fr );
  747. }
  748. void bbCameraClsColor( Camera *c,float r,float g,float b ){
  749. debugCamera(c);
  750. c->setClsColor( Vector( r*ctof,g*ctof,b*ctof ) );
  751. }
  752. void bbCameraClsMode( Camera *c,int cls_color,int cls_zbuffer ){
  753. debugCamera(c);
  754. c->setClsMode( cls_color ? true : false,cls_zbuffer ? true : false );
  755. }
  756. void bbCameraProjMode( Camera *c,int mode ){
  757. debugCamera(c);
  758. c->setProjMode( mode );
  759. }
  760. void bbCameraViewport( Camera *c,int x,int y,int w,int h ){
  761. debugCamera(c);
  762. c->setViewport( x,y,w,h );
  763. }
  764. void bbCameraFogRange( Camera *c,float nr,float fr ){
  765. debugCamera(c);
  766. c->setFogRange( nr,fr );
  767. }
  768. void bbCameraFogColor( Camera *c,float r,float g,float b ){
  769. debugCamera(c);
  770. c->setFogColor( Vector( r*ctof,g*ctof,b*ctof ) );
  771. }
  772. void bbCameraFogMode( Camera *c,int mode ){
  773. debugCamera(c);
  774. c->setFogMode( mode );
  775. }
  776. int bbCameraProject( Camera *c,float x,float y,float z ){
  777. debugCamera(c);
  778. Vector v=-c->getWorldTform()*Vector(x,y,z);
  779. const Frustum &f=c->getFrustum();
  780. if( c->getProjMode()==Camera::PROJ_ORTHO ){
  781. int vp_x,vp_y,vp_w,vp_h;
  782. c->getViewport( &vp_x,&vp_y,&vp_w,&vp_h );
  783. float nr=c->getFrustumNear();
  784. float fr=c->getFrustumFar();
  785. float nr_w=c->getFrustumWidth();
  786. float nr_h=c->getFrustumHeight();
  787. projected=Vector( (v.x/nr_w+.5f)*vp_w,(.5f-v.y/nr_h)*vp_h,nr );
  788. return 1;
  789. }
  790. if( v.z>0 ){
  791. float fr=+f.getPlane( Frustum::PLANE_FAR ).d;
  792. if( v.z<=fr ){
  793. int vp_x,vp_y,vp_w,vp_h;
  794. c->getViewport( &vp_x,&vp_y,&vp_w,&vp_h );
  795. float nr=c->getFrustumNear();
  796. float fr=c->getFrustumFar();
  797. float nr_w=c->getFrustumWidth();
  798. float nr_h=c->getFrustumHeight();
  799. projected=Vector(
  800. (v.x*nr/v.z/nr_w+.5f)*vp_w,
  801. (.5f-v.y*nr/v.z/nr_h)*vp_h,nr );
  802. return 1;
  803. }
  804. }
  805. projected=Vector();
  806. return 0;
  807. }
  808. float bbProjectedX(){
  809. return projected.x;
  810. }
  811. float bbProjectedY(){
  812. return projected.y;
  813. }
  814. float bbProjectedZ(){
  815. return projected.z;
  816. }
  817. static Object *doPick( const Line &l,float radius ){
  818. picked.collision.time=1;
  819. return world->traceRay( l,radius,&picked );
  820. }
  821. Entity * bbCameraPick( Camera *c,float x,float y ){
  822. debugCamera(c);
  823. int vp_x,vp_y,vp_w,vp_h;
  824. c->getViewport( &vp_x,&vp_y,&vp_w,&vp_h );
  825. float nr=c->getFrustumNear();
  826. float fr=c->getFrustumFar();
  827. float nr_w=c->getFrustumWidth();
  828. float nr_h=c->getFrustumHeight();
  829. x=((x/vp_w)-.5f)*nr_w;
  830. y=(.5f-(y/vp_h))*nr_h;
  831. Line l;
  832. if( c->getProjMode()==Camera::PROJ_ORTHO ){
  833. l=c->getWorldTform() * Line( Vector(x,y,0),Vector(0,0,fr) ); //x,y,fr) );
  834. }else{
  835. x/=nr;y/=nr;
  836. l=c->getWorldTform() * Line( Vector(),Vector( x*fr,y*fr,fr ) );
  837. }
  838. return doPick( l,0 );
  839. }
  840. Entity * bbLinePick( float x,float y,float z,float dx,float dy,float dz,float radius ){
  841. debug3d();
  842. Line l( Vector( x,y,z ),Vector( dx,dy,dz ) );
  843. return doPick( l,radius );
  844. }
  845. Entity * bbEntityPick( Object *src,float range ){
  846. debugEntity(src);
  847. Line l( src->getWorldPosition(),src->getWorldTform().m.k * range );
  848. return doPick( l,0 );
  849. }
  850. int bbEntityVisible( Object *src,Object *dest ){
  851. if( debug ){ debugObject(src);debugObject(dest); }
  852. return world->checkLOS( src,dest ) ? 1 : 0;
  853. }
  854. int bbEntityInView( Entity *e,Camera *c ){
  855. if( debug ){ debugEntity(e);debugCamera(c); }
  856. if( Model *p=e->getModel() ){
  857. if( MeshModel *m=p->getMeshModel() ){
  858. const Box &b=m->getBox();
  859. Transform t=-c->getWorldTform() * e->getWorldTform();
  860. Vector p[]={
  861. t*b.corner(0),t*b.corner(1),t*b.corner(2),t*b.corner(3),
  862. t*b.corner(4),t*b.corner(5),t*b.corner(6),t*b.corner(7)
  863. };
  864. return c->getFrustum().cull( p,8 );
  865. }
  866. }
  867. Vector p[]={ -c->getWorldTform() * e->getWorldPosition() };
  868. return c->getFrustum().cull( p,1 );
  869. }
  870. float bbPickedX(){
  871. return picked.coords.x;
  872. }
  873. float bbPickedY(){
  874. return picked.coords.y;
  875. }
  876. float bbPickedZ(){
  877. return picked.coords.z;
  878. }
  879. float bbPickedNX(){
  880. return picked.collision.normal.x;
  881. }
  882. float bbPickedNY(){
  883. return picked.collision.normal.y;
  884. }
  885. float bbPickedNZ(){
  886. return picked.collision.normal.z;
  887. }
  888. float bbPickedTime(){
  889. return picked.collision.time;
  890. }
  891. Object * bbPickedEntity(){
  892. return picked.with;
  893. }
  894. void * bbPickedSurface(){
  895. return picked.collision.surface;
  896. }
  897. int bbPickedTriangle(){
  898. return picked.collision.index;
  899. }
  900. ////////////////////
  901. // LIGHT COMMANDS //
  902. ////////////////////
  903. Entity * bbCreateLight( int type,Entity *p ){
  904. debugParent(p);
  905. Light *t=d_new Light( type );
  906. return insertEntity( t,p );
  907. }
  908. void bbLightColor( Light *light,float r,float g,float b ){
  909. debugLight(light);
  910. light->setColor( Vector(r*ctof,g*ctof,b*ctof) );
  911. }
  912. void bbLightRange( Light *light,float range ){
  913. debugLight(light);
  914. light->setRange( range );
  915. }
  916. void bbLightConeAngles( Light *light,float inner,float outer ){
  917. debugLight(light);
  918. inner*=dtor;
  919. outer*=dtor;
  920. if( inner<0 ) inner=0;
  921. else if( inner>PI ) inner=PI;
  922. if( outer<inner ) outer=inner;
  923. else if( outer>PI ) outer=PI;
  924. light->setConeAngles( inner,outer );
  925. }
  926. ////////////////////
  927. // PIVOT COMMANDS //
  928. ////////////////////
  929. Entity * bbCreatePivot( Entity *p ){
  930. debugParent(p);
  931. Pivot *t=d_new Pivot();
  932. return insertEntity( t,p );
  933. }
  934. /////////////////////
  935. // SPRITE COMMANDS //
  936. /////////////////////
  937. Entity * bbCreateSprite( Entity *p ){
  938. debugParent(p);
  939. Sprite *s=d_new Sprite();
  940. s->setFX( gxScene::FX_FULLBRIGHT );
  941. return insertEntity( s,p );
  942. }
  943. Entity * bbLoadSprite( BBStr *file,int flags,Entity *p ){
  944. debugParent(p);
  945. Texture t( *file,flags );
  946. delete file;if( !t.getCanvas(0) ) return 0;
  947. Sprite *s=d_new Sprite();
  948. s->setTexture( 0,t,0 );
  949. s->setFX( gxScene::FX_FULLBRIGHT );
  950. if( flags & gxCanvas::CANVAS_TEX_MASK ) s->setBlend( gxScene::BLEND_REPLACE );
  951. else if( flags & gxCanvas::CANVAS_TEX_ALPHA ) s->setBlend( gxScene::BLEND_ALPHA );
  952. else s->setBlend( gxScene::BLEND_ADD );
  953. return insertEntity( s,p );
  954. }
  955. void bbRotateSprite( Sprite *s,float angle ){
  956. debugSprite(s);
  957. s->setRotation( angle*dtor );
  958. }
  959. void bbScaleSprite( Sprite *s,float x,float y ){
  960. debugSprite(s);
  961. s->setScale( x,y );
  962. }
  963. void bbHandleSprite( Sprite *s,float x,float y ){
  964. debugSprite(s);
  965. s->setHandle( x,y );
  966. }
  967. void bbSpriteViewMode( Sprite *s,int mode ){
  968. debugSprite(s);
  969. s->setViewmode( mode );
  970. }
  971. /////////////////////
  972. // MIRROR COMMANDS //
  973. /////////////////////
  974. Entity * bbCreateMirror( Entity *p ){
  975. debugParent(p);
  976. Mirror *t=d_new Mirror();
  977. return insertEntity( t,p );
  978. }
  979. ////////////////////
  980. // PLANE COMMANDS //
  981. ////////////////////
  982. Entity * bbCreatePlane( int segs,Entity *p ){
  983. if( debug ){
  984. debugParent(p);
  985. if( segs<1 || segs>20 ) RTEX( "Illegal number of segments" );
  986. }
  987. PlaneModel *t=d_new PlaneModel( segs );
  988. return insertEntity( t,p );
  989. }
  990. //////////////////
  991. // MD2 COMMANDS //
  992. //////////////////
  993. Entity * bbLoadMD2( BBStr *file,Entity *p ){
  994. debugParent(p);
  995. MD2Model *t=d_new MD2Model( *file );delete file;
  996. if( !t->getValid() ){ delete t;return 0; }
  997. return insertEntity( t,p );
  998. }
  999. void bbAnimateMD2( MD2Model *m,int mode,float speed,int first,int last,float trans ){
  1000. debugMD2(m);
  1001. m->startMD2Anim( first,last,mode,speed,trans );
  1002. }
  1003. float bbMD2AnimTime( MD2Model *m ){
  1004. debugMD2(m);
  1005. return m->getMD2AnimTime();
  1006. }
  1007. int bbMD2AnimLength( MD2Model *m ){
  1008. debugMD2(m);
  1009. return m->getMD2AnimLength();
  1010. }
  1011. int bbMD2Animating( MD2Model *m ){
  1012. debugMD2(m);
  1013. return m->getMD2Animating();
  1014. }
  1015. //////////////////
  1016. // BSP Commands //
  1017. //////////////////
  1018. Entity * bbLoadBSP( BBStr *file,float gam,Entity *p ){
  1019. debugParent(p);
  1020. CachedTexture::setPath( filenamepath( *file ) );
  1021. Q3BSPModel *t=d_new Q3BSPModel( *file,gam );delete file;
  1022. CachedTexture::setPath( "" );
  1023. if( !t->isValid() ){ delete t;return 0; }
  1024. return insertEntity( t,p );
  1025. }
  1026. void bbBSPAmbientLight( Q3BSPModel *t,float r,float g,float b ){
  1027. debugBSP(t);
  1028. t->setAmbient( Vector( r*ctof,g*ctof,b*ctof ) );
  1029. }
  1030. void bbBSPLighting( Q3BSPModel *t,int lmap ){
  1031. debugBSP(t);
  1032. t->setLighting( !!lmap );
  1033. }
  1034. //////////////////////
  1035. // TERRAIN COMMANDS //
  1036. //////////////////////
  1037. static float terrainHeight( Terrain *t,float x,float z ){
  1038. int ix=floor(x);
  1039. int iz=floor(z);
  1040. float tx=x-ix,tz=z-iz;
  1041. float h0=t->getHeight(ix,iz);
  1042. float h1=t->getHeight(ix+1,iz);
  1043. float h2=t->getHeight(ix,iz+1);
  1044. float h3=t->getHeight(ix+1,iz+1);
  1045. float ha=(h1-h0)*tx+h0,hb=(h3-h2)*tx+h2;
  1046. float h=(hb-ha)*tz+ha;
  1047. return h;
  1048. }
  1049. static Vector terrainVector( Terrain *t,float x,float y,float z ){
  1050. Vector v=-t->getWorldTform() * Vector( x,y,z );
  1051. return t->getWorldTform() * Vector( v.x,terrainHeight( t,v.x,v.z ),v.z );
  1052. }
  1053. Entity * bbCreateTerrain( int n,Entity *p ){
  1054. debugParent(p);
  1055. int shift=0;
  1056. while( (1<<shift)<n ) ++shift;
  1057. if( (1<<shift)!=n ) RTEX( "Illegal terrain size" );
  1058. Terrain *t=d_new Terrain( shift );
  1059. return insertEntity( t,p );
  1060. }
  1061. Entity * bbLoadTerrain( BBStr *file,Entity *p ){
  1062. debugParent(p);
  1063. gxCanvas *c=gx_graphics->loadCanvas( *file,gxCanvas::CANVAS_HIGHCOLOR );
  1064. if( !c ) RTEX( "Unable to load heightmap image" );
  1065. int w=c->getWidth(),h=c->getHeight();
  1066. if( w!=h ) RTEX( "Terrain must be square" );
  1067. int shift=0;
  1068. while( (1<<shift)<w ) ++shift;
  1069. if( (1<<shift)!=w ) RTEX( "Illegal terrain size" );
  1070. Terrain *t=d_new Terrain( shift );
  1071. c->lock();
  1072. for( int y=0;y<h;++y ){
  1073. for( int x=0;x<w;++x ){
  1074. int rgb=c->getPixelFast( x,y );
  1075. int r=(rgb>>16)&0xff,g=(rgb>>8)&0xff,b=rgb&0xff;
  1076. float p=(r>g?(r>b?r:b):(g>b?g:b))/255.0f;
  1077. t->setHeight( x,h-1-y,p,false );
  1078. }
  1079. }
  1080. c->unlock();
  1081. gx_graphics->freeCanvas( c );
  1082. return insertEntity( t,p );
  1083. }
  1084. void bbTerrainDetail( Terrain *t,int n,int m ){
  1085. debugTerrain(t);
  1086. t->setDetail( n,!!m );
  1087. }
  1088. void bbTerrainShading( Terrain *t,int enable ){
  1089. debugTerrain(t);
  1090. t->setShading( !!enable );
  1091. }
  1092. float bbTerrainX( Terrain *t,float x,float y,float z ){
  1093. debugTerrain(t);
  1094. return terrainVector( t,x,y,z ).x;
  1095. }
  1096. float bbTerrainY( Terrain *t,float x,float y,float z ){
  1097. debugTerrain(t);
  1098. return terrainVector( t,x,y,z ).y;
  1099. }
  1100. float bbTerrainZ( Terrain *t,float x,float y,float z ){
  1101. debugTerrain(t);
  1102. return terrainVector( t,x,y,z ).z;
  1103. }
  1104. int bbTerrainSize( Terrain *t ){
  1105. debugTerrain(t);
  1106. return t->getSize();
  1107. }
  1108. float bbTerrainHeight( Terrain *t,int x,int z ){
  1109. debugTerrain(t);
  1110. return t->getHeight( x,z );
  1111. }
  1112. void bbModifyTerrain( Terrain *t,int x,int z,float h,int realtime ){
  1113. debugTerrain(t);
  1114. t->setHeight( x,z,h,!!realtime );
  1115. }
  1116. ////////////////////
  1117. // AUDIO COMMANDS //
  1118. ////////////////////
  1119. Entity * bbCreateListener( Entity *p,float roll,float dopp,float dist ){
  1120. if( debug ){
  1121. debugParent(p);
  1122. if( listener ) RTEX( "Listener already created" );
  1123. }
  1124. listener=d_new Listener( roll,dopp,dist );
  1125. return insertEntity( listener,p );
  1126. }
  1127. gxChannel * bbEmitSound( gxSound *sound,Object *o ){
  1128. if( debug ){
  1129. debugObject(o);
  1130. if( !listener ) RTEX( "No Listener created" );
  1131. }
  1132. return o->emitSound( sound );
  1133. }
  1134. /////////////////////
  1135. // ENTITY COMMANDS //
  1136. /////////////////////
  1137. Entity * bbCopyEntity( Entity *e,Entity *p ){
  1138. if( debug ){
  1139. debugEntity(e);
  1140. debugParent(p);
  1141. }
  1142. Entity *t=e->getObject()->copy();
  1143. if( !t ) return 0;
  1144. return insertEntity( t,p );
  1145. }
  1146. void bbFreeEntity( Entity *e ){
  1147. if( !e ) return;
  1148. if( debug ){
  1149. debugEntity(e);
  1150. erase(e);
  1151. }
  1152. delete e;
  1153. }
  1154. void bbHideEntity( Entity *e ){
  1155. debugEntity(e);
  1156. e->setEnabled(false);
  1157. e->setVisible(false);
  1158. }
  1159. void bbShowEntity( Entity *e ){
  1160. debugEntity(e);
  1161. e->setVisible(true);
  1162. e->setEnabled(true);
  1163. e->getObject()->reset();
  1164. }
  1165. void bbEntityParent( Entity *e,Entity *p,int global ){
  1166. if( debug ){
  1167. debugEntity(e);
  1168. debugParent(p);
  1169. Entity *t=p;
  1170. while( t ){
  1171. if( t==e ){
  1172. RTEX( "Entity cannot be parented to itself!" );
  1173. }
  1174. t=t->getParent();
  1175. }
  1176. }
  1177. if( e->getParent()==p ) return;
  1178. if( global ){
  1179. Transform t=e->getWorldTform();
  1180. e->setParent( p );
  1181. e->setWorldTform( t );
  1182. }else{
  1183. e->setParent( p );
  1184. e->getObject()->reset();
  1185. }
  1186. }
  1187. int bbCountChildren( Entity *e ){
  1188. debugEntity(e);
  1189. int n=0;
  1190. for( Entity *p=e->children();p;p=p->successor() ) ++n;
  1191. return n;
  1192. }
  1193. Entity * bbGetChild( Entity *e,int index ){
  1194. debugEntity(e);
  1195. Entity *p=e->children();
  1196. while( --index && p ) p=p->successor();
  1197. return p;
  1198. }
  1199. Entity * bbFindChild( Entity *e,BBStr *t ){
  1200. debugEntity(e);
  1201. e=findChild( e,*t );
  1202. delete t;
  1203. return e;
  1204. }
  1205. ////////////////////////
  1206. // ANIMATION COMMANDS //
  1207. ////////////////////////
  1208. int bbLoadAnimSeq( Object *o,BBStr *f ){
  1209. debugObject( o );
  1210. if( Animator *anim=o->getAnimator() ){
  1211. Entity *t=loadEntity( f->c_str(),MeshLoader::HINT_ANIMONLY );
  1212. delete f;
  1213. if( t ){
  1214. if( Animator *p=t->getObject()->getAnimator() ){
  1215. anim->addSeqs( p );
  1216. }
  1217. delete t;
  1218. }
  1219. return anim->numSeqs()-1;
  1220. }else{
  1221. delete f;
  1222. }
  1223. return -1;
  1224. }
  1225. void bbSetAnimTime( Object *o,float time,int seq ){
  1226. debugObject( o );
  1227. if( Animator *anim=o->getAnimator() ){
  1228. anim->setAnimTime( time,seq );
  1229. }else{
  1230. RTEX( "Entity has not animation" );
  1231. }
  1232. }
  1233. void bbAnimate( Object *o,int mode,float speed,int seq,float trans ){
  1234. debugObject( o );
  1235. if( Animator *anim=o->getAnimator() ){
  1236. anim->animate( mode,speed,seq,trans );
  1237. }else{
  1238. RTEX( "Entity has no animation" );
  1239. }
  1240. }
  1241. void bbSetAnimKey( Object *o,int frame,int pos_key,int rot_key,int scl_key ){
  1242. debugObject( o );
  1243. Animation anim=o->getAnimation();
  1244. if( pos_key ) anim.setPositionKey( frame,o->getLocalPosition() );
  1245. if( rot_key ) anim.setRotationKey( frame,o->getLocalRotation() );
  1246. if( scl_key ) anim.setScaleKey( frame,o->getLocalScale() );
  1247. o->setAnimation( anim );
  1248. }
  1249. int bbExtractAnimSeq( Object *o,int first,int last,int seq ){
  1250. debugObject( o );
  1251. if( Animator *anim=o->getAnimator() ){
  1252. anim->extractSeq( first,last,seq );
  1253. return anim->numSeqs()-1;
  1254. }
  1255. return -1;
  1256. }
  1257. int bbAddAnimSeq( Object *o,int length ){
  1258. debugObject( o );
  1259. Animator *anim=o->getAnimator();
  1260. if( anim ){
  1261. anim->addSeq( length );
  1262. }else{
  1263. anim=d_new Animator( o,length );
  1264. o->setAnimator( anim );
  1265. }
  1266. return anim->numSeqs()-1;
  1267. }
  1268. int bbAnimSeq( Object *o ){
  1269. debugObject(o);
  1270. if( Animator *anim=o->getAnimator() ) return anim->animSeq();
  1271. return -1;
  1272. }
  1273. float bbAnimTime( Object *o ){
  1274. debugObject(o);
  1275. if( Animator *anim=o->getAnimator() ) return anim->animTime();
  1276. return -1;
  1277. }
  1278. int bbAnimLength( Object *o ){
  1279. debugObject(o);
  1280. if( Animator *anim=o->getAnimator() ) return anim->animLen();
  1281. return -1;
  1282. }
  1283. int bbAnimating( Object *o ){
  1284. debugObject(o);
  1285. if( Animator *anim=o->getAnimator() ) return anim->animating();
  1286. return 0;
  1287. }
  1288. ////////////////////////////////
  1289. // ENTITY SPECIAL FX COMMANDS //
  1290. ////////////////////////////////
  1291. void bbPaintEntity( Model *m,Brush *b ){
  1292. if( debug ){
  1293. debugModel(m);
  1294. debugBrush(b);
  1295. }
  1296. m->setBrush( *b );
  1297. }
  1298. void bbEntityColor( Model *m,float r,float g,float b ){
  1299. debugModel(m);
  1300. m->setColor( Vector( r*ctof,g*ctof,b*ctof ) );
  1301. }
  1302. void bbEntityAlpha( Model *m,float alpha ){
  1303. debugModel(m);
  1304. m->setAlpha( alpha );
  1305. }
  1306. void bbEntityShininess( Model *m,float shininess ){
  1307. debugModel(m);
  1308. m->setShininess( shininess );
  1309. }
  1310. void bbEntityTexture( Model *m,Texture *t,int frame,int index ){
  1311. debugModel(m);
  1312. debugTexture(t);
  1313. m->setTexture( index,*t,frame );
  1314. }
  1315. void bbEntityBlend( Model *m,int blend ){
  1316. debugModel(m);
  1317. m->setBlend( blend );
  1318. }
  1319. void bbEntityFX( Model *m,int fx ){
  1320. debugModel(m);
  1321. m->setFX( fx );
  1322. }
  1323. void bbEntityAutoFade( Model *m,float nr,float fr ){
  1324. debugModel(m);
  1325. m->setAutoFade( nr,fr );
  1326. }
  1327. void bbEntityOrder( Object *o,int n ){
  1328. if( debug ){
  1329. debugEntity(o);
  1330. if( !o->getModel() && !o->getCamera() ){
  1331. RTEX( "Entity is not a model or camera" );
  1332. }
  1333. }
  1334. o->setOrder( n );
  1335. }
  1336. //////////////////////////////
  1337. // ENTITY PROPERTY COMMANDS //
  1338. //////////////////////////////
  1339. float bbEntityX( Entity *e,int global ){
  1340. debugEntity(e);
  1341. return global ? e->getWorldPosition().x : e->getLocalPosition().x;
  1342. }
  1343. float bbEntityY( Entity *e,int global ){
  1344. debugEntity(e);
  1345. return global ? e->getWorldPosition().y : e->getLocalPosition().y;
  1346. }
  1347. float bbEntityZ( Entity *e,int global ){
  1348. debugEntity(e);
  1349. return global ? e->getWorldPosition().z : e->getLocalPosition().z;
  1350. }
  1351. float bbEntityPitch( Entity *e,int global ){
  1352. debugEntity(e);
  1353. return quatPitch( global ? e->getWorldRotation() : e->getLocalRotation() ) * rtod;
  1354. }
  1355. float bbEntityYaw( Entity *e,int global ){
  1356. debugEntity(e);
  1357. return quatYaw( global ? e->getWorldRotation() : e->getLocalRotation() ) * rtod;
  1358. }
  1359. float bbEntityRoll( Entity *e,int global ){
  1360. debugEntity(e);
  1361. return quatRoll( global ? e->getWorldRotation() : e->getLocalRotation() ) * rtod;
  1362. }
  1363. float bbGetMatElement( Entity *e,int row,int col ){
  1364. debugEntity(e);
  1365. return row<3 ? e->getWorldTform().m[row][col] : e->getWorldTform().v[col];
  1366. }
  1367. void bbTFormPoint( float x,float y,float z,Entity *src,Entity *dest ){
  1368. if( debug ){
  1369. if( src ) debugEntity(src);
  1370. if( dest ) debugEntity(dest);
  1371. }
  1372. tformed=Vector( x,y,z );
  1373. if( src ) tformed=src->getWorldTform() * tformed;
  1374. if( dest ) tformed=-dest->getWorldTform() * tformed;
  1375. }
  1376. void bbTFormVector( float x,float y,float z,Entity *src,Entity *dest ){
  1377. if( debug ){
  1378. if( src ) debugEntity(src);
  1379. if( dest ) debugEntity(dest);
  1380. }
  1381. tformed=Vector( x,y,z );
  1382. if( src ) tformed=src->getWorldTform().m * tformed;
  1383. if( dest ) tformed=-dest->getWorldTform().m * tformed;
  1384. }
  1385. void bbTFormNormal( float x,float y,float z,Entity *src,Entity *dest ){
  1386. if( debug ){
  1387. if( src ) debugEntity(src);
  1388. if( dest ) debugEntity(dest);
  1389. }
  1390. tformed=Vector( x,y,z );
  1391. if( src ) tformed=(src->getWorldTform().m).cofactor() * tformed;
  1392. if( dest ) tformed=(-dest->getWorldTform().m).cofactor() * tformed;
  1393. tformed.normalize();
  1394. }
  1395. float bbTFormedX(){
  1396. return tformed.x;
  1397. }
  1398. float bbTFormedY(){
  1399. return tformed.y;
  1400. }
  1401. float bbTFormedZ(){
  1402. return tformed.z;
  1403. }
  1404. float bbVectorYaw( float x,float y,float z ){
  1405. return Vector(x,y,z).yaw() * rtod;
  1406. }
  1407. float bbVectorPitch( float x,float y,float z ){
  1408. return Vector(x,y,z).pitch() * rtod;
  1409. }
  1410. float bbDeltaYaw( Entity *src,Entity *dest ){
  1411. float x=src->getWorldTform().m.k.yaw();
  1412. float y=(dest->getWorldTform().v-src->getWorldTform().v).yaw();
  1413. float d=y-x;
  1414. if( d<-PI ) d+=TWOPI;
  1415. else if( d>=PI ) d-=TWOPI;
  1416. return d*rtod;
  1417. }
  1418. float bbDeltaPitch( Entity *src,Entity *dest ){
  1419. float x=src->getWorldTform().m.k.pitch();
  1420. float y=(dest->getWorldTform().v-src->getWorldTform().v).pitch();
  1421. float d=y-x;
  1422. if( d<-PI ) d+=TWOPI;
  1423. else if( d>=PI ) d-=TWOPI;
  1424. return d*rtod;
  1425. }
  1426. ///////////////////////////////
  1427. // ENTITY COLLISION COMMANDS //
  1428. ///////////////////////////////
  1429. void bbResetEntity( Object *o ){
  1430. debugObject(o);
  1431. o->reset();
  1432. }
  1433. static void entityType( Entity *e,int type ){
  1434. e->getObject()->setCollisionType(type);
  1435. e->getObject()->reset();
  1436. for( Entity *p=e->children();p;p=p->successor() ){
  1437. entityType( p,type );
  1438. }
  1439. }
  1440. void bbEntityType( Object *o,int type,int recurs ){
  1441. if( debug ){
  1442. debugObject(o);
  1443. if( type<0 || type>999 ) RTEX( "EntityType ID must be in the range 0...999" );
  1444. }
  1445. if( recurs ) entityType( o,type );
  1446. else{
  1447. o->setCollisionType(type);
  1448. o->reset();
  1449. }
  1450. }
  1451. void bbEntityPickMode( Object *o,int mode,int obs ){
  1452. debugObject(o);
  1453. o->setPickGeometry( mode );
  1454. o->setObscurer( !!obs );
  1455. }
  1456. Entity * bbGetParent( Entity *e ){
  1457. debugEntity(e);
  1458. return e->getParent();
  1459. }
  1460. int bbGetEntityType( Object *o ){
  1461. debugObject(o);
  1462. return o->getCollisionType();
  1463. }
  1464. void bbEntityRadius( Object *o,float x_radius,float y_radius ){
  1465. debugObject(o);
  1466. Vector radii( x_radius,y_radius ? y_radius : x_radius,x_radius );
  1467. o->setCollisionRadii( radii );
  1468. }
  1469. void bbEntityBox( Object *o,float x,float y,float z,float w,float h,float d ){
  1470. debugObject(o);
  1471. Box b( Vector(x,y,z) );
  1472. b.update( Vector( x+w,y+h,z+d ) );
  1473. o->setCollisionBox( b );
  1474. }
  1475. Object * bbEntityCollided( Object *o,int type ){
  1476. debugObject(o);
  1477. Object::Collisions::const_iterator it;
  1478. const Object::Collisions &c=o->getCollisions();
  1479. for( it=c.begin();it!=c.end();++it ){
  1480. const ObjCollision *c=*it;
  1481. if( c->with->getCollisionType()==type ) return c->with;
  1482. }
  1483. return 0;
  1484. }
  1485. int bbCountCollisions( Object *o ){
  1486. debugObject(o);
  1487. return o->getCollisions().size();
  1488. }
  1489. float bbCollisionX( Object *o,int index ){
  1490. debugColl(o,index);
  1491. return o->getCollisions()[index-1]->coords.x;
  1492. }
  1493. float bbCollisionY( Object *o,int index ){
  1494. debugColl(o,index);
  1495. return o->getCollisions()[index-1]->coords.y;
  1496. }
  1497. float bbCollisionZ( Object *o,int index ){
  1498. debugColl(o,index);
  1499. return o->getCollisions()[index-1]->coords.z;
  1500. }
  1501. float bbCollisionNX( Object *o,int index ){
  1502. debugColl(o,index);
  1503. return o->getCollisions()[index-1]->collision.normal.x;
  1504. }
  1505. float bbCollisionNY( Object *o,int index ){
  1506. debugColl(o,index);
  1507. return o->getCollisions()[index-1]->collision.normal.y;
  1508. }
  1509. float bbCollisionNZ( Object *o,int index ){
  1510. debugColl(o,index);
  1511. return o->getCollisions()[index-1]->collision.normal.z;
  1512. }
  1513. float bbCollisionTime( Object *o,int index ){
  1514. debugColl(o,index);
  1515. return o->getCollisions()[index-1]->collision.time;
  1516. }
  1517. Object * bbCollisionEntity( Object *o,int index ){
  1518. debugColl(o,index);
  1519. return o->getCollisions()[index-1]->with;
  1520. }
  1521. void * bbCollisionSurface( Object *o,int index ){
  1522. debugColl(o,index);
  1523. return o->getCollisions()[index-1]->collision.surface;
  1524. }
  1525. int bbCollisionTriangle( Object *o,int index ){
  1526. debugColl(o,index);
  1527. return o->getCollisions()[index-1]->collision.index;
  1528. }
  1529. float bbEntityDistance( Entity *src,Entity *dest ){
  1530. debugEntity(src);
  1531. debugEntity(dest);
  1532. return src->getWorldPosition().distance( dest->getWorldPosition() );
  1533. }
  1534. ////////////////////////////////////
  1535. // ENTITY TRANSFORMATION COMMANDS //
  1536. ////////////////////////////////////
  1537. void bbMoveEntity( Entity *e,float x,float y,float z ){
  1538. debugEntity(e);
  1539. e->setLocalPosition( e->getLocalPosition()+e->getLocalRotation()*Vector(x,y,z) );
  1540. }
  1541. void bbTurnEntity( Entity *e,float p,float y,float r,int global ){
  1542. debugEntity(e);
  1543. global?
  1544. e->setWorldRotation( rotationQuat( p*dtor,y*dtor,r*dtor )*e->getWorldRotation() ):
  1545. e->setLocalRotation( e->getLocalRotation()*rotationQuat( p*dtor,y*dtor,r*dtor ) );
  1546. }
  1547. void bbTranslateEntity( Entity *e,float x,float y,float z,int global ){
  1548. debugEntity(e);
  1549. global?
  1550. e->setWorldPosition( e->getWorldPosition()+Vector( x,y,z ) ):
  1551. e->setLocalPosition( e->getLocalPosition()+Vector( x,y,z ) );
  1552. }
  1553. void bbPositionEntity( Entity *e,float x,float y,float z,int global ){
  1554. debugEntity(e);
  1555. global?
  1556. e->setWorldPosition(Vector(x,y,z)):
  1557. e->setLocalPosition(Vector(x,y,z));
  1558. }
  1559. void bbScaleEntity( Entity *e,float x,float y,float z,int global ){
  1560. debugEntity(e);
  1561. global?
  1562. e->setWorldScale(Vector(x,y,z)):
  1563. e->setLocalScale(Vector(x,y,z));
  1564. }
  1565. void bbRotateEntity( Entity *e,float p,float y,float r,int global ){
  1566. debugEntity(e);
  1567. global?
  1568. e->setWorldRotation( rotationQuat( p*dtor,y*dtor,r*dtor ) ):
  1569. e->setLocalRotation( rotationQuat( p*dtor,y*dtor,r*dtor ) );
  1570. }
  1571. void bbPointEntity( Entity *e,Entity *t,float roll ){
  1572. if( debug ){ debugEntity(e);debugEntity(t); }
  1573. Vector v=t->getWorldTform().v-e->getWorldTform().v;
  1574. e->setWorldRotation( rotationQuat( v.pitch(),v.yaw(),roll*dtor ) );
  1575. }
  1576. void bbAlignToVector( Entity *e,float nx,float ny,float nz,int axis,float rate ){
  1577. Vector ax( nx,ny,nz );
  1578. float l=ax.length();
  1579. if( l<=EPSILON ) return;
  1580. ax/=l;
  1581. Quat q=e->getWorldRotation();
  1582. Vector tv=(axis==1) ? q.i() : (axis==2 ? q.j() : q.k());
  1583. float dp=ax.dot( tv );
  1584. if( dp>=1-EPSILON ) return;
  1585. if( dp<=-1+EPSILON ){
  1586. float an=PI*rate/2;
  1587. Vector cp=(axis==1) ? q.j() : (axis==2 ? q.k() : q.i());
  1588. e->setWorldRotation( Quat( cosf(an),cp*sinf(an) ) * q );
  1589. return;
  1590. }
  1591. float an=acosf( dp )*rate/2;
  1592. Vector cp=ax.cross( tv ).normalized();
  1593. e->setWorldRotation( Quat( cosf(an),cp*sinf(an) ) * q );
  1594. }
  1595. //////////////////////////
  1596. // ENTITY MISC COMMANDS //
  1597. //////////////////////////
  1598. void bbNameEntity( Entity *e,BBStr *t ){
  1599. debugEntity(e);
  1600. e->setName( *t );
  1601. delete t;
  1602. }
  1603. BBStr * bbEntityName( Entity *e ){
  1604. debugEntity(e);
  1605. return d_new BBStr( e->getName() );
  1606. }
  1607. BBStr *bbEntityClass( Entity *e ){
  1608. debugEntity(e);
  1609. const char *p="Pivot";
  1610. if( e->getLight() ) p="Light";
  1611. else if( e->getCamera() ) p="Camera";
  1612. else if( e->getMirror() ) p="Mirror";
  1613. else if( e->getListener() ) p="Listener";
  1614. else if( Model *t=e->getModel() ){
  1615. if( t->getSprite() ) p="Sprite";
  1616. else if( t->getTerrain() ) p="Terrain";
  1617. else if( t->getPlaneModel() ) p="Plane";
  1618. else if( t->getMeshModel() ) p="Mesh";
  1619. else if( t->getMD2Model() ) p="MD2";
  1620. else if( t->getBSPModel() ) p="BSP";
  1621. }
  1622. return new BBStr(p);
  1623. }
  1624. void bbClearWorld( int e,int b,int t ){
  1625. if( e ){
  1626. while( Entity::orphans() ) bbFreeEntity( Entity::orphans() );
  1627. }
  1628. if( b ){
  1629. while( brush_set.size() ) bbFreeBrush( *brush_set.begin() );
  1630. }
  1631. if( t ){
  1632. while( texture_set.size() ) bbFreeTexture( *texture_set.begin() );
  1633. }
  1634. }
  1635. extern int active_texs;
  1636. int bbActiveTextures(){
  1637. return active_texs;
  1638. }
  1639. void blitz3d_open(){
  1640. gx_scene=gx_graphics->createScene( 0 );
  1641. if( !gx_scene ) RTEX( "Unable to create 3D Scene" );
  1642. world=d_new World();
  1643. projected=Vector();
  1644. picked.collision=Collision();
  1645. picked.with=0;picked.coords=Vector();
  1646. Texture::clearFilters();
  1647. Texture::addFilter( "",gxCanvas::CANVAS_TEX_RGB|gxCanvas::CANVAS_TEX_MIPMAP );
  1648. loader_mat_map.clear();
  1649. loader_mat_map["x"]=Transform();
  1650. loader_mat_map["3ds"]=Transform(Matrix(Vector(1,0,0),Vector(0,0,1),Vector(0,1,0)));
  1651. listener=0;
  1652. stats_mode=false;
  1653. }
  1654. void blitz3d_close(){
  1655. if( !gx_scene ) return;
  1656. bbClearWorld( 1,1,1 );
  1657. Texture::clearFilters();
  1658. loader_mat_map.clear();
  1659. delete world;
  1660. gx_graphics->freeScene( gx_scene );
  1661. gx_scene=0;
  1662. }
  1663. bool blitz3d_create(){
  1664. tri_count=0;
  1665. gx_scene=0;world=0;
  1666. return true;
  1667. }
  1668. bool blitz3d_destroy(){
  1669. blitz3d_close();
  1670. return true;
  1671. }
  1672. void blitz3d_link( void (*rtSym)( const char *sym,void *pc ) ){
  1673. rtSym( "LoaderMatrix$file_ext#xx#xy#xz#yx#yy#yz#zx#zy#zz",bbLoaderMatrix );
  1674. rtSym( "HWMultiTex%enable",bbHWMultiTex );
  1675. rtSym( "%HWTexUnits",bbHWTexUnits );
  1676. rtSym( "%GfxDriverCaps3D",bbGfxDriverCaps3D );
  1677. rtSym( "WBuffer%enable",bbWBuffer );
  1678. rtSym( "Dither%enable",bbDither );
  1679. rtSym( "AntiAlias%enable",bbAntiAlias );
  1680. rtSym( "WireFrame%enable",bbWireFrame );
  1681. rtSym( "AmbientLight#red#green#blue",bbAmbientLight );
  1682. rtSym( "ClearCollisions",bbClearCollisions );
  1683. rtSym( "Collisions%source_type%destination_type%method%response",bbCollisions );
  1684. rtSym( "UpdateWorld#elapsed_time=1",bbUpdateWorld );
  1685. rtSym( "CaptureWorld",bbCaptureWorld );
  1686. rtSym( "RenderWorld#tween=1",bbRenderWorld );
  1687. rtSym( "ClearWorld%entities=1%brushes=1%textures=1",bbClearWorld );
  1688. rtSym( "%ActiveTextures",bbActiveTextures );
  1689. rtSym( "%TrisRendered",bbTrisRendered );
  1690. rtSym( "#Stats3D%type",bbStats3D );
  1691. rtSym( "%CreateTexture%width%height%flags=0%frames=1",bbCreateTexture );
  1692. rtSym( "%LoadTexture$file%flags=1",bbLoadTexture );
  1693. rtSym( "%LoadAnimTexture$file%flags%width%height%first%count",bbLoadAnimTexture );
  1694. rtSym( "FreeTexture%texture",bbFreeTexture );
  1695. rtSym( "TextureBlend%texture%blend",bbTextureBlend );
  1696. rtSym( "TextureCoords%texture%coords",bbTextureCoords );
  1697. rtSym( "ScaleTexture%texture#u_scale#v_scale",bbScaleTexture );
  1698. rtSym( "RotateTexture%texture#angle",bbRotateTexture );
  1699. rtSym( "PositionTexture%texture#u_offset#v_offset",bbPositionTexture );
  1700. rtSym( "%TextureWidth%texture",bbTextureWidth );
  1701. rtSym( "%TextureHeight%texture",bbTextureHeight );
  1702. rtSym( "$TextureName%texture",bbTextureName );
  1703. rtSym( "SetCubeFace%texture%face",bbSetCubeFace );
  1704. rtSym( "SetCubeMode%texture%mode",bbSetCubeMode );
  1705. rtSym( "%TextureBuffer%texture%frame=0",bbTextureBuffer );
  1706. rtSym( "ClearTextureFilters",bbClearTextureFilters );
  1707. rtSym( "TextureFilter$match_text%texture_flags=0",bbTextureFilter );
  1708. rtSym( "%CreateBrush#red=255#green=255#blue=255",bbCreateBrush );
  1709. rtSym( "%LoadBrush$file%texture_flags=1#u_scale=1#v_scale=1",bbLoadBrush );
  1710. rtSym( "FreeBrush%brush",bbFreeBrush );
  1711. rtSym( "BrushColor%brush#red#green#blue",bbBrushColor );
  1712. rtSym( "BrushAlpha%brush#alpha",bbBrushAlpha );
  1713. rtSym( "BrushShininess%brush#shininess",bbBrushShininess );
  1714. rtSym( "BrushTexture%brush%texture%frame=0%index=0",bbBrushTexture );
  1715. rtSym( "%GetBrushTexture%brush%index=0",bbGetBrushTexture );
  1716. rtSym( "BrushBlend%brush%blend",bbBrushBlend );
  1717. rtSym( "BrushFX%brush%fx",bbBrushFX );
  1718. rtSym( "%LoadMesh$file%parent=0",bbLoadMesh );
  1719. rtSym( "%LoadAnimMesh$file%parent=0",bbLoadAnimMesh );
  1720. rtSym( "%LoadAnimSeq%entity$file",bbLoadAnimSeq );
  1721. rtSym( "%CreateMesh%parent=0",bbCreateMesh );
  1722. rtSym( "%CreateCube%parent=0",bbCreateCube );
  1723. rtSym( "%CreateSphere%segments=8%parent=0",bbCreateSphere );
  1724. rtSym( "%CreateCylinder%segments=8%solid=1%parent=0",bbCreateCylinder );
  1725. rtSym( "%CreateCone%segments=8%solid=1%parent=0",bbCreateCone );
  1726. rtSym( "%CopyMesh%mesh%parent=0",bbCopyMesh );
  1727. rtSym( "ScaleMesh%mesh#x_scale#y_scale#z_scale",bbScaleMesh );
  1728. rtSym( "RotateMesh%mesh#pitch#yaw#roll",bbRotateMesh );
  1729. rtSym( "PositionMesh%mesh#x#y#z",bbPositionMesh );
  1730. rtSym( "FitMesh%mesh#x#y#z#width#height#depth%uniform=0",bbFitMesh );
  1731. rtSym( "FlipMesh%mesh",bbFlipMesh );
  1732. rtSym( "PaintMesh%mesh%brush",bbPaintMesh );
  1733. rtSym( "AddMesh%source_mesh%dest_mesh",bbAddMesh );
  1734. rtSym( "UpdateNormals%mesh",bbUpdateNormals );
  1735. rtSym( "LightMesh%mesh#red#green#blue#range=0#x=0#y=0#z=0",bbLightMesh );
  1736. rtSym( "#MeshWidth%mesh",bbMeshWidth );
  1737. rtSym( "#MeshHeight%mesh",bbMeshHeight );
  1738. rtSym( "#MeshDepth%mesh",bbMeshDepth );
  1739. rtSym( "%MeshesIntersect%mesh_a%mesh_b",bbMeshesIntersect );
  1740. rtSym( "%CountSurfaces%mesh",bbCountSurfaces );
  1741. rtSym( "%GetSurface%mesh%surface_index",bbGetSurface );
  1742. rtSym( "MeshCullBox%mesh#x#y#z#width#height#depth",bbMeshCullBox );
  1743. rtSym( "%CreateSurface%mesh%brush=0",bbCreateSurface );
  1744. rtSym( "%GetSurfaceBrush%surface",bbGetSurfaceBrush );
  1745. rtSym( "%GetEntityBrush%entity",bbGetEntityBrush );
  1746. rtSym( "%FindSurface%mesh%brush",bbFindSurface );
  1747. rtSym( "ClearSurface%surface%clear_vertices=1%clear_triangles=1",bbClearSurface );
  1748. rtSym( "PaintSurface%surface%brush",bbPaintSurface );
  1749. rtSym( "%AddVertex%surface#x#y#z#u=0#v=0#w=1",bbAddVertex );
  1750. rtSym( "%AddTriangle%surface%v0%v1%v2",bbAddTriangle );
  1751. rtSym( "VertexCoords%surface%index#x#y#z",bbVertexCoords );
  1752. rtSym( "VertexNormal%surface%index#nx#ny#nz",bbVertexNormal );
  1753. rtSym( "VertexColor%surface%index#red#green#blue#alpha=1",bbVertexColor );
  1754. rtSym( "VertexTexCoords%surface%index#u#v#w=1%coord_set=0",bbVertexTexCoords );
  1755. rtSym( "%CountVertices%surface",bbCountVertices );
  1756. rtSym( "%CountTriangles%surface",bbCountTriangles );
  1757. rtSym( "#VertexX%surface%index",bbVertexX );
  1758. rtSym( "#VertexY%surface%index",bbVertexY );
  1759. rtSym( "#VertexZ%surface%index",bbVertexZ );
  1760. rtSym( "#VertexNX%surface%index",bbVertexNX );
  1761. rtSym( "#VertexNY%surface%index",bbVertexNY );
  1762. rtSym( "#VertexNZ%surface%index",bbVertexNZ );
  1763. rtSym( "#VertexRed%surface%index",bbVertexRed );
  1764. rtSym( "#VertexGreen%surface%index",bbVertexGreen );
  1765. rtSym( "#VertexBlue%surface%index",bbVertexBlue );
  1766. rtSym( "#VertexAlpha%surface%index",bbVertexAlpha );
  1767. rtSym( "#VertexU%surface%index%coord_set=0",bbVertexU );
  1768. rtSym( "#VertexV%surface%index%coord_set=0",bbVertexV );
  1769. rtSym( "#VertexW%surface%index%coord_set=0",bbVertexW );
  1770. rtSym( "%TriangleVertex%surface%index%vertex",bbTriangleVertex );
  1771. rtSym( "%CreateCamera%parent=0",bbCreateCamera );
  1772. rtSym( "CameraZoom%camera#zoom",bbCameraZoom );
  1773. rtSym( "CameraRange%camera#near#far",bbCameraRange );
  1774. rtSym( "CameraClsColor%camera#red#green#blue",bbCameraClsColor );
  1775. rtSym( "CameraClsMode%camera%cls_color%cls_zbuffer",bbCameraClsMode );
  1776. rtSym( "CameraProjMode%camera%mode",bbCameraProjMode );
  1777. rtSym( "CameraViewport%camera%x%y%width%height",bbCameraViewport );
  1778. rtSym( "CameraFogColor%camera#red#green#blue",bbCameraFogColor );
  1779. rtSym( "CameraFogRange%camera#near#far",bbCameraFogRange );
  1780. rtSym( "CameraFogMode%camera%mode",bbCameraFogMode );
  1781. rtSym( "CameraProject%camera#x#y#z",bbCameraProject );
  1782. rtSym( "#ProjectedX",bbProjectedX );
  1783. rtSym( "#ProjectedY",bbProjectedY );
  1784. rtSym( "#ProjectedZ",bbProjectedZ );
  1785. rtSym( "%EntityInView%entity%camera",bbEntityInView );
  1786. rtSym( "%EntityVisible%src_entity%dest_entity",bbEntityVisible );
  1787. rtSym( "%EntityPick%entity#range",bbEntityPick );
  1788. rtSym( "%LinePick#x#y#z#dx#dy#dz#radius=0",bbLinePick );
  1789. rtSym( "%CameraPick%camera#viewport_x#viewport_y",bbCameraPick );
  1790. rtSym( "#PickedX",bbPickedX );
  1791. rtSym( "#PickedY",bbPickedY );
  1792. rtSym( "#PickedZ",bbPickedZ );
  1793. rtSym( "#PickedNX",bbPickedNX );
  1794. rtSym( "#PickedNY",bbPickedNY );
  1795. rtSym( "#PickedNZ",bbPickedNZ );
  1796. rtSym( "#PickedTime",bbPickedTime );
  1797. rtSym( "%PickedEntity",bbPickedEntity );
  1798. rtSym( "%PickedSurface",bbPickedSurface );
  1799. rtSym( "%PickedTriangle",bbPickedTriangle );
  1800. rtSym( "%CreateLight%type=1%parent=0",bbCreateLight );
  1801. rtSym( "LightColor%light#red#green#blue",bbLightColor );
  1802. rtSym( "LightRange%light#range",bbLightRange );
  1803. rtSym( "LightConeAngles%light#inner_angle#outer_angle",bbLightConeAngles );
  1804. rtSym( "%CreatePivot%parent=0",bbCreatePivot );
  1805. rtSym( "%CreateSprite%parent=0",bbCreateSprite );
  1806. rtSym( "%LoadSprite$file%texture_flags=1%parent=0",bbLoadSprite );
  1807. rtSym( "RotateSprite%sprite#angle",bbRotateSprite );
  1808. rtSym( "ScaleSprite%sprite#x_scale#y_scale",bbScaleSprite );
  1809. rtSym( "HandleSprite%sprite#x_handle#y_handle",bbHandleSprite );
  1810. rtSym( "SpriteViewMode%sprite%view_mode",bbSpriteViewMode );
  1811. rtSym( "%LoadMD2$file%parent=0",bbLoadMD2 );
  1812. rtSym( "AnimateMD2%md2%mode=1#speed=1%first_frame=0%last_frame=9999#transition=0",bbAnimateMD2 );
  1813. rtSym( "#MD2AnimTime%md2",bbMD2AnimTime );
  1814. rtSym( "%MD2AnimLength%md2",bbMD2AnimLength );
  1815. rtSym( "%MD2Animating%md2",bbMD2Animating );
  1816. rtSym( "%LoadBSP$file#gamma_adj=0%parent=0",bbLoadBSP );
  1817. rtSym( "BSPLighting%bsp%use_lightmaps",bbBSPLighting );
  1818. rtSym( "BSPAmbientLight%bsp#red#green#blue",bbBSPAmbientLight );
  1819. rtSym( "%CreateMirror%parent=0",bbCreateMirror );
  1820. rtSym( "%CreatePlane%segments=1%parent=0",bbCreatePlane );
  1821. rtSym( "%CreateTerrain%grid_size%parent=0",bbCreateTerrain );
  1822. rtSym( "%LoadTerrain$heightmap_file%parent=0",bbLoadTerrain );
  1823. rtSym( "TerrainDetail%terrain%detail_level%morph=0",bbTerrainDetail );
  1824. rtSym( "TerrainShading%terrain%enable",bbTerrainShading );
  1825. rtSym( "#TerrainX%terrain#world_x#world_y#world_z",bbTerrainX );
  1826. rtSym( "#TerrainY%terrain#world_x#world_y#world_z",bbTerrainY );
  1827. rtSym( "#TerrainZ%terrain#world_x#world_y#world_z",bbTerrainZ );
  1828. rtSym( "%TerrainSize%terrain",bbTerrainSize );
  1829. rtSym( "#TerrainHeight%terrain%terrain_x%terrain_z",bbTerrainHeight );
  1830. rtSym( "ModifyTerrain%terrain%terrain_x%terrain_z#height%realtime=0",bbModifyTerrain );
  1831. rtSym( "%CreateListener%parent#rolloff_factor=1#doppler_scale=1#distance_scale=1",bbCreateListener );
  1832. rtSym( "%EmitSound%sound%entity",bbEmitSound );
  1833. rtSym( "%CopyEntity%entity%parent=0",bbCopyEntity );
  1834. rtSym( "#EntityX%entity%global=0",bbEntityX );
  1835. rtSym( "#EntityY%entity%global=0",bbEntityY );
  1836. rtSym( "#EntityZ%entity%global=0",bbEntityZ );
  1837. rtSym( "#EntityPitch%entity%global=0",bbEntityPitch );
  1838. rtSym( "#EntityYaw%entity%global=0",bbEntityYaw );
  1839. rtSym( "#EntityRoll%entity%global=0",bbEntityRoll );
  1840. rtSym( "#GetMatElement%entity%row%column",bbGetMatElement );
  1841. rtSym( "TFormPoint#x#y#z%source_entity%dest_entity",bbTFormPoint );
  1842. rtSym( "TFormVector#x#y#z%source_entity%dest_entity",bbTFormVector );
  1843. rtSym( "TFormNormal#x#y#z%source_entity%dest_entity",bbTFormNormal );
  1844. rtSym( "#TFormedX",bbTFormedX );
  1845. rtSym( "#TFormedY",bbTFormedY );
  1846. rtSym( "#TFormedZ",bbTFormedZ );
  1847. rtSym( "#VectorYaw#x#y#z",bbVectorYaw );
  1848. rtSym( "#VectorPitch#x#y#z",bbVectorPitch );
  1849. rtSym( "#DeltaPitch%src_entity%dest_entity",bbDeltaPitch );
  1850. rtSym( "#DeltaYaw%src_entity%dest_entity",bbDeltaYaw );
  1851. rtSym( "ResetEntity%entity",bbResetEntity );
  1852. rtSym( "EntityType%entity%collision_type%recursive=0",bbEntityType );
  1853. rtSym( "EntityPickMode%entity%pick_geometry%obscurer=1",bbEntityPickMode );
  1854. rtSym( "%GetParent%entity",bbGetParent );
  1855. rtSym( "%GetEntityType%entity",bbGetEntityType );
  1856. rtSym( "EntityRadius%entity#x_radius#y_radius=0",bbEntityRadius );
  1857. rtSym( "EntityBox%entity#x#y#z#width#height#depth",bbEntityBox );
  1858. rtSym( "#EntityDistance%source_entity%destination_entity",bbEntityDistance );
  1859. rtSym( "%EntityCollided%entity%type",bbEntityCollided );
  1860. rtSym( "%CountCollisions%entity",bbCountCollisions );
  1861. rtSym( "#CollisionX%entity%collision_index",bbCollisionX );
  1862. rtSym( "#CollisionY%entity%collision_index",bbCollisionY );
  1863. rtSym( "#CollisionZ%entity%collision_index",bbCollisionZ );
  1864. rtSym( "#CollisionNX%entity%collision_index",bbCollisionNX );
  1865. rtSym( "#CollisionNY%entity%collision_index",bbCollisionNY );
  1866. rtSym( "#CollisionNZ%entity%collision_index",bbCollisionNZ );
  1867. rtSym( "#CollisionTime%entity%collision_index",bbCollisionTime );
  1868. rtSym( "%CollisionEntity%entity%collision_index",bbCollisionEntity );
  1869. rtSym( "%CollisionSurface%entity%collision_index",bbCollisionSurface );
  1870. rtSym( "%CollisionTriangle%entity%collision_index",bbCollisionTriangle );
  1871. rtSym( "MoveEntity%entity#x#y#z",bbMoveEntity );
  1872. rtSym( "TurnEntity%entity#pitch#yaw#roll%global=0",bbTurnEntity );
  1873. rtSym( "TranslateEntity%entity#x#y#z%global=0",bbTranslateEntity );
  1874. rtSym( "PositionEntity%entity#x#y#z%global=0",bbPositionEntity );
  1875. rtSym( "ScaleEntity%entity#x_scale#y_scale#z_scale%global=0",bbScaleEntity );
  1876. rtSym( "RotateEntity%entity#pitch#yaw#roll%global=0",bbRotateEntity );
  1877. rtSym( "PointEntity%entity%target#roll=0",bbPointEntity );
  1878. rtSym( "AlignToVector%entity#vector_x#vector_y#vector_z%axis#rate=1",bbAlignToVector );
  1879. rtSym( "SetAnimTime%entity#time%anim_seq=0",bbSetAnimTime );
  1880. rtSym( "Animate%entity%mode=1#speed=1%sequence=0#transition=0",bbAnimate );
  1881. rtSym( "SetAnimKey%entity%frame%pos_key=1%rot_key=1%scale_key=1",bbSetAnimKey );
  1882. rtSym( "%AddAnimSeq%entity%length",bbAddAnimSeq );
  1883. rtSym( "%ExtractAnimSeq%entity%first_frame%last_frame%anim_seq=0",bbExtractAnimSeq );
  1884. rtSym( "%AnimSeq%entity",bbAnimSeq );
  1885. rtSym( "#AnimTime%entity",bbAnimTime );
  1886. rtSym( "%AnimLength%entity",bbAnimLength );
  1887. rtSym( "%Animating%entity",bbAnimating );
  1888. rtSym( "EntityParent%entity%parent%global=1",bbEntityParent );
  1889. rtSym( "%CountChildren%entity",bbCountChildren );
  1890. rtSym( "%GetChild%entity%index",bbGetChild );
  1891. rtSym( "%FindChild%entity$name",bbFindChild );
  1892. rtSym( "PaintEntity%entity%brush",bbPaintEntity );
  1893. rtSym( "EntityColor%entity#red#green#blue",bbEntityColor );
  1894. rtSym( "EntityAlpha%entity#alpha",bbEntityAlpha );
  1895. rtSym( "EntityShininess%entity#shininess",bbEntityShininess );
  1896. rtSym( "EntityTexture%entity%texture%frame=0%index=0",bbEntityTexture );
  1897. rtSym( "EntityBlend%entity%blend",bbEntityBlend );
  1898. rtSym( "EntityFX%entity%fx",bbEntityFX );
  1899. rtSym( "EntityAutoFade%entity#near#far",bbEntityAutoFade );
  1900. rtSym( "EntityOrder%entity%order",bbEntityOrder );
  1901. rtSym( "HideEntity%entity",bbHideEntity );
  1902. rtSym( "ShowEntity%entity",bbShowEntity );
  1903. rtSym( "FreeEntity%entity",bbFreeEntity );
  1904. rtSym( "NameEntity%entity$name",bbNameEntity );
  1905. rtSym( "$EntityName%entity",bbEntityName );
  1906. rtSym( "$EntityClass%entity",bbEntityClass );
  1907. }
  1908. #endif