runtime: Formatting
This commit is contained in:
+193
-148
@@ -1,234 +1,278 @@
|
||||
|
||||
#pragma warning( disable:4786 )
|
||||
#pragma warning(disable : 4786)
|
||||
|
||||
#include "bbruntime_dll.hpp"
|
||||
#include "../debugger/debugger.hpp"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <map>
|
||||
#include <eh.h>
|
||||
#include <float.h>
|
||||
#include <map>
|
||||
|
||||
#include "bbruntime.hpp"
|
||||
|
||||
class DummyDebugger : public Debugger{
|
||||
public:
|
||||
virtual void debugRun(){}
|
||||
virtual void debugStop(){}// bbruntime_panic(0); }
|
||||
virtual void debugStmt( int srcpos,const char *file ){}
|
||||
virtual void debugEnter( void *frame,void *env,const char *func ){}
|
||||
virtual void debugLeave(){}
|
||||
virtual void debugLog( const char *msg ){}
|
||||
virtual void debugMsg( const char *e,bool serious ){
|
||||
if( serious ) MessageBox( 0,e,"Error!",MB_OK|MB_TOPMOST|MB_SETFOREGROUND );
|
||||
class DummyDebugger : public Debugger {
|
||||
public:
|
||||
virtual void debugRun() {}
|
||||
virtual void debugStop() {} // bbruntime_panic(0); }
|
||||
virtual void debugStmt(int srcpos, const char* file) {}
|
||||
virtual void debugEnter(void* frame, void* env, const char* func) {}
|
||||
virtual void debugLeave() {}
|
||||
virtual void debugLog(const char* msg) {}
|
||||
virtual void debugMsg(const char* e, bool serious)
|
||||
{
|
||||
if (serious)
|
||||
MessageBox(0, e, "Error!", MB_OK | MB_TOPMOST | MB_SETFOREGROUND);
|
||||
}
|
||||
virtual void debugSys( void *msg ){}
|
||||
virtual void debugSys(void* msg) {}
|
||||
};
|
||||
|
||||
static HINSTANCE hinst;
|
||||
static map<const char*,void*> syms;
|
||||
map<const char*,void*>::iterator sym_it;
|
||||
static gxRuntime *gx_runtime;
|
||||
static map<const char*, void*> syms;
|
||||
map<const char*, void*>::iterator sym_it;
|
||||
static gxRuntime* gx_runtime;
|
||||
|
||||
static void rtSym( const char *sym,void *pc ){
|
||||
syms[sym]=pc;
|
||||
static void rtSym(const char* sym, void* pc)
|
||||
{
|
||||
syms[sym] = pc;
|
||||
}
|
||||
|
||||
static void _cdecl seTranslator( unsigned int u,EXCEPTION_POINTERS* pExp ){
|
||||
switch( u ){
|
||||
static void _cdecl seTranslator(unsigned int u, EXCEPTION_POINTERS* pExp)
|
||||
{
|
||||
switch (u) {
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
bbruntime_panic( "Integer divide by zero" );
|
||||
bbruntime_panic("Integer divide by zero");
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
bbruntime_panic( "Memory access violation" );
|
||||
bbruntime_panic("Memory access violation");
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
bbruntime_panic( "Illegal instruction" );
|
||||
bbruntime_panic("Illegal instruction");
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
bbruntime_panic( "Stack overflow!" );
|
||||
bbruntime_panic("Stack overflow!");
|
||||
}
|
||||
bbruntime_panic( "Unknown runtime exception" );
|
||||
bbruntime_panic("Unknown runtime exception");
|
||||
}
|
||||
|
||||
int Runtime::version(){
|
||||
int Runtime::version()
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
const char *Runtime::nextSym(){
|
||||
if( !syms.size() ){
|
||||
bbruntime_link( rtSym );
|
||||
sym_it=syms.begin();
|
||||
const char* Runtime::nextSym()
|
||||
{
|
||||
if (!syms.size()) {
|
||||
bbruntime_link(rtSym);
|
||||
sym_it = syms.begin();
|
||||
}
|
||||
if( sym_it==syms.end() ){
|
||||
syms.clear();return 0;
|
||||
if (sym_it == syms.end()) {
|
||||
syms.clear();
|
||||
return 0;
|
||||
}
|
||||
return (sym_it++)->first;
|
||||
}
|
||||
|
||||
int Runtime::symValue( const char *sym ){
|
||||
map<const char*,void*>::iterator it=syms.find( sym );
|
||||
if( it!=syms.end() ) return (int)it->second;
|
||||
int Runtime::symValue(const char* sym)
|
||||
{
|
||||
map<const char*, void*>::iterator it = syms.find(sym);
|
||||
if (it != syms.end())
|
||||
return (int)it->second;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Runtime::startup( HINSTANCE h ){
|
||||
hinst=h;
|
||||
void Runtime::startup(HINSTANCE h)
|
||||
{
|
||||
hinst = h;
|
||||
}
|
||||
|
||||
void Runtime::shutdown(){
|
||||
trackmem( false );
|
||||
void Runtime::shutdown()
|
||||
{
|
||||
trackmem(false);
|
||||
syms.clear();
|
||||
}
|
||||
|
||||
void Runtime::execute( void (*pc)(),const char *args,Debugger *dbg ){
|
||||
|
||||
bool debug=!!dbg;
|
||||
void Runtime::execute(void (*pc)(), const char* args, Debugger* dbg)
|
||||
{
|
||||
bool debug = !!dbg;
|
||||
|
||||
static DummyDebugger dummydebug;
|
||||
|
||||
if( !dbg ) dbg=&dummydebug;
|
||||
if (!dbg)
|
||||
dbg = &dummydebug;
|
||||
|
||||
trackmem( true );
|
||||
trackmem(true);
|
||||
|
||||
_se_translator_function old_trans = _set_se_translator(seTranslator);
|
||||
_control87(_RC_NEAR | _PC_24 | _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT | _EM_DENORMAL, 0xfffff);
|
||||
_control87(_RC_NEAR | _PC_24 | _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT
|
||||
| _EM_DENORMAL,
|
||||
0xfffff);
|
||||
|
||||
//strip spaces from ends of args...
|
||||
string params=args;
|
||||
while( params.size() && params[0]==' ' ) params=params.substr( 1 );
|
||||
while( params.size() && params[params.size()-1]==' ' ) params=params.substr( 0,params.size()-1 );
|
||||
string params = args;
|
||||
while (params.size() && params[0] == ' ')
|
||||
params = params.substr(1);
|
||||
while (params.size() && params[params.size() - 1] == ' ')
|
||||
params = params.substr(0, params.size() - 1);
|
||||
|
||||
if( gx_runtime=gxRuntime::openRuntime( hinst,params,dbg ) ){
|
||||
bbruntime_run( gx_runtime,pc,debug );
|
||||
if (gx_runtime = gxRuntime::openRuntime(hinst, params, dbg)) {
|
||||
bbruntime_run(gx_runtime, pc, debug);
|
||||
|
||||
gxRuntime *t=gx_runtime;
|
||||
gx_runtime=0;
|
||||
gxRuntime::closeRuntime( t );
|
||||
gxRuntime* t = gx_runtime;
|
||||
gx_runtime = 0;
|
||||
gxRuntime::closeRuntime(t);
|
||||
}
|
||||
|
||||
_control87(_CW_DEFAULT, 0xfffff);
|
||||
_set_se_translator(old_trans);
|
||||
}
|
||||
|
||||
void Runtime::asyncStop(){
|
||||
if( gx_runtime ) gx_runtime->asyncStop();
|
||||
void Runtime::asyncStop()
|
||||
{
|
||||
if (gx_runtime)
|
||||
gx_runtime->asyncStop();
|
||||
}
|
||||
|
||||
void Runtime::asyncRun(){
|
||||
if( gx_runtime ) gx_runtime->asyncRun();
|
||||
void Runtime::asyncRun()
|
||||
{
|
||||
if (gx_runtime)
|
||||
gx_runtime->asyncRun();
|
||||
}
|
||||
|
||||
void Runtime::asyncEnd(){
|
||||
if( gx_runtime ) gx_runtime->asyncEnd();
|
||||
void Runtime::asyncEnd()
|
||||
{
|
||||
if (gx_runtime)
|
||||
gx_runtime->asyncEnd();
|
||||
}
|
||||
|
||||
void Runtime::checkmem( streambuf *buf ){
|
||||
ostream out( buf );
|
||||
::checkmem( out );
|
||||
void Runtime::checkmem(streambuf* buf)
|
||||
{
|
||||
ostream out(buf);
|
||||
::checkmem(out);
|
||||
}
|
||||
|
||||
Runtime *_cdecl runtimeGetRuntime(){
|
||||
Runtime* _cdecl runtimeGetRuntime()
|
||||
{
|
||||
static Runtime runtime;
|
||||
return &runtime;
|
||||
}
|
||||
|
||||
/********************** BUTT UGLY DLL->EXE HOOK! *************************/
|
||||
|
||||
static void *module_pc;
|
||||
static map<string,int> module_syms;
|
||||
static map<string,int> runtime_syms;
|
||||
static Runtime *runtime;
|
||||
static void* module_pc;
|
||||
static map<string, int> module_syms;
|
||||
static map<string, int> runtime_syms;
|
||||
static Runtime* runtime;
|
||||
|
||||
static void fail(){
|
||||
MessageBox( 0,"Unable to run Blitz Basic module",0,0 );
|
||||
static void fail()
|
||||
{
|
||||
MessageBox(0, "Unable to run Blitz Basic module", 0, 0);
|
||||
ExitProcess(-1);
|
||||
}
|
||||
|
||||
struct Sym{
|
||||
struct Sym {
|
||||
string name;
|
||||
int value;
|
||||
};
|
||||
|
||||
static Sym getSym( void **p ){
|
||||
static Sym getSym(void** p)
|
||||
{
|
||||
Sym sym;
|
||||
char *t=(char*)*p;
|
||||
while( char c=*t++ ) sym.name+=c;
|
||||
sym.value=*(int*)t+(int)module_pc;
|
||||
*p=t+4;return sym;
|
||||
char* t = (char*)*p;
|
||||
while (char c = *t++)
|
||||
sym.name += c;
|
||||
sym.value = *(int*)t + (int)module_pc;
|
||||
*p = t + 4;
|
||||
return sym;
|
||||
}
|
||||
|
||||
static int findSym( const string &t ){
|
||||
map<string,int>::iterator it;
|
||||
static int findSym(const string& t)
|
||||
{
|
||||
map<string, int>::iterator it;
|
||||
|
||||
it=module_syms.find( t );
|
||||
if( it!=module_syms.end() ) return it->second;
|
||||
it=runtime_syms.find( t );
|
||||
if( it!=runtime_syms.end() ) return it->second;
|
||||
it = module_syms.find(t);
|
||||
if (it != module_syms.end())
|
||||
return it->second;
|
||||
it = runtime_syms.find(t);
|
||||
if (it != runtime_syms.end())
|
||||
return it->second;
|
||||
|
||||
string err="Can't find symbol: "+t;
|
||||
MessageBox( 0,err.c_str(),0,0 );
|
||||
string err = "Can't find symbol: " + t;
|
||||
MessageBox(0, err.c_str(), 0, 0);
|
||||
ExitProcess(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void link(){
|
||||
|
||||
while( const char *sc=runtime->nextSym() ){
|
||||
|
||||
static void link()
|
||||
{
|
||||
while (const char* sc = runtime->nextSym()) {
|
||||
string t(sc);
|
||||
|
||||
if( t[0]=='_' ){
|
||||
runtime_syms["_"+t]=runtime->symValue(sc);
|
||||
if (t[0] == '_') {
|
||||
runtime_syms["_" + t] = runtime->symValue(sc);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( t[0]=='!' ) t=t.substr(1);
|
||||
if (t[0] == '!')
|
||||
t = t.substr(1);
|
||||
|
||||
if( !isalnum(t[0]) ) t=t.substr(1);
|
||||
if (!isalnum(t[0]))
|
||||
t = t.substr(1);
|
||||
|
||||
for( int k=0;k<t.size();++k ){
|
||||
if( isalnum(t[k]) || t[k]=='_' ) continue;
|
||||
t=t.substr( 0,k );break;
|
||||
for (int k = 0; k < t.size(); ++k) {
|
||||
if (isalnum(t[k]) || t[k] == '_')
|
||||
continue;
|
||||
t = t.substr(0, k);
|
||||
break;
|
||||
}
|
||||
|
||||
runtime_syms["_f"+tolower(t)]=runtime->symValue(sc);
|
||||
runtime_syms["_f" + tolower(t)] = runtime->symValue(sc);
|
||||
}
|
||||
|
||||
HRSRC hres=FindResource( 0,MAKEINTRESOURCE(1111),RT_RCDATA );if( !hres ) fail();
|
||||
HGLOBAL hglo=LoadResource( 0,hres );if( !hglo ) fail();
|
||||
void *p=LockResource( hglo );if( !p ) fail();
|
||||
HRSRC hres = FindResource(0, MAKEINTRESOURCE(1111), RT_RCDATA);
|
||||
if (!hres)
|
||||
fail();
|
||||
HGLOBAL hglo = LoadResource(0, hres);
|
||||
if (!hglo)
|
||||
fail();
|
||||
void* p = LockResource(hglo);
|
||||
if (!p)
|
||||
fail();
|
||||
|
||||
int sz=*(int*)p;p=(int*)p+1;
|
||||
int sz = *(int*)p;
|
||||
p = (int*)p + 1;
|
||||
|
||||
//replace malloc for service pack 2 Data Execution Prevention (DEP).
|
||||
module_pc=VirtualAlloc( 0,sz,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE );
|
||||
module_pc = VirtualAlloc(0, sz, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
|
||||
memcpy( module_pc,p,sz );
|
||||
p=(char*)p+sz;
|
||||
memcpy(module_pc, p, sz);
|
||||
p = (char*)p + sz;
|
||||
|
||||
int k,cnt;
|
||||
int k, cnt;
|
||||
|
||||
cnt=*(int*)p;p=(int*)p+1;
|
||||
for( k=0;k<cnt;++k ){
|
||||
Sym sym=getSym( &p );
|
||||
if( sym.value<(int)module_pc || sym.value>=(int)module_pc+sz ) fail();
|
||||
module_syms[sym.name]=sym.value;
|
||||
cnt = *(int*)p;
|
||||
p = (int*)p + 1;
|
||||
for (k = 0; k < cnt; ++k) {
|
||||
Sym sym = getSym(&p);
|
||||
if (sym.value < (int)module_pc || sym.value >= (int)module_pc + sz)
|
||||
fail();
|
||||
module_syms[sym.name] = sym.value;
|
||||
}
|
||||
|
||||
cnt=*(int*)p;p=(int*)p+1;
|
||||
for( k=0;k<cnt;++k ){
|
||||
Sym sym=getSym( &p );
|
||||
int *pp=(int*)sym.value;
|
||||
int dest=findSym( sym.name );
|
||||
*pp+=dest-(int)pp;
|
||||
cnt = *(int*)p;
|
||||
p = (int*)p + 1;
|
||||
for (k = 0; k < cnt; ++k) {
|
||||
Sym sym = getSym(&p);
|
||||
int* pp = (int*)sym.value;
|
||||
int dest = findSym(sym.name);
|
||||
*pp += dest - (int)pp;
|
||||
}
|
||||
|
||||
cnt=*(int*)p;p=(int*)p+1;
|
||||
for( k=0;k<cnt;++k ){
|
||||
Sym sym=getSym( &p );
|
||||
int *pp=(int*)sym.value;
|
||||
int dest=findSym( sym.name );
|
||||
*pp+=dest;
|
||||
cnt = *(int*)p;
|
||||
p = (int*)p + 1;
|
||||
for (k = 0; k < cnt; ++k) {
|
||||
Sym sym = getSym(&p);
|
||||
int* pp = (int*)sym.value;
|
||||
int dest = findSym(sym.name);
|
||||
*pp += dest;
|
||||
}
|
||||
|
||||
runtime_syms.clear();
|
||||
@@ -236,56 +280,57 @@ static void link(){
|
||||
}
|
||||
|
||||
extern "C" _declspec(dllexport) int _stdcall bbWinMain();
|
||||
extern "C" BOOL _stdcall _DllMainCRTStartup( HANDLE,DWORD,LPVOID );
|
||||
extern "C" BOOL _stdcall _DllMainCRTStartup(HANDLE, DWORD, LPVOID);
|
||||
|
||||
bool WINAPI DllMain( HANDLE module,DWORD reason,void *reserved ){
|
||||
bool WINAPI DllMain(HANDLE module, DWORD reason, void* reserved)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int __stdcall bbWinMain(){
|
||||
int __stdcall bbWinMain()
|
||||
{
|
||||
HINSTANCE inst = GetModuleHandle(0);
|
||||
|
||||
HINSTANCE inst=GetModuleHandle( 0 );
|
||||
|
||||
_DllMainCRTStartup( inst,DLL_PROCESS_ATTACH,0 );
|
||||
_DllMainCRTStartup(inst, DLL_PROCESS_ATTACH, 0);
|
||||
|
||||
#ifdef BETA
|
||||
int ver=VERSION & 0x7fff;
|
||||
string t="Created with Blitz3D Beta V"+itoa( ver/100 )+"."+itoa( ver%100 );
|
||||
MessageBox( GetDesktopWindow(),t.c_str(),"Blitz3D Message",MB_OK );
|
||||
int ver = VERSION & 0x7fff;
|
||||
string t = "Created with Blitz3D Beta V" + itoa(ver / 100) + "." + itoa(ver % 100);
|
||||
MessageBox(GetDesktopWindow(), t.c_str(), "Blitz3D Message", MB_OK);
|
||||
#endif
|
||||
|
||||
#ifdef SCHOOLS
|
||||
MessageBox( GetDesktopWindow(),"Created with the schools version of Blitz Basic","Blitz Basic Message",MB_OK );
|
||||
MessageBox(GetDesktopWindow(), "Created with the schools version of Blitz Basic", "Blitz Basic Message", MB_OK);
|
||||
#endif
|
||||
|
||||
runtime=runtimeGetRuntime();
|
||||
runtime->startup( inst );
|
||||
runtime = runtimeGetRuntime();
|
||||
runtime->startup(inst);
|
||||
|
||||
link();
|
||||
|
||||
//get cmd_line and params
|
||||
string cmd=GetCommandLine(),params;
|
||||
while( cmd.size() && cmd[0]==' ' ) cmd=cmd.substr( 1 );
|
||||
if( cmd.find( '\"' )==0 ){
|
||||
int n=cmd.find( '\"',1 );
|
||||
if( n!=string::npos ){
|
||||
params=cmd.substr( n+1 );
|
||||
cmd=cmd.substr( 1,n-1 );
|
||||
string cmd = GetCommandLine(), params;
|
||||
while (cmd.size() && cmd[0] == ' ')
|
||||
cmd = cmd.substr(1);
|
||||
if (cmd.find('\"') == 0) {
|
||||
int n = cmd.find('\"', 1);
|
||||
if (n != string::npos) {
|
||||
params = cmd.substr(n + 1);
|
||||
cmd = cmd.substr(1, n - 1);
|
||||
}
|
||||
}else{
|
||||
int n=cmd.find( ' ' );
|
||||
if( n!=string::npos ){
|
||||
params=cmd.substr( n+1 );
|
||||
cmd=cmd.substr( 0,n );
|
||||
} else {
|
||||
int n = cmd.find(' ');
|
||||
if (n != string::npos) {
|
||||
params = cmd.substr(n + 1);
|
||||
cmd = cmd.substr(0, n);
|
||||
}
|
||||
}
|
||||
|
||||
runtime->execute( (void(*)())module_pc,params.c_str(),0 );
|
||||
runtime->execute((void (*)())module_pc, params.c_str(), 0);
|
||||
runtime->shutdown();
|
||||
|
||||
_DllMainCRTStartup( inst,DLL_PROCESS_DETACH,0 );
|
||||
_DllMainCRTStartup(inst, DLL_PROCESS_DETACH, 0);
|
||||
|
||||
ExitProcess(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,21 +10,21 @@
|
||||
|
||||
class Debugger;
|
||||
|
||||
class Runtime{
|
||||
public:
|
||||
class Runtime {
|
||||
public:
|
||||
virtual int version();
|
||||
virtual const char *nextSym();
|
||||
virtual int symValue( const char *sym );
|
||||
virtual void startup( HINSTANCE hinst );
|
||||
virtual const char* nextSym();
|
||||
virtual int symValue(const char* sym);
|
||||
virtual void startup(HINSTANCE hinst);
|
||||
virtual void shutdown();
|
||||
virtual void asyncStop();
|
||||
virtual void asyncRun();
|
||||
virtual void asyncEnd();
|
||||
virtual void checkmem( std::streambuf *buf );
|
||||
virtual void checkmem(std::streambuf* buf);
|
||||
|
||||
virtual void execute( void (*pc)(),const char *args,Debugger *dbg );
|
||||
virtual void execute(void (*pc)(), const char* args, Debugger* dbg);
|
||||
};
|
||||
|
||||
extern "C" _declspec(dllexport) Runtime * _cdecl runtimeGetRuntime();
|
||||
extern "C" _declspec(dllexport) Runtime* _cdecl runtimeGetRuntime();
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.hpp"
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
@@ -1,142 +1,163 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "animation.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
struct Animation::Rep{
|
||||
|
||||
struct Animation::Rep {
|
||||
int ref_cnt;
|
||||
|
||||
typedef map<int,Quat> KeyList;
|
||||
typedef map<int, Quat> KeyList;
|
||||
|
||||
KeyList scale_anim,rot_anim,pos_anim;
|
||||
KeyList scale_anim, rot_anim, pos_anim;
|
||||
|
||||
Rep():
|
||||
ref_cnt(1){
|
||||
}
|
||||
Rep() : ref_cnt(1) {}
|
||||
|
||||
Rep( const Rep &t ):
|
||||
ref_cnt(1),
|
||||
scale_anim(t.scale_anim),rot_anim(t.rot_anim),pos_anim(t.pos_anim){
|
||||
}
|
||||
Rep(const Rep& t) : ref_cnt(1), scale_anim(t.scale_anim), rot_anim(t.rot_anim), pos_anim(t.pos_anim) {}
|
||||
|
||||
Vector getLinearValue( const KeyList &keys,float time )const{
|
||||
KeyList::const_iterator next,curr;
|
||||
Vector getLinearValue(const KeyList& keys, float time) const
|
||||
{
|
||||
KeyList::const_iterator next, curr;
|
||||
|
||||
//for( next=keys.begin();next!=keys.end() && time>=next->first;++next ){}
|
||||
next=keys.upper_bound( (int)time );
|
||||
next = keys.upper_bound((int)time);
|
||||
|
||||
if( next==keys.begin() ) return next->second.v;
|
||||
curr=next;--curr;
|
||||
if( next==keys.end() ) return curr->second.v;
|
||||
if (next == keys.begin())
|
||||
return next->second.v;
|
||||
curr = next;
|
||||
--curr;
|
||||
if (next == keys.end())
|
||||
return curr->second.v;
|
||||
|
||||
float delta=( time-curr->first )/( next->first-curr->first );
|
||||
return ( next->second.v-curr->second.v )*delta+curr->second.v;
|
||||
float delta = (time - curr->first) / (next->first - curr->first);
|
||||
return (next->second.v - curr->second.v) * delta + curr->second.v;
|
||||
}
|
||||
|
||||
Quat getSlerpValue( const KeyList &keys,float time )const{
|
||||
KeyList::const_iterator next,curr;
|
||||
Quat getSlerpValue(const KeyList& keys, float time) const
|
||||
{
|
||||
KeyList::const_iterator next, curr;
|
||||
|
||||
//for( next=keys.begin();next!=keys.end() && time>=next->first;++next ){}
|
||||
next=keys.upper_bound( (int)time );
|
||||
next = keys.upper_bound((int)time);
|
||||
|
||||
if( next==keys.begin() ) return next->second;
|
||||
curr=next;--curr;
|
||||
if( next==keys.end() ) return curr->second;
|
||||
if (next == keys.begin())
|
||||
return next->second;
|
||||
curr = next;
|
||||
--curr;
|
||||
if (next == keys.end())
|
||||
return curr->second;
|
||||
|
||||
float delta=( time-curr->first )/( next->first-curr->first );
|
||||
return curr->second.slerpTo( next->second,delta );
|
||||
float delta = (time - curr->first) / (next->first - curr->first);
|
||||
return curr->second.slerpTo(next->second, delta);
|
||||
}
|
||||
|
||||
void setKey( KeyList &keys,int time,const Quat &value ){
|
||||
keys[time]=value;
|
||||
void setKey(KeyList& keys, int time, const Quat& value)
|
||||
{
|
||||
keys[time] = value;
|
||||
}
|
||||
};
|
||||
|
||||
Animation::Animation():
|
||||
rep( new Rep() ){
|
||||
}
|
||||
Animation::Animation() : rep(new Rep()) {}
|
||||
|
||||
Animation::Animation( const Animation &t ):
|
||||
rep( t.rep ){
|
||||
Animation::Animation(const Animation& t) : rep(t.rep)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
|
||||
Animation::Animation( const Animation &t,int first,int last ):
|
||||
rep( new Rep() ){
|
||||
Animation::Animation(const Animation& t, int first, int last) : rep(new Rep())
|
||||
{
|
||||
Rep::KeyList::const_iterator it;
|
||||
for( it=t.rep->pos_anim.begin();it!=t.rep->pos_anim.end();++it ){
|
||||
if( it->first<first || it->first>last ) continue;
|
||||
rep->setKey( rep->pos_anim,it->first-first,it->second );
|
||||
for (it = t.rep->pos_anim.begin(); it != t.rep->pos_anim.end(); ++it) {
|
||||
if (it->first < first || it->first > last)
|
||||
continue;
|
||||
rep->setKey(rep->pos_anim, it->first - first, it->second);
|
||||
}
|
||||
for( it=t.rep->scale_anim.begin();it!=t.rep->scale_anim.end();++it ){
|
||||
if( it->first<first || it->first>last ) continue;
|
||||
rep->setKey( rep->scale_anim,it->first-first,it->second );
|
||||
for (it = t.rep->scale_anim.begin(); it != t.rep->scale_anim.end(); ++it) {
|
||||
if (it->first < first || it->first > last)
|
||||
continue;
|
||||
rep->setKey(rep->scale_anim, it->first - first, it->second);
|
||||
}
|
||||
for( it=t.rep->rot_anim.begin();it!=t.rep->rot_anim.end();++it ){
|
||||
if( it->first<first || it->first>last ) continue;
|
||||
rep->setKey( rep->rot_anim,it->first-first,it->second );
|
||||
for (it = t.rep->rot_anim.begin(); it != t.rep->rot_anim.end(); ++it) {
|
||||
if (it->first < first || it->first > last)
|
||||
continue;
|
||||
rep->setKey(rep->rot_anim, it->first - first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
Animation::~Animation(){
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
Animation::~Animation()
|
||||
{
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
}
|
||||
|
||||
Animation &Animation::operator=( const Animation &t ){
|
||||
Animation& Animation::operator=(const Animation& t)
|
||||
{
|
||||
++t.rep->ref_cnt;
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
rep=t.rep;
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
rep = t.rep;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Animation::Rep *Animation::write(){
|
||||
if( rep->ref_cnt>1 ){
|
||||
Animation::Rep* Animation::write()
|
||||
{
|
||||
if (rep->ref_cnt > 1) {
|
||||
--rep->ref_cnt;
|
||||
rep=new Rep( *rep );
|
||||
rep = new Rep(*rep);
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
void Animation::setScaleKey( int time,const Vector &q ){
|
||||
void Animation::setScaleKey(int time, const Vector& q)
|
||||
{
|
||||
write();
|
||||
rep->setKey( rep->scale_anim,time,Quat( 0,q ) );
|
||||
rep->setKey(rep->scale_anim, time, Quat(0, q));
|
||||
}
|
||||
|
||||
void Animation::setPositionKey( int time,const Vector &q ){
|
||||
void Animation::setPositionKey(int time, const Vector& q)
|
||||
{
|
||||
write();
|
||||
rep->setKey( rep->pos_anim,time,Quat( 0,q ) );
|
||||
rep->setKey(rep->pos_anim, time, Quat(0, q));
|
||||
}
|
||||
|
||||
void Animation::setRotationKey( int time,const Quat &q ){
|
||||
void Animation::setRotationKey(int time, const Quat& q)
|
||||
{
|
||||
write();
|
||||
rep->setKey( rep->rot_anim,time,q );
|
||||
rep->setKey(rep->rot_anim, time, q);
|
||||
}
|
||||
|
||||
int Animation::numScaleKeys()const{
|
||||
int Animation::numScaleKeys() const
|
||||
{
|
||||
return rep->scale_anim.size();
|
||||
}
|
||||
|
||||
int Animation::numRotationKeys()const{
|
||||
int Animation::numRotationKeys() const
|
||||
{
|
||||
return rep->rot_anim.size();
|
||||
}
|
||||
|
||||
int Animation::numPositionKeys()const{
|
||||
int Animation::numPositionKeys() const
|
||||
{
|
||||
return rep->pos_anim.size();
|
||||
}
|
||||
|
||||
Vector Animation::getScale( float time )const{
|
||||
if( !rep->scale_anim.size() ) return Vector(1,1,1);
|
||||
return rep->getLinearValue( rep->scale_anim,time );
|
||||
Vector Animation::getScale(float time) const
|
||||
{
|
||||
if (!rep->scale_anim.size())
|
||||
return Vector(1, 1, 1);
|
||||
return rep->getLinearValue(rep->scale_anim, time);
|
||||
}
|
||||
|
||||
Vector Animation::getPosition( float time )const{
|
||||
if( !rep->pos_anim.size() ) return Vector(0,0,0);
|
||||
return rep->getLinearValue( rep->pos_anim,time );
|
||||
Vector Animation::getPosition(float time) const
|
||||
{
|
||||
if (!rep->pos_anim.size())
|
||||
return Vector(0, 0, 0);
|
||||
return rep->getLinearValue(rep->pos_anim, time);
|
||||
}
|
||||
|
||||
Quat Animation::getRotation( float time )const{
|
||||
if( !rep->rot_anim.size() ) return Quat();
|
||||
return rep->getSlerpValue( rep->rot_anim,time );
|
||||
Quat Animation::getRotation(float time) const
|
||||
{
|
||||
if (!rep->rot_anim.size())
|
||||
return Quat();
|
||||
return rep->getSlerpValue(rep->rot_anim, time);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -6,32 +6,32 @@
|
||||
|
||||
#include "geom.hpp"
|
||||
|
||||
class Animation{
|
||||
public:
|
||||
class Animation {
|
||||
public:
|
||||
Animation();
|
||||
Animation( const Animation &t );
|
||||
Animation( const Animation &t,int first,int last );
|
||||
Animation(const Animation& t);
|
||||
Animation(const Animation& t, int first, int last);
|
||||
~Animation();
|
||||
|
||||
Animation &operator=( const Animation &t );
|
||||
Animation& operator=(const Animation& t);
|
||||
|
||||
void setScaleKey( int frame,const Vector &q );
|
||||
void setPositionKey( int frame,const Vector &p );
|
||||
void setRotationKey( int frame,const Quat &q );
|
||||
void setScaleKey(int frame, const Vector& q);
|
||||
void setPositionKey(int frame, const Vector& p);
|
||||
void setRotationKey(int frame, const Quat& q);
|
||||
|
||||
int numScaleKeys()const;
|
||||
int numRotationKeys()const;
|
||||
int numPositionKeys()const;
|
||||
int numScaleKeys() const;
|
||||
int numRotationKeys() const;
|
||||
int numPositionKeys() const;
|
||||
|
||||
Vector getScale( float time )const;
|
||||
Vector getPosition( float time )const;
|
||||
Quat getRotation( float time )const;
|
||||
Vector getScale(float time) const;
|
||||
Vector getPosition(float time) const;
|
||||
Quat getRotation(float time) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Rep;
|
||||
Rep *rep;
|
||||
Rep* rep;
|
||||
|
||||
Rep *write();
|
||||
Rep* write();
|
||||
};
|
||||
|
||||
#endif
|
||||
+151
-124
@@ -1,218 +1,245 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "animator.hpp"
|
||||
#include "object.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
Animator::Animator( Animator *t ):_seqs( t->_seqs ){
|
||||
Animator::Animator(Animator* t) : _seqs(t->_seqs)
|
||||
{
|
||||
_objs.resize(t->_objs.size());
|
||||
_anims.resize(t->_anims.size());
|
||||
|
||||
_objs.resize( t->_objs.size() );
|
||||
_anims.resize( t->_anims.size() );
|
||||
|
||||
for( int k=0;k<t->_objs.size();++k ){
|
||||
_objs[k]=t->_objs[k]->getLastCopy();
|
||||
_anims[k].keys=t->_anims[k].keys;
|
||||
for (int k = 0; k < t->_objs.size(); ++k) {
|
||||
_objs[k] = t->_objs[k]->getLastCopy();
|
||||
_anims[k].keys = t->_anims[k].keys;
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
Animator::Animator( Object *obj,int frames ){
|
||||
addObjs( obj );
|
||||
_anims.resize( _objs.size() );
|
||||
addSeq( frames );
|
||||
Animator::Animator(Object* obj, int frames)
|
||||
{
|
||||
addObjs(obj);
|
||||
_anims.resize(_objs.size());
|
||||
addSeq(frames);
|
||||
reset();
|
||||
}
|
||||
|
||||
Animator::Animator( const vector<Object*> &objs,int frames ):_objs(objs){
|
||||
_anims.resize( _objs.size() );
|
||||
addSeq( frames );
|
||||
Animator::Animator(const vector<Object*>& objs, int frames) : _objs(objs)
|
||||
{
|
||||
_anims.resize(_objs.size());
|
||||
addSeq(frames);
|
||||
reset();
|
||||
}
|
||||
|
||||
void Animator::reset(){
|
||||
_seq=_mode=_seq_len=_time=_speed=_trans_time=_trans_speed=0;
|
||||
void Animator::reset()
|
||||
{
|
||||
_seq = _mode = _seq_len = _time = _speed = _trans_time = _trans_speed = 0;
|
||||
}
|
||||
|
||||
void Animator::addObjs( Object *obj ){
|
||||
_objs.push_back( obj );
|
||||
for( Entity *e=obj->GetChildren();e;e=e->GetSuccessor() ){
|
||||
addObjs( e->getObject() );
|
||||
void Animator::addObjs(Object* obj)
|
||||
{
|
||||
_objs.push_back(obj);
|
||||
for (Entity* e = obj->GetChildren(); e; e = e->GetSuccessor()) {
|
||||
addObjs(e->getObject());
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::addSeq( int frames ){
|
||||
void Animator::addSeq(int frames)
|
||||
{
|
||||
Seq seq;
|
||||
seq.frames=frames;
|
||||
_seqs.push_back( seq );
|
||||
for( int k=0;k<_objs.size();++k ){
|
||||
Object *obj=_objs[k];
|
||||
_anims[k].keys.push_back( obj->getAnimation() );
|
||||
obj->setAnimation( Animation() );
|
||||
seq.frames = frames;
|
||||
_seqs.push_back(seq);
|
||||
for (int k = 0; k < _objs.size(); ++k) {
|
||||
Object* obj = _objs[k];
|
||||
_anims[k].keys.push_back(obj->getAnimation());
|
||||
obj->setAnimation(Animation());
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::addSeqs( Animator *t ){
|
||||
for( int n=0;n<t->_seqs.size();++n ){
|
||||
_seqs.push_back( t->_seqs[n] );
|
||||
for( int k=0;k<_objs.size();++k ){
|
||||
void Animator::addSeqs(Animator* t)
|
||||
{
|
||||
for (int n = 0; n < t->_seqs.size(); ++n) {
|
||||
_seqs.push_back(t->_seqs[n]);
|
||||
for (int k = 0; k < _objs.size(); ++k) {
|
||||
int j;
|
||||
for( j=0;j<t->_objs.size();++j ){
|
||||
if( _objs[k]->getName()==t->_objs[j]->getName() ) break;
|
||||
for (j = 0; j < t->_objs.size(); ++j) {
|
||||
if (_objs[k]->getName() == t->_objs[j]->getName())
|
||||
break;
|
||||
}
|
||||
if( j==t->_objs.size() ){
|
||||
_anims[k].keys.push_back( Animation() );
|
||||
if (j == t->_objs.size()) {
|
||||
_anims[k].keys.push_back(Animation());
|
||||
continue;
|
||||
}
|
||||
_anims[k].keys.push_back( t->_anims[j].keys[n] );
|
||||
_anims[k].keys.push_back(t->_anims[j].keys[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::extractSeq( int first,int last,int seq ){
|
||||
void Animator::extractSeq(int first, int last, int seq)
|
||||
{
|
||||
Seq sq;
|
||||
sq.frames=last-first;
|
||||
_seqs.push_back( sq );
|
||||
sq.frames = last - first;
|
||||
_seqs.push_back(sq);
|
||||
|
||||
for( int k=0;k<_objs.size();++k ){
|
||||
Animation &keys=_anims[k].keys[seq];
|
||||
_anims[k].keys.push_back( Animation( keys,first,last ) );
|
||||
for (int k = 0; k < _objs.size(); ++k) {
|
||||
Animation& keys = _anims[k].keys[seq];
|
||||
_anims[k].keys.push_back(Animation(keys, first, last));
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::updateAnim(){
|
||||
void Animator::updateAnim()
|
||||
{
|
||||
for (int k = 0; k < _objs.size(); ++k) {
|
||||
Object* obj = _objs[k];
|
||||
const Animation& keys = _anims[k].keys[_seq];
|
||||
|
||||
for( int k=0;k<_objs.size();++k ){
|
||||
|
||||
Object *obj=_objs[k];
|
||||
const Animation &keys=_anims[k].keys[_seq];
|
||||
|
||||
if( keys.numPositionKeys() ){
|
||||
obj->SetLocalPosition( keys.getPosition( _time ) );
|
||||
if (keys.numPositionKeys()) {
|
||||
obj->SetLocalPosition(keys.getPosition(_time));
|
||||
}
|
||||
if( keys.numScaleKeys() ){
|
||||
obj->SetLocalScale( keys.getScale( _time ) );
|
||||
if (keys.numScaleKeys()) {
|
||||
obj->SetLocalScale(keys.getScale(_time));
|
||||
}
|
||||
if( keys.numRotationKeys() ){
|
||||
obj->SetLocalRotation( keys.getRotation( _time ) );
|
||||
if (keys.numRotationKeys()) {
|
||||
obj->SetLocalRotation(keys.getRotation(_time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::updateTrans(){
|
||||
void Animator::updateTrans()
|
||||
{
|
||||
for (int k = 0; k < _objs.size(); ++k) {
|
||||
Object* obj = _objs[k];
|
||||
const Anim& anim = _anims[k];
|
||||
|
||||
for( int k=0;k<_objs.size();++k ){
|
||||
|
||||
Object *obj=_objs[k];
|
||||
const Anim &anim=_anims[k];
|
||||
|
||||
if( anim.pos ) obj->SetLocalPosition( (anim.dest_pos-anim.src_pos)*_trans_time+anim.src_pos );
|
||||
if( anim.scl ) obj->SetLocalScale( (anim.dest_scl-anim.src_scl)*_trans_time+anim.src_scl );
|
||||
if( anim.rot ) obj->SetLocalRotation( anim.src_rot.slerpTo( anim.dest_rot,_trans_time ) );
|
||||
if (anim.pos)
|
||||
obj->SetLocalPosition((anim.dest_pos - anim.src_pos) * _trans_time + anim.src_pos);
|
||||
if (anim.scl)
|
||||
obj->SetLocalScale((anim.dest_scl - anim.src_scl) * _trans_time + anim.src_scl);
|
||||
if (anim.rot)
|
||||
obj->SetLocalRotation(anim.src_rot.slerpTo(anim.dest_rot, _trans_time));
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::beginTrans(){
|
||||
void Animator::beginTrans()
|
||||
{
|
||||
for (int k = 0; k < _objs.size(); ++k) {
|
||||
Object* obj = _objs[k];
|
||||
Anim& anim = _anims[k];
|
||||
const Animation& keys = _anims[k].keys[_seq];
|
||||
|
||||
for( int k=0;k<_objs.size();++k ){
|
||||
|
||||
Object *obj=_objs[k];
|
||||
Anim &anim=_anims[k];
|
||||
const Animation &keys=_anims[k].keys[_seq];
|
||||
|
||||
if( anim.pos=!!keys.numPositionKeys() ){
|
||||
anim.src_pos=obj->GetLocalPosition();
|
||||
anim.dest_pos=keys.getPosition( _time );
|
||||
if (anim.pos = !!keys.numPositionKeys()) {
|
||||
anim.src_pos = obj->GetLocalPosition();
|
||||
anim.dest_pos = keys.getPosition(_time);
|
||||
}
|
||||
if( anim.scl=!!keys.numScaleKeys() ){
|
||||
anim.src_scl=obj->GetLocalScale();
|
||||
anim.dest_scl=keys.getScale( _time );
|
||||
if (anim.scl = !!keys.numScaleKeys()) {
|
||||
anim.src_scl = obj->GetLocalScale();
|
||||
anim.dest_scl = keys.getScale(_time);
|
||||
}
|
||||
if( anim.rot=!!keys.numRotationKeys() ){
|
||||
anim.src_rot=obj->GetLocalRotation();
|
||||
anim.dest_rot=keys.getRotation( _time );
|
||||
if (anim.rot = !!keys.numRotationKeys()) {
|
||||
anim.src_rot = obj->GetLocalRotation();
|
||||
anim.dest_rot = keys.getRotation(_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::setAnimTime( float time,int seq ){
|
||||
if( seq<0 || seq>_seqs.size() ) return;
|
||||
void Animator::setAnimTime(float time, int seq)
|
||||
{
|
||||
if (seq < 0 || seq > _seqs.size())
|
||||
return;
|
||||
|
||||
_mode=0;
|
||||
_speed=0;
|
||||
_seq=seq;
|
||||
_seq_len=_seqs[_seq].frames;
|
||||
_mode = 0;
|
||||
_speed = 0;
|
||||
_seq = seq;
|
||||
_seq_len = _seqs[_seq].frames;
|
||||
|
||||
//Ok, mod the anim time!
|
||||
_time=fmod( time,_seq_len );
|
||||
_time = fmod(time, _seq_len);
|
||||
|
||||
//if( time<0 || time>_seq_len ) time=fmod( time,_seq_len );
|
||||
//_time=time;
|
||||
|
||||
if( _time<0 ) _time+=+_seq_len;
|
||||
if (_time < 0)
|
||||
_time += +_seq_len;
|
||||
|
||||
updateAnim();
|
||||
}
|
||||
|
||||
void Animator::animate( int mode,float speed,int seq,float trans ){
|
||||
if( !mode && !speed ){ _mode=0;return; }
|
||||
|
||||
if( seq<0 || seq>=_seqs.size() ) return;
|
||||
|
||||
_seq=seq;
|
||||
_mode=mode;
|
||||
_seq_len=_seqs[_seq].frames;
|
||||
_speed=speed;
|
||||
_time=_speed>=0 ? 0 : _seq_len;
|
||||
|
||||
if( trans<=0 ){
|
||||
updateAnim();
|
||||
if( !_speed ) _mode=0;
|
||||
void Animator::animate(int mode, float speed, int seq, float trans)
|
||||
{
|
||||
if (!mode && !speed) {
|
||||
_mode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
_mode|=0x8000;
|
||||
_trans_time=0;
|
||||
_trans_speed=1/trans;
|
||||
if (seq < 0 || seq >= _seqs.size())
|
||||
return;
|
||||
|
||||
_seq = seq;
|
||||
_mode = mode;
|
||||
_seq_len = _seqs[_seq].frames;
|
||||
_speed = speed;
|
||||
_time = _speed >= 0 ? 0 : _seq_len;
|
||||
|
||||
if (trans <= 0) {
|
||||
updateAnim();
|
||||
if (!_speed)
|
||||
_mode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
_mode |= 0x8000;
|
||||
_trans_time = 0;
|
||||
_trans_speed = 1 / trans;
|
||||
beginTrans();
|
||||
}
|
||||
|
||||
void Animator::update( float elapsed ){
|
||||
void Animator::update(float elapsed)
|
||||
{
|
||||
if (!_mode)
|
||||
return;
|
||||
|
||||
if( !_mode ) return;
|
||||
|
||||
if( _mode&0x8000 ){
|
||||
_trans_time+=_trans_speed*elapsed;
|
||||
if( _trans_time<1 ){
|
||||
if (_mode & 0x8000) {
|
||||
_trans_time += _trans_speed * elapsed;
|
||||
if (_trans_time < 1) {
|
||||
updateTrans();
|
||||
return;
|
||||
}
|
||||
_mode&=0x7fff;
|
||||
if( !_mode || !_speed ){
|
||||
_mode &= 0x7fff;
|
||||
if (!_mode || !_speed) {
|
||||
updateAnim();
|
||||
_mode=0;
|
||||
_mode = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//do anim...
|
||||
_time+=_speed*elapsed;
|
||||
_time += _speed * elapsed;
|
||||
|
||||
switch( _mode ){
|
||||
switch (_mode) {
|
||||
case ANIM_MODE_LOOP:
|
||||
_time=fmod( _time,_seq_len );
|
||||
if( _time<0 ) _time+=_seq_len;
|
||||
_time = fmod(_time, _seq_len);
|
||||
if (_time < 0)
|
||||
_time += _seq_len;
|
||||
break;
|
||||
case ANIM_MODE_PINGPONG:
|
||||
_time=fmod( _time,_seq_len*2 );
|
||||
if( _time<0 ) _time+=_seq_len*2;
|
||||
if( _time>=_seq_len ){ _time=_seq_len-(_time-_seq_len);_speed=-_speed; }
|
||||
_time = fmod(_time, _seq_len * 2);
|
||||
if (_time < 0)
|
||||
_time += _seq_len * 2;
|
||||
if (_time >= _seq_len) {
|
||||
_time = _seq_len - (_time - _seq_len);
|
||||
_speed = -_speed;
|
||||
}
|
||||
break;
|
||||
case ANIM_MODE_ONESHOT:
|
||||
if( _time<0 ){ _time=0;_mode=0; }
|
||||
else if( _time>=_seq_len ){ _time=_seq_len;_mode=0; }
|
||||
if (_time < 0) {
|
||||
_time = 0;
|
||||
_mode = 0;
|
||||
} else if (_time >= _seq_len) {
|
||||
_time = _seq_len;
|
||||
_mode = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
updateAnim();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,54 +6,68 @@
|
||||
|
||||
class Object;
|
||||
|
||||
class Animator{
|
||||
public:
|
||||
enum{
|
||||
ANIM_MODE_LOOP=1,
|
||||
ANIM_MODE_PINGPONG=2,
|
||||
ANIM_MODE_ONESHOT=3
|
||||
};
|
||||
class Animator {
|
||||
public:
|
||||
enum { ANIM_MODE_LOOP = 1, ANIM_MODE_PINGPONG = 2, ANIM_MODE_ONESHOT = 3 };
|
||||
|
||||
Animator( Animator *animator );
|
||||
Animator(Animator* animator);
|
||||
|
||||
Animator( Object *tree,int frames );
|
||||
Animator(Object* tree, int frames);
|
||||
|
||||
Animator( const vector<Object*> &objs,int frames );
|
||||
Animator(const vector<Object*>& objs, int frames);
|
||||
|
||||
void addSeq( int frames );
|
||||
void addSeq(int frames);
|
||||
|
||||
void addSeqs( Animator *t );
|
||||
void addSeqs(Animator* t);
|
||||
|
||||
void extractSeq( int first,int last,int seq );
|
||||
void extractSeq(int first, int last, int seq);
|
||||
|
||||
void setAnimTime( float time,int seq );
|
||||
void setAnimTime(float time, int seq);
|
||||
|
||||
void animate( int mode,float speed,int seq,float trans );
|
||||
void animate(int mode, float speed, int seq, float trans);
|
||||
|
||||
void update( float elapsed );
|
||||
void update(float elapsed);
|
||||
|
||||
int animSeq()const{ return _seq; }
|
||||
int animLen()const{ return _seq_len; }
|
||||
float animTime()const{ return _time; }
|
||||
bool animating()const{ return !!_mode; }
|
||||
int animSeq() const
|
||||
{
|
||||
return _seq;
|
||||
}
|
||||
int animLen() const
|
||||
{
|
||||
return _seq_len;
|
||||
}
|
||||
float animTime() const
|
||||
{
|
||||
return _time;
|
||||
}
|
||||
bool animating() const
|
||||
{
|
||||
return !!_mode;
|
||||
}
|
||||
|
||||
int numSeqs()const{ return _seqs.size(); }
|
||||
const vector<Object*> &getObjects()const{ return _objs; }
|
||||
int numSeqs() const
|
||||
{
|
||||
return _seqs.size();
|
||||
}
|
||||
const vector<Object*>& getObjects() const
|
||||
{
|
||||
return _objs;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Seq{
|
||||
private:
|
||||
struct Seq {
|
||||
int frames;
|
||||
};
|
||||
|
||||
struct Anim{
|
||||
struct Anim {
|
||||
//anim keys
|
||||
vector<Animation> keys;
|
||||
//for transitions...
|
||||
bool pos,scl,rot;
|
||||
Vector src_pos,dest_pos;
|
||||
Vector src_scl,dest_scl;
|
||||
Quat src_rot,dest_rot;
|
||||
Anim():pos(false),scl(false),rot(false){}
|
||||
bool pos, scl, rot;
|
||||
Vector src_pos, dest_pos;
|
||||
Vector src_scl, dest_scl;
|
||||
Quat src_rot, dest_rot;
|
||||
Anim() : pos(false), scl(false), rot(false) {}
|
||||
};
|
||||
|
||||
vector<Seq> _seqs;
|
||||
@@ -61,11 +75,11 @@ private:
|
||||
vector<Anim> _anims;
|
||||
vector<Object*> _objs;
|
||||
|
||||
int _seq,_mode,_seq_len;
|
||||
float _time,_speed,_trans_time,_trans_speed;
|
||||
int _seq, _mode, _seq_len;
|
||||
float _time, _speed, _trans_time, _trans_speed;
|
||||
|
||||
void reset();
|
||||
void addObjs( Object *obj );
|
||||
void addObjs(Object* obj);
|
||||
void updateAnim();
|
||||
void beginTrans();
|
||||
void updateTrans();
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
|
||||
#include "bd2model.hpp"
|
||||
|
||||
struct BD2Vert{
|
||||
unsigned char x,y,z,n,u,v;
|
||||
struct BD2Vert {
|
||||
unsigned char x, y, z, n, u, v;
|
||||
};
|
||||
|
||||
struct BD2Tri{
|
||||
unsigned short v0,v1,v2;
|
||||
struct BD2Tri {
|
||||
unsigned short v0, v1, v2;
|
||||
};
|
||||
|
||||
struct BD2Frame{
|
||||
float x_scale,y_scale,z_scale;
|
||||
float x_offset,y_offset,z_offset;
|
||||
struct BD2Frame {
|
||||
float x_scale, y_scale, z_scale;
|
||||
float x_offset, y_offset, z_offset;
|
||||
BD2Vert verts[1];
|
||||
};
|
||||
|
||||
struct BD2File{
|
||||
struct BD2File {
|
||||
int id; //'BD2F'
|
||||
float u_scale,v_scale;
|
||||
int n_verts,n_tris,n_frames;
|
||||
float u_scale, v_scale;
|
||||
int n_verts, n_tris, n_frames;
|
||||
BD2Tri tris[1];
|
||||
BD2Frame frames[1];
|
||||
};
|
||||
|
||||
struct BD2Model::Rep{
|
||||
};
|
||||
struct BD2Model::Rep {};
|
||||
@@ -2,12 +2,11 @@
|
||||
#ifndef BD2MODEL_H
|
||||
#define BD2MODEL_H
|
||||
|
||||
class BD2Model : public Model{
|
||||
public:
|
||||
private:
|
||||
class BD2Model : public Model {
|
||||
public:
|
||||
private:
|
||||
struct Rep;
|
||||
Rep *rep;
|
||||
Rep* rep;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
+127
-122
@@ -1,201 +1,206 @@
|
||||
|
||||
#include <cfloat>
|
||||
#include "std.hpp"
|
||||
#include "world.hpp"
|
||||
#include <cfloat>
|
||||
|
||||
static World *w;
|
||||
static World* w;
|
||||
|
||||
struct Face{
|
||||
struct Face {
|
||||
Vector verts[4];
|
||||
|
||||
Face( const Vector &v0,const Vector &v1,const Vector &v2,const Vector &v3 ){
|
||||
verts[0]=v0;
|
||||
verts[1]=v1;
|
||||
verts[2]=v2;
|
||||
verts[3]=v3;
|
||||
Face(const Vector& v0, const Vector& v1, const Vector& v2, const Vector& v3)
|
||||
{
|
||||
verts[0] = v0;
|
||||
verts[1] = v1;
|
||||
verts[2] = v2;
|
||||
verts[3] = v3;
|
||||
}
|
||||
};
|
||||
|
||||
static int face_verts[][4]={
|
||||
2,3,1,0,
|
||||
3,7,5,1,
|
||||
7,6,4,5,
|
||||
6,2,0,4,
|
||||
6,7,3,2,
|
||||
0,1,5,4
|
||||
static int face_verts[][4] = {2, 3, 1, 0, 3, 7, 5, 1, 7, 6, 4, 5, 6, 2, 0, 4, 6, 7, 3, 2, 0, 1, 5, 4};
|
||||
|
||||
struct Coll {
|
||||
int obj, surf, tri;
|
||||
Coll(const ObjCollision& t) : obj((int)t.with), surf((int)t.collision.surface), tri(t.collision.index) {}
|
||||
};
|
||||
|
||||
struct Coll{
|
||||
int obj,surf,tri;
|
||||
Coll( const ObjCollision &t ):obj((int)t.with),surf((int)t.collision.surface),tri(t.collision.index){
|
||||
}
|
||||
};
|
||||
|
||||
struct CollCmp{
|
||||
bool operator()( const Coll &a,const Coll &b )const{
|
||||
if( a.obj<b.obj ) return true;
|
||||
if( b.obj<a.obj ) return false;
|
||||
if( a.surf<b.surf ) return true;
|
||||
if( b.surf<a.surf ) return false;
|
||||
if( a.tri<b.tri ) return true;
|
||||
struct CollCmp {
|
||||
bool operator()(const Coll& a, const Coll& b) const
|
||||
{
|
||||
if (a.obj < b.obj)
|
||||
return true;
|
||||
if (b.obj < a.obj)
|
||||
return false;
|
||||
if (a.surf < b.surf)
|
||||
return true;
|
||||
if (b.surf < a.surf)
|
||||
return false;
|
||||
if (a.tri < b.tri)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
typedef set<Coll,CollCmp> CollSet;
|
||||
typedef set<Coll, CollCmp> CollSet;
|
||||
|
||||
//returns: 1 for visible, 0 for hidden, -1 for don't know
|
||||
static int faceVis( const Face &src,const Face &dest ){
|
||||
|
||||
static int faceVis(const Face& src, const Face& dest)
|
||||
{
|
||||
static CollSet all;
|
||||
static CollSet colls[16];
|
||||
|
||||
all.clear();
|
||||
|
||||
for( int k=0;k<4;++k ){
|
||||
for( int j=0;j<4;++j ){
|
||||
int n=k*4+j;
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
int n = k * 4 + j;
|
||||
colls[n].clear();
|
||||
|
||||
Vector sv=src.verts[k];
|
||||
Vector dv=dest.verts[j];
|
||||
Vector adj=(dv-sv).normalized()*.01f;
|
||||
dv-=adj;
|
||||
Vector sv = src.verts[k];
|
||||
Vector dv = dest.verts[j];
|
||||
Vector adj = (dv - sv).normalized() * .01f;
|
||||
dv -= adj;
|
||||
|
||||
for(;;){
|
||||
sv+=adj;
|
||||
Line line( sv,dv-sv );
|
||||
for (;;) {
|
||||
sv += adj;
|
||||
Line line(sv, dv - sv);
|
||||
|
||||
ObjCollision c;
|
||||
if( !w->traceRay( line,EPSILON,&c ) ) break;
|
||||
if (!w->traceRay(line, EPSILON, &c))
|
||||
break;
|
||||
|
||||
Coll t( c );
|
||||
all.insert( t );
|
||||
colls[n].insert( t );
|
||||
Coll t(c);
|
||||
all.insert(t);
|
||||
colls[n].insert(t);
|
||||
|
||||
sv=c.coords;
|
||||
sv = c.coords;
|
||||
}
|
||||
if( !colls[n].size() ) return 1;
|
||||
if (!colls[n].size())
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
CollSet::const_iterator it;
|
||||
for( it=all.begin();it!=all.end();++it ){
|
||||
int k=0;
|
||||
for( ;k<16;++k ){
|
||||
if( !colls[k].count( *it ) ) break;
|
||||
for (it = all.begin(); it != all.end(); ++it) {
|
||||
int k = 0;
|
||||
for (; k < 16; ++k) {
|
||||
if (!colls[k].count(*it))
|
||||
break;
|
||||
}
|
||||
if( k==16 ) return 0; //definitely hidden!
|
||||
if (k == 16)
|
||||
return 0; //definitely hidden!
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void subdivide( list<Face> &lst ){
|
||||
int n=lst.size();
|
||||
while( n-- ){
|
||||
const Face &f=lst.front();
|
||||
Vector a( (f.verts[0]+f.verts[1])/2 );
|
||||
Vector b( (f.verts[1]+f.verts[2])/2 );
|
||||
Vector c( (f.verts[2]+f.verts[3])/2 );
|
||||
Vector d( (f.verts[3]+f.verts[0])/2 );
|
||||
Vector e( (f.verts[0]+f.verts[1]+f.verts[2]+f.verts[3])/4 );
|
||||
lst.push_back( Face( f.verts[0],a,e,d ) );
|
||||
lst.push_back( Face( a,f.verts[1],b,e ) );
|
||||
lst.push_back( Face( e,b,f.verts[2],c ) );
|
||||
lst.push_back( Face( d,e,c,f.verts[3] ) );
|
||||
lst.erase( lst.begin() );
|
||||
static void subdivide(list<Face>& lst)
|
||||
{
|
||||
int n = lst.size();
|
||||
while (n--) {
|
||||
const Face& f = lst.front();
|
||||
Vector a((f.verts[0] + f.verts[1]) / 2);
|
||||
Vector b((f.verts[1] + f.verts[2]) / 2);
|
||||
Vector c((f.verts[2] + f.verts[3]) / 2);
|
||||
Vector d((f.verts[3] + f.verts[0]) / 2);
|
||||
Vector e((f.verts[0] + f.verts[1] + f.verts[2] + f.verts[3]) / 4);
|
||||
lst.push_back(Face(f.verts[0], a, e, d));
|
||||
lst.push_back(Face(a, f.verts[1], b, e));
|
||||
lst.push_back(Face(e, b, f.verts[2], c));
|
||||
lst.push_back(Face(d, e, c, f.verts[3]));
|
||||
lst.erase(lst.begin());
|
||||
}
|
||||
}
|
||||
|
||||
static int faceVis( const Face &src,const Face &dest,int recurs_limit ){
|
||||
|
||||
static list<Face> src_faces,dest_faces;
|
||||
static int faceVis(const Face& src, const Face& dest, int recurs_limit)
|
||||
{
|
||||
static list<Face> src_faces, dest_faces;
|
||||
|
||||
src_faces.clear();
|
||||
dest_faces.clear();
|
||||
|
||||
src_faces.push_back( src );
|
||||
dest_faces.push_back( dest );
|
||||
src_faces.push_back(src);
|
||||
dest_faces.push_back(dest);
|
||||
|
||||
while( recurs_limit-- ){
|
||||
list<Face>::iterator src_it,dest_it;
|
||||
for( src_it=src_faces.begin();src_it!=src_faces.end();++src_it ){
|
||||
int cnt=0;
|
||||
for( dest_it=dest_faces.begin();dest_it!=dest_faces.end();++dest_it ){
|
||||
int n=faceVis( *src_it,*dest_it );
|
||||
if( n==1 ) return 1;
|
||||
if( !n ) ++cnt;
|
||||
while (recurs_limit--) {
|
||||
list<Face>::iterator src_it, dest_it;
|
||||
for (src_it = src_faces.begin(); src_it != src_faces.end(); ++src_it) {
|
||||
int cnt = 0;
|
||||
for (dest_it = dest_faces.begin(); dest_it != dest_faces.end(); ++dest_it) {
|
||||
int n = faceVis(*src_it, *dest_it);
|
||||
if (n == 1)
|
||||
return 1;
|
||||
if (!n)
|
||||
++cnt;
|
||||
}
|
||||
if( cnt==dest_faces.size() ){
|
||||
if (cnt == dest_faces.size()) {
|
||||
//source can't see ANY dest faces
|
||||
src_it=src_faces.erase( src_it );
|
||||
src_it = src_faces.erase(src_it);
|
||||
--src_it;
|
||||
}
|
||||
}
|
||||
if( !src_faces.size() ) return 0;
|
||||
if (!src_faces.size())
|
||||
return 0;
|
||||
//ok, subdivide!
|
||||
subdivide( src_faces );
|
||||
subdivide( dest_faces );
|
||||
subdivide(src_faces);
|
||||
subdivide(dest_faces);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool World::boxVis( const Box &src,const Box &dest,int recurs_limit ){
|
||||
|
||||
w=this;
|
||||
bool World::boxVis(const Box& src, const Box& dest, int recurs_limit)
|
||||
{
|
||||
w = this;
|
||||
|
||||
Box big;
|
||||
|
||||
big.update( src );
|
||||
big.update( dest );
|
||||
big.update(src);
|
||||
big.update(dest);
|
||||
|
||||
Plane planes[6];
|
||||
|
||||
for( int n=0;n<6;++n ){
|
||||
planes[n]=Plane(
|
||||
big.corner( face_verts[n][0] ),
|
||||
big.corner( face_verts[n][1] ),
|
||||
big.corner( face_verts[n][2] ));
|
||||
for (int n = 0; n < 6; ++n) {
|
||||
planes[n] = Plane(big.corner(face_verts[n][0]), big.corner(face_verts[n][1]), big.corner(face_verts[n][2]));
|
||||
}
|
||||
|
||||
for( int k=0;k<6;++k ){
|
||||
Vector v0=src.corner( face_verts[k][0] );
|
||||
Vector v1=src.corner( face_verts[k][1] );
|
||||
Vector v2=src.corner( face_verts[k][2] );
|
||||
Vector v3=src.corner( face_verts[k][3] );
|
||||
for (int k = 0; k < 6; ++k) {
|
||||
Vector v0 = src.corner(face_verts[k][0]);
|
||||
Vector v1 = src.corner(face_verts[k][1]);
|
||||
Vector v2 = src.corner(face_verts[k][2]);
|
||||
Vector v3 = src.corner(face_verts[k][3]);
|
||||
|
||||
int n;
|
||||
for( n=0;n<6;++n ){
|
||||
const Plane &p=planes[n];
|
||||
if( fabs(p.distance(v0))<=EPSILON &&
|
||||
fabs(p.distance(v1))<=EPSILON &&
|
||||
fabs(p.distance(v2))<=EPSILON &&
|
||||
fabs(p.distance(v3))<=EPSILON ) break;
|
||||
for (n = 0; n < 6; ++n) {
|
||||
const Plane& p = planes[n];
|
||||
if (fabs(p.distance(v0)) <= EPSILON && fabs(p.distance(v1)) <= EPSILON && fabs(p.distance(v2)) <= EPSILON
|
||||
&& fabs(p.distance(v3)) <= EPSILON)
|
||||
break;
|
||||
}
|
||||
if( n<6 ) continue;
|
||||
if (n < 6)
|
||||
continue;
|
||||
|
||||
Face src_face( v0,v1,v2,v3 );
|
||||
Face src_face(v0, v1, v2, v3);
|
||||
|
||||
for( int j=0;j<6;++j ){
|
||||
Vector v0=dest.corner( face_verts[j][0] );
|
||||
Vector v1=dest.corner( face_verts[j][1] );
|
||||
Vector v2=dest.corner( face_verts[j][2] );
|
||||
Vector v3=dest.corner( face_verts[j][3] );
|
||||
for (int j = 0; j < 6; ++j) {
|
||||
Vector v0 = dest.corner(face_verts[j][0]);
|
||||
Vector v1 = dest.corner(face_verts[j][1]);
|
||||
Vector v2 = dest.corner(face_verts[j][2]);
|
||||
Vector v3 = dest.corner(face_verts[j][3]);
|
||||
|
||||
int n;
|
||||
for( n=0;n<6;++n ){
|
||||
const Plane &p=planes[n];
|
||||
if( fabs(p.distance(v0))<=EPSILON &&
|
||||
fabs(p.distance(v1))<=EPSILON &&
|
||||
fabs(p.distance(v2))<=EPSILON &&
|
||||
fabs(p.distance(v3))<=EPSILON ) break;
|
||||
for (n = 0; n < 6; ++n) {
|
||||
const Plane& p = planes[n];
|
||||
if (fabs(p.distance(v0)) <= EPSILON && fabs(p.distance(v1)) <= EPSILON
|
||||
&& fabs(p.distance(v2)) <= EPSILON && fabs(p.distance(v3)) <= EPSILON)
|
||||
break;
|
||||
}
|
||||
if( n<6 ) continue;
|
||||
if (n < 6)
|
||||
continue;
|
||||
|
||||
Face dest_face( v0,v1,v2,v3 );
|
||||
Face dest_face(v0, v1, v2, v3);
|
||||
|
||||
int t=faceVis( src_face,dest_face,recurs_limit );
|
||||
int t = faceVis(src_face, dest_face, recurs_limit);
|
||||
|
||||
if( t ) return true;
|
||||
if (t)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
+136
-107
@@ -1,211 +1,240 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "brush.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
#include "../gxruntime/gxgraphics.hpp"
|
||||
|
||||
struct Brush::Rep{
|
||||
union{ int ref_cnt;Rep *next; };
|
||||
int blend,max_tex;
|
||||
struct Brush::Rep {
|
||||
union {
|
||||
int ref_cnt;
|
||||
Rep* next;
|
||||
};
|
||||
int blend, max_tex;
|
||||
bool blend_valid;
|
||||
gxScene::RenderState rs;
|
||||
Texture texs[gxScene::MAX_TEXTURES];
|
||||
|
||||
static Rep *pool;
|
||||
static Rep* pool;
|
||||
|
||||
Rep():
|
||||
ref_cnt(1),blend(0),max_tex(0),blend_valid(true){
|
||||
memset( &rs,0,sizeof(rs) );
|
||||
rs.blend=gxScene::BLEND_REPLACE;
|
||||
rs.color[0]=rs.color[1]=rs.color[2]=rs.alpha=1;
|
||||
Rep() : ref_cnt(1), blend(0), max_tex(0), blend_valid(true)
|
||||
{
|
||||
memset(&rs, 0, sizeof(rs));
|
||||
rs.blend = gxScene::BLEND_REPLACE;
|
||||
rs.color[0] = rs.color[1] = rs.color[2] = rs.alpha = 1;
|
||||
}
|
||||
|
||||
Rep( const Rep &t ):
|
||||
ref_cnt(1),blend(t.blend),max_tex(t.max_tex),rs(t.rs),blend_valid(t.blend_valid){
|
||||
for( int k=0;k<max_tex;++k ) texs[k]=t.texs[k];
|
||||
Rep(const Rep& t) : ref_cnt(1), blend(t.blend), max_tex(t.max_tex), rs(t.rs), blend_valid(t.blend_valid)
|
||||
{
|
||||
for (int k = 0; k < max_tex; ++k)
|
||||
texs[k] = t.texs[k];
|
||||
}
|
||||
|
||||
void *operator new( size_t sz ){
|
||||
static const int GROW=64;
|
||||
if( !pool ){
|
||||
pool=new Rep[GROW];
|
||||
for( int k=0;k<GROW-1;++k ) pool[k].next=&pool[k+1];
|
||||
pool[GROW-1].next=0;
|
||||
void* operator new(size_t sz)
|
||||
{
|
||||
static const int GROW = 64;
|
||||
if (!pool) {
|
||||
pool = new Rep[GROW];
|
||||
for (int k = 0; k < GROW - 1; ++k)
|
||||
pool[k].next = &pool[k + 1];
|
||||
pool[GROW - 1].next = 0;
|
||||
}
|
||||
Rep *p=pool;
|
||||
pool=p->next;
|
||||
Rep* p = pool;
|
||||
pool = p->next;
|
||||
return p;
|
||||
}
|
||||
|
||||
void operator delete( void *q ){
|
||||
Rep *p=(Rep*)q;
|
||||
p->next=pool;
|
||||
pool=p;
|
||||
void operator delete(void* q)
|
||||
{
|
||||
Rep* p = (Rep*)q;
|
||||
p->next = pool;
|
||||
pool = p;
|
||||
}
|
||||
};
|
||||
|
||||
Brush::Rep *Brush::Rep::pool;
|
||||
Brush::Rep* Brush::Rep::pool;
|
||||
|
||||
Brush::Brush():
|
||||
rep( new Rep() ){
|
||||
}
|
||||
Brush::Brush() : rep(new Rep()) {}
|
||||
|
||||
Brush::Brush( const Brush &t ):
|
||||
rep( t.rep ){
|
||||
Brush::Brush(const Brush& t) : rep(t.rep)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
|
||||
Brush::Brush( const Brush &a,const Brush &b ):
|
||||
rep( new Rep( *a.rep ) ){
|
||||
Brush::Brush(const Brush& a, const Brush& b) : rep(new Rep(*a.rep))
|
||||
{
|
||||
*(Vector*)rep->rs.color *= *(Vector*)b.rep->rs.color;
|
||||
|
||||
*(Vector*)rep->rs.color*=*(Vector*)b.rep->rs.color;
|
||||
rep->rs.alpha *= b.rep->rs.alpha;
|
||||
rep->rs.shininess += b.rep->rs.shininess;
|
||||
|
||||
rep->rs.alpha*=b.rep->rs.alpha;
|
||||
rep->rs.shininess+=b.rep->rs.shininess;
|
||||
if (b.rep->blend)
|
||||
rep->blend = b.rep->blend;
|
||||
|
||||
if( b.rep->blend ) rep->blend=b.rep->blend;
|
||||
rep->rs.fx |= b.rep->rs.fx;
|
||||
|
||||
rep->rs.fx|=b.rep->rs.fx;
|
||||
if (b.rep->max_tex > rep->max_tex)
|
||||
rep->max_tex = b.rep->max_tex;
|
||||
|
||||
if( b.rep->max_tex>rep->max_tex ) rep->max_tex=b.rep->max_tex;
|
||||
|
||||
for( int k=0;k<rep->max_tex;++k ){
|
||||
if( b.rep->rs.tex_states[k].canvas ){
|
||||
rep->rs.tex_states[k].canvas=b.rep->rs.tex_states[k].canvas;
|
||||
rep->texs[k]=b.rep->texs[k];
|
||||
for (int k = 0; k < rep->max_tex; ++k) {
|
||||
if (b.rep->rs.tex_states[k].canvas) {
|
||||
rep->rs.tex_states[k].canvas = b.rep->rs.tex_states[k].canvas;
|
||||
rep->texs[k] = b.rep->texs[k];
|
||||
}
|
||||
}
|
||||
|
||||
rep->blend_valid=false;
|
||||
rep->blend_valid = false;
|
||||
}
|
||||
|
||||
Brush::~Brush(){
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
Brush::~Brush()
|
||||
{
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
}
|
||||
|
||||
Brush &Brush::operator=( const Brush &t ){
|
||||
Brush& Brush::operator=(const Brush& t)
|
||||
{
|
||||
++t.rep->ref_cnt;
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
rep=t.rep;return *this;
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
rep = t.rep;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Brush::Rep *Brush::write()const{
|
||||
if( rep->ref_cnt>1 ){
|
||||
Brush::Rep* Brush::write() const
|
||||
{
|
||||
if (rep->ref_cnt > 1) {
|
||||
--rep->ref_cnt;
|
||||
rep=new Rep( *rep );
|
||||
rep = new Rep(*rep);
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
void Brush::setColor( const Vector &color ){
|
||||
*(Vector*)write()->rs.color=color;
|
||||
void Brush::setColor(const Vector& color)
|
||||
{
|
||||
*(Vector*)write()->rs.color = color;
|
||||
}
|
||||
|
||||
void Brush::setAlpha( float alpha ){
|
||||
float a=rep->rs.alpha;
|
||||
write()->rs.alpha=alpha;
|
||||
if( (a<1)!=(alpha<1) ) rep->blend_valid=false;
|
||||
void Brush::setAlpha(float alpha)
|
||||
{
|
||||
float a = rep->rs.alpha;
|
||||
write()->rs.alpha = alpha;
|
||||
if ((a < 1) != (alpha < 1))
|
||||
rep->blend_valid = false;
|
||||
}
|
||||
|
||||
void Brush::setShininess( float n ){
|
||||
write()->rs.shininess=n;
|
||||
void Brush::setShininess(float n)
|
||||
{
|
||||
write()->rs.shininess = n;
|
||||
}
|
||||
|
||||
void Brush::setBlend( int blend ){
|
||||
write()->blend=blend;
|
||||
rep->blend_valid=false;
|
||||
void Brush::setBlend(int blend)
|
||||
{
|
||||
write()->blend = blend;
|
||||
rep->blend_valid = false;
|
||||
}
|
||||
|
||||
void Brush::setFX( int fx ){
|
||||
write()->rs.fx=fx;
|
||||
rep->blend_valid=false;
|
||||
void Brush::setFX(int fx)
|
||||
{
|
||||
write()->rs.fx = fx;
|
||||
rep->blend_valid = false;
|
||||
}
|
||||
|
||||
void Brush::setTexture( int index,const Texture &t,int n ){
|
||||
void Brush::setTexture(int index, const Texture& t, int n)
|
||||
{
|
||||
write();
|
||||
gxScene::RenderState &rs=rep->rs;
|
||||
gxScene::RenderState& rs = rep->rs;
|
||||
|
||||
rep->texs[index]=t;
|
||||
rs.tex_states[index].canvas=t.getCanvas( n );
|
||||
rep->texs[index] = t;
|
||||
rs.tex_states[index].canvas = t.getCanvas(n);
|
||||
|
||||
rep->max_tex=0;
|
||||
for( int k=0;k<gxScene::MAX_TEXTURES;++k ){
|
||||
if( rs.tex_states[k].canvas ) rep->max_tex=k+1;
|
||||
rep->max_tex = 0;
|
||||
for (int k = 0; k < gxScene::MAX_TEXTURES; ++k) {
|
||||
if (rs.tex_states[k].canvas)
|
||||
rep->max_tex = k + 1;
|
||||
}
|
||||
rep->blend_valid=false;
|
||||
rep->blend_valid = false;
|
||||
}
|
||||
|
||||
const Vector &Brush::getColor()const{
|
||||
const Vector& Brush::getColor() const
|
||||
{
|
||||
return *(Vector*)rep->rs.color;
|
||||
}
|
||||
|
||||
float Brush::getAlpha()const{
|
||||
float Brush::getAlpha() const
|
||||
{
|
||||
return rep->rs.alpha;
|
||||
}
|
||||
|
||||
float Brush::getShininess()const{
|
||||
float Brush::getShininess() const
|
||||
{
|
||||
return rep->rs.shininess;
|
||||
}
|
||||
|
||||
int Brush::getBlend()const{
|
||||
if( rep->blend_valid ) return rep->rs.blend;
|
||||
int Brush::getBlend() const
|
||||
{
|
||||
if (rep->blend_valid)
|
||||
return rep->rs.blend;
|
||||
|
||||
rep->blend_valid=true; //well, it will be...
|
||||
rep->blend_valid = true; //well, it will be...
|
||||
|
||||
gxScene::RenderState &rs=rep->rs;
|
||||
gxScene::RenderState& rs = rep->rs;
|
||||
|
||||
//alphatest
|
||||
if( rep->texs[0].getCanvasFlags() & gxCanvas::CANVAS_TEX_MASK ){
|
||||
rs.fx|=gxScene::FX_ALPHATEST;
|
||||
}else{
|
||||
rs.fx&=~gxScene::FX_ALPHATEST;
|
||||
if (rep->texs[0].getCanvasFlags() & gxCanvas::CANVAS_TEX_MASK) {
|
||||
rs.fx |= gxScene::FX_ALPHATEST;
|
||||
} else {
|
||||
rs.fx &= ~gxScene::FX_ALPHATEST;
|
||||
}
|
||||
|
||||
//0 = default/replace
|
||||
//1 = alpha
|
||||
//2 = multiply
|
||||
//3 = add
|
||||
if( rep->blend ){
|
||||
if( rep->blend!=gxScene::BLEND_ALPHA ){
|
||||
return rs.blend=rep->blend;
|
||||
if (rep->blend) {
|
||||
if (rep->blend != gxScene::BLEND_ALPHA) {
|
||||
return rs.blend = rep->blend;
|
||||
}
|
||||
for( int k=0;k<rep->max_tex;++k ){
|
||||
if( rep->texs[k].isTransparent() ){
|
||||
return rs.blend=gxScene::BLEND_ALPHA;
|
||||
for (int k = 0; k < rep->max_tex; ++k) {
|
||||
if (rep->texs[k].isTransparent()) {
|
||||
return rs.blend = gxScene::BLEND_ALPHA;
|
||||
}
|
||||
}
|
||||
}else if( rep->max_tex==1 && rep->texs[0].isTransparent() ){
|
||||
} else if (rep->max_tex == 1 && rep->texs[0].isTransparent()) {
|
||||
//single transparent texture?
|
||||
return rs.blend=gxScene::BLEND_ALPHA;
|
||||
return rs.blend = gxScene::BLEND_ALPHA;
|
||||
}
|
||||
|
||||
//vertex alpha or entityalpha?
|
||||
if( (rs.fx&gxScene::FX_VERTEXALPHA) || rs.alpha<1 ){
|
||||
return rs.blend=gxScene::BLEND_ALPHA;
|
||||
if ((rs.fx & gxScene::FX_VERTEXALPHA) || rs.alpha < 1) {
|
||||
return rs.blend = gxScene::BLEND_ALPHA;
|
||||
}
|
||||
|
||||
return rs.blend=gxScene::BLEND_REPLACE;
|
||||
return rs.blend = gxScene::BLEND_REPLACE;
|
||||
}
|
||||
|
||||
int Brush::getFX()const{
|
||||
int Brush::getFX() const
|
||||
{
|
||||
return rep->rs.fx;
|
||||
}
|
||||
|
||||
Texture Brush::getTexture( int index )const{
|
||||
Texture Brush::getTexture(int index) const
|
||||
{
|
||||
return rep->texs[index];
|
||||
}
|
||||
|
||||
const gxScene::RenderState &Brush::getRenderState()const{
|
||||
const gxScene::RenderState& Brush::getRenderState() const
|
||||
{
|
||||
getBlend();
|
||||
for( int k=0;k<rep->max_tex;++k ){
|
||||
gxScene::RenderState::TexState *ts=&rep->rs.tex_states[k];
|
||||
ts->matrix=rep->texs[k].getMatrix();
|
||||
ts->blend=rep->texs[k].getBlend();
|
||||
ts->flags=rep->texs[k].getFlags();
|
||||
for (int k = 0; k < rep->max_tex; ++k) {
|
||||
gxScene::RenderState::TexState* ts = &rep->rs.tex_states[k];
|
||||
ts->matrix = rep->texs[k].getMatrix();
|
||||
ts->blend = rep->texs[k].getBlend();
|
||||
ts->flags = rep->texs[k].getFlags();
|
||||
}
|
||||
return rep->rs;
|
||||
}
|
||||
|
||||
bool Brush::operator<( const Brush &t )const{
|
||||
return memcmp( &getRenderState(),&t.getRenderState(),sizeof(gxScene::RenderState) )<0;
|
||||
bool Brush::operator<(const Brush& t) const
|
||||
{
|
||||
return memcmp(&getRenderState(), &t.getRenderState(), sizeof(gxScene::RenderState)) < 0;
|
||||
}
|
||||
|
||||
+22
-22
@@ -5,38 +5,38 @@
|
||||
#include "geom.hpp"
|
||||
#include "texture.hpp"
|
||||
|
||||
class Brush{
|
||||
public:
|
||||
class Brush {
|
||||
public:
|
||||
Brush();
|
||||
Brush( const Brush &t );
|
||||
Brush( const Brush &a,const Brush &b );
|
||||
Brush(const Brush& t);
|
||||
Brush(const Brush& a, const Brush& b);
|
||||
~Brush();
|
||||
|
||||
Brush &operator=( const Brush &t );
|
||||
Brush& operator=(const Brush& t);
|
||||
|
||||
void setColor( const Vector &color );
|
||||
void setAlpha( float alpha );
|
||||
void setShininess( float shininess );
|
||||
void setBlend( int blend );
|
||||
void setFX( int fx );
|
||||
void setTexture( int index,const Texture &t,int frame );
|
||||
void setColor(const Vector& color);
|
||||
void setAlpha(float alpha);
|
||||
void setShininess(float shininess);
|
||||
void setBlend(int blend);
|
||||
void setFX(int fx);
|
||||
void setTexture(int index, const Texture& t, int frame);
|
||||
|
||||
const Vector &getColor()const;
|
||||
float getAlpha()const;
|
||||
float getShininess()const;
|
||||
int getBlend()const;
|
||||
int getFX()const;
|
||||
Texture getTexture( int index )const;
|
||||
const Vector& getColor() const;
|
||||
float getAlpha() const;
|
||||
float getShininess() const;
|
||||
int getBlend() const;
|
||||
int getFX() const;
|
||||
Texture getTexture(int index) const;
|
||||
|
||||
const gxScene::RenderState &getRenderState()const;
|
||||
const gxScene::RenderState& getRenderState() const;
|
||||
|
||||
bool operator<( const Brush &b )const;
|
||||
bool operator<(const Brush& b) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Rep;
|
||||
mutable Rep *rep;
|
||||
mutable Rep* rep;
|
||||
|
||||
Rep *write()const;
|
||||
Rep* write() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,165 +1,187 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "cachedtexture.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
int active_texs;
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxRuntime* gx_runtime;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
set<CachedTextureFactory::CachedTexture*> CachedTextureFactory::rep_set;
|
||||
|
||||
static string path;
|
||||
|
||||
struct CachedTextureFactory::CachedTexture{
|
||||
struct CachedTextureFactory::CachedTexture {
|
||||
int ref_cnt;
|
||||
string file;
|
||||
int flags,w,h,first;
|
||||
int flags, w, h, first;
|
||||
vector<gxCanvas*> frames;
|
||||
|
||||
CachedTexture( int w,int h,int flags,int cnt ):
|
||||
ref_cnt(1),flags(flags),w(w),h(h),first(0){
|
||||
CachedTexture(int w, int h, int flags, int cnt) : ref_cnt(1), flags(flags), w(w), h(h), first(0)
|
||||
{
|
||||
++active_texs;
|
||||
while( cnt-->0 ){
|
||||
if( gxCanvas *t=gx_graphics->createCanvas( w,h,flags ) ){
|
||||
frames.push_back( t );
|
||||
}else break;
|
||||
while (cnt-- > 0) {
|
||||
if (gxCanvas* t = gx_graphics->createCanvas(w, h, flags)) {
|
||||
frames.push_back(t);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CachedTexture( const string &f,int flags,int w,int h,int first,int cnt ):
|
||||
ref_cnt(1),file(f),flags(flags),w(w),h(h),first(first){
|
||||
CachedTexture(const string& f, int flags, int w, int h, int first, int cnt)
|
||||
: ref_cnt(1), file(f), flags(flags), w(w), h(h), first(first)
|
||||
{
|
||||
++active_texs;
|
||||
if( !(flags & gxCanvas::CANVAS_TEX_CUBE) ){
|
||||
if( w<=0 || h<=0 || first<0 || cnt<=0 ){
|
||||
w=h=first=0;
|
||||
if( gxCanvas *t=gx_graphics->loadCanvas( f,flags ) ){
|
||||
frames.push_back( t );
|
||||
if (!(flags & gxCanvas::CANVAS_TEX_CUBE)) {
|
||||
if (w <= 0 || h <= 0 || first < 0 || cnt <= 0) {
|
||||
w = h = first = 0;
|
||||
if (gxCanvas* t = gx_graphics->loadCanvas(f, flags)) {
|
||||
frames.push_back(t);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int t_flags=flags & (
|
||||
gxCanvas::CANVAS_TEX_RGB|
|
||||
gxCanvas::CANVAS_TEX_ALPHA|
|
||||
gxCanvas::CANVAS_TEX_MASK|
|
||||
gxCanvas::CANVAS_TEX_HICOLOR ) | gxCanvas::CANVAS_NONDISPLAY;
|
||||
int t_flags = flags
|
||||
& (gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA | gxCanvas::CANVAS_TEX_MASK
|
||||
| gxCanvas::CANVAS_TEX_HICOLOR)
|
||||
| gxCanvas::CANVAS_NONDISPLAY;
|
||||
|
||||
gxCanvas *t=gx_graphics->loadCanvas( f,t_flags );
|
||||
if( !t ) return;
|
||||
if( !t->getDepth() ){
|
||||
gx_graphics->freeCanvas( t );
|
||||
gxCanvas* t = gx_graphics->loadCanvas(f, t_flags);
|
||||
if (!t)
|
||||
return;
|
||||
if (!t->getDepth()) {
|
||||
gx_graphics->freeCanvas(t);
|
||||
return;
|
||||
}
|
||||
|
||||
if( flags & gxCanvas::CANVAS_TEX_CUBE ){
|
||||
int w=t->getWidth()/6;
|
||||
if( w*6!=t->getWidth() ) return;
|
||||
int h=t->getHeight();
|
||||
if (flags & gxCanvas::CANVAS_TEX_CUBE) {
|
||||
int w = t->getWidth() / 6;
|
||||
if (w * 6 != t->getWidth())
|
||||
return;
|
||||
int h = t->getHeight();
|
||||
|
||||
gxCanvas *tex=gx_graphics->createCanvas( w,h,flags );
|
||||
if( tex ){
|
||||
frames.push_back( tex );
|
||||
gxCanvas* tex = gx_graphics->createCanvas(w, h, flags);
|
||||
if (tex) {
|
||||
frames.push_back(tex);
|
||||
|
||||
for( int face=0;face<6;++face ){
|
||||
for (int face = 0; face < 6; ++face) {
|
||||
tex->setCubeFace(face);
|
||||
gx_graphics->copy( tex,0,0,tex->getWidth(),tex->getHeight(),t,face*w,0,w,h );
|
||||
gx_graphics->copy(tex, 0, 0, tex->getWidth(), tex->getHeight(), t, face * w, 0, w, h);
|
||||
}
|
||||
tex->setCubeFace(1);
|
||||
}
|
||||
}else{
|
||||
int x_tiles=t->getWidth()/w;
|
||||
int y_tiles=t->getHeight()/h;
|
||||
if( first+cnt>x_tiles*y_tiles ){
|
||||
gx_graphics->freeCanvas( t );
|
||||
} else {
|
||||
int x_tiles = t->getWidth() / w;
|
||||
int y_tiles = t->getHeight() / h;
|
||||
if (first + cnt > x_tiles * y_tiles) {
|
||||
gx_graphics->freeCanvas(t);
|
||||
return;
|
||||
}
|
||||
int x=(first%x_tiles)*w;
|
||||
int y=(first/x_tiles)*h;
|
||||
while( cnt-- ){
|
||||
gxCanvas *p=gx_graphics->createCanvas( w,h,flags );
|
||||
gx_graphics->copy( p,0,0,p->getWidth(),p->getHeight(),t,x,y,w,h );
|
||||
int x = (first % x_tiles) * w;
|
||||
int y = (first / x_tiles) * h;
|
||||
while (cnt--) {
|
||||
gxCanvas* p = gx_graphics->createCanvas(w, h, flags);
|
||||
gx_graphics->copy(p, 0, 0, p->getWidth(), p->getHeight(), t, x, y, w, h);
|
||||
frames.push_back(p);
|
||||
x=x+w;if( x+w>t->getWidth() ){ x=0;y=y+h; }
|
||||
x = x + w;
|
||||
if (x + w > t->getWidth()) {
|
||||
x = 0;
|
||||
y = y + h;
|
||||
}
|
||||
}
|
||||
gx_graphics->freeCanvas( t );
|
||||
}
|
||||
gx_graphics->freeCanvas(t);
|
||||
}
|
||||
|
||||
~CachedTexture(){
|
||||
~CachedTexture()
|
||||
{
|
||||
--active_texs;
|
||||
for( int k=0;k<frames.size();++k ) gx_graphics->freeCanvas( frames[k] );
|
||||
for (int k = 0; k < frames.size(); ++k)
|
||||
gx_graphics->freeCanvas(frames[k]);
|
||||
}
|
||||
};
|
||||
|
||||
CachedTextureFactory::CachedTexture *CachedTextureFactory::findRep( const string &f,int flags,int w,int h,int first,int cnt ){
|
||||
CachedTextureFactory::CachedTexture* CachedTextureFactory::findRep(const string& f, int flags, int w, int h, int first,
|
||||
int cnt)
|
||||
{
|
||||
set<CachedTexture*>::const_iterator it;
|
||||
for( it=rep_set.begin();it!=rep_set.end();++it ){
|
||||
CachedTexture *rep=*it;
|
||||
if( rep->file==f && rep->flags==flags && rep->w==w && rep->h==h && rep->first==first && rep->frames.size()==cnt ){
|
||||
++rep->ref_cnt;return rep;
|
||||
for (it = rep_set.begin(); it != rep_set.end(); ++it) {
|
||||
CachedTexture* rep = *it;
|
||||
if (rep->file == f && rep->flags == flags && rep->w == w && rep->h == h && rep->first == first
|
||||
&& rep->frames.size() == cnt) {
|
||||
++rep->ref_cnt;
|
||||
return rep;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CachedTextureFactory::CachedTextureFactory( int w,int h,int flags,int cnt ):
|
||||
rep(new CachedTexture(w,h,flags,cnt)){
|
||||
}
|
||||
CachedTextureFactory::CachedTextureFactory(int w, int h, int flags, int cnt) : rep(new CachedTexture(w, h, flags, cnt))
|
||||
{}
|
||||
|
||||
CachedTextureFactory::CachedTextureFactory( const string &f_,int flags,int w,int h,int first,int cnt ){
|
||||
string f=f_;
|
||||
if( f.substr(0,2)==".\\" ) f=f.substr(2);
|
||||
if( path.size() ){
|
||||
string t=path+tolower( filenamefile( f ) );
|
||||
if( rep=findRep( t,flags,w,h,first,cnt ) ) return;
|
||||
rep=new CachedTexture( t,flags,w,h,first,cnt );
|
||||
if( rep->frames.size() ){
|
||||
rep_set.insert( rep );
|
||||
CachedTextureFactory::CachedTextureFactory(const string& f_, int flags, int w, int h, int first, int cnt)
|
||||
{
|
||||
string f = f_;
|
||||
if (f.substr(0, 2) == ".\\")
|
||||
f = f.substr(2);
|
||||
if (path.size()) {
|
||||
string t = path + tolower(filenamefile(f));
|
||||
if (rep = findRep(t, flags, w, h, first, cnt))
|
||||
return;
|
||||
rep = new CachedTexture(t, flags, w, h, first, cnt);
|
||||
if (rep->frames.size()) {
|
||||
rep_set.insert(rep);
|
||||
return;
|
||||
}
|
||||
delete rep;
|
||||
}
|
||||
string t=tolower( fullfilename( f ) );
|
||||
if( rep=findRep( t,flags,w,h,first,cnt ) ) return;
|
||||
rep=new CachedTexture( t,flags,w,h,first,cnt );
|
||||
rep_set.insert( rep );
|
||||
string t = tolower(fullfilename(f));
|
||||
if (rep = findRep(t, flags, w, h, first, cnt))
|
||||
return;
|
||||
rep = new CachedTexture(t, flags, w, h, first, cnt);
|
||||
rep_set.insert(rep);
|
||||
}
|
||||
|
||||
CachedTextureFactory::CachedTextureFactory( const CachedTextureFactory &t ):
|
||||
rep(t.rep){
|
||||
CachedTextureFactory::CachedTextureFactory(const CachedTextureFactory& t) : rep(t.rep)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
|
||||
CachedTextureFactory::~CachedTextureFactory(){
|
||||
if( !--rep->ref_cnt ){
|
||||
rep_set.erase( rep );
|
||||
CachedTextureFactory::~CachedTextureFactory()
|
||||
{
|
||||
if (!--rep->ref_cnt) {
|
||||
rep_set.erase(rep);
|
||||
delete rep;
|
||||
}
|
||||
}
|
||||
|
||||
CachedTextureFactory &CachedTextureFactory::operator=( const CachedTextureFactory &t ){
|
||||
CachedTextureFactory& CachedTextureFactory::operator=(const CachedTextureFactory& t)
|
||||
{
|
||||
++t.rep->ref_cnt;
|
||||
if( !--rep->ref_cnt ){
|
||||
rep_set.erase( rep );
|
||||
if (!--rep->ref_cnt) {
|
||||
rep_set.erase(rep);
|
||||
delete rep;
|
||||
}
|
||||
rep=t.rep;
|
||||
rep = t.rep;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string CachedTextureFactory::getName()const{
|
||||
string CachedTextureFactory::getName() const
|
||||
{
|
||||
return rep->file;
|
||||
}
|
||||
|
||||
const vector<gxCanvas*> &CachedTextureFactory::getFrames()const{
|
||||
const vector<gxCanvas*>& CachedTextureFactory::getFrames() const
|
||||
{
|
||||
return rep->frames;
|
||||
}
|
||||
|
||||
void CachedTextureFactory::setPath( const string &t ){
|
||||
path=tolower(t);
|
||||
if( int sz=path.size() ){
|
||||
if( path[sz-1]!='/' && path[sz-1]!='\\' ) path+='\\';
|
||||
void CachedTextureFactory::setPath(const string& t)
|
||||
{
|
||||
path = tolower(t);
|
||||
if (int sz = path.size()) {
|
||||
if (path[sz - 1] != '/' && path[sz - 1] != '\\')
|
||||
path += '\\';
|
||||
}
|
||||
}
|
||||
@@ -2,30 +2,33 @@
|
||||
#ifndef CACHEDTEXTURE_H
|
||||
#define CACHEDTEXTURE_H
|
||||
|
||||
#include "../gxruntime/gxcanvas.hpp"
|
||||
#include "gxcanvas.hpp"
|
||||
|
||||
class CachedTextureFactory{
|
||||
public:
|
||||
CachedTextureFactory( int w,int h,int flags,int cnt );
|
||||
CachedTextureFactory( const string &f,int flags,int w,int h,int first,int cnt );
|
||||
CachedTextureFactory( const CachedTextureFactory &t );
|
||||
class CachedTextureFactory {
|
||||
public:
|
||||
CachedTextureFactory(int w, int h, int flags, int cnt);
|
||||
CachedTextureFactory(const string& f, int flags, int w, int h, int first, int cnt);
|
||||
CachedTextureFactory(const CachedTextureFactory& t);
|
||||
~CachedTextureFactory();
|
||||
|
||||
CachedTextureFactory &operator=( const CachedTextureFactory &t );
|
||||
CachedTextureFactory& operator=(const CachedTextureFactory& t);
|
||||
|
||||
string getName()const;
|
||||
string getName() const;
|
||||
|
||||
const vector<gxCanvas*> &getFrames()const;
|
||||
const vector<gxCanvas*>& getFrames() const;
|
||||
|
||||
bool operator<( const CachedTextureFactory &t )const{ return rep<t.rep; }
|
||||
bool operator<(const CachedTextureFactory& t) const
|
||||
{
|
||||
return rep < t.rep;
|
||||
}
|
||||
|
||||
static void setPath( const string &t );
|
||||
static void setPath(const string& t);
|
||||
|
||||
private:
|
||||
private:
|
||||
struct CachedTexture;
|
||||
CachedTexture *rep;
|
||||
CachedTexture* rep;
|
||||
|
||||
CachedTexture *findRep( const string &f,int flags,int w,int h,int first,int cnt );
|
||||
CachedTexture* findRep(const string& f, int flags, int w, int h, int first, int cnt);
|
||||
|
||||
static set<CachedTexture*> rep_set;
|
||||
};
|
||||
|
||||
+94
-65
@@ -1,103 +1,132 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxScene *gx_scene;
|
||||
extern gxScene* gx_scene;
|
||||
|
||||
Camera::Camera(){
|
||||
setZoom( 1 );
|
||||
setRange( 1,1000 );
|
||||
setViewport( 0,0,0,0 );
|
||||
setClsColor( Vector() );
|
||||
setClsMode( true,true );
|
||||
setProjMode( PROJ_PERSP );
|
||||
setFogRange( 1,1000 );
|
||||
setFogColor( Vector() );
|
||||
setFogMode( gxScene::FOG_NONE );
|
||||
Camera::Camera()
|
||||
{
|
||||
setZoom(1);
|
||||
setRange(1, 1000);
|
||||
setViewport(0, 0, 0, 0);
|
||||
setClsColor(Vector());
|
||||
setClsMode(true, true);
|
||||
setProjMode(PROJ_PERSP);
|
||||
setFogRange(1, 1000);
|
||||
setFogColor(Vector());
|
||||
setFogMode(gxScene::FOG_NONE);
|
||||
}
|
||||
|
||||
void Camera::setZoom( float z ){
|
||||
zoom=z;
|
||||
local_valid=false;
|
||||
void Camera::setZoom(float z)
|
||||
{
|
||||
zoom = z;
|
||||
local_valid = false;
|
||||
}
|
||||
|
||||
void Camera::setRange( float n,float f ){
|
||||
frustum_nr=n;frustum_fr=f;
|
||||
local_valid=false;
|
||||
void Camera::setRange(float n, float f)
|
||||
{
|
||||
frustum_nr = n;
|
||||
frustum_fr = f;
|
||||
local_valid = false;
|
||||
}
|
||||
|
||||
void Camera::setViewport( int x,int y,int w,int h ){
|
||||
vp_x=x;vp_y=y;vp_w=w;vp_h=h;
|
||||
local_valid=false;
|
||||
void Camera::setViewport(int x, int y, int w, int h)
|
||||
{
|
||||
vp_x = x;
|
||||
vp_y = y;
|
||||
vp_w = w;
|
||||
vp_h = h;
|
||||
local_valid = false;
|
||||
}
|
||||
|
||||
void Camera::setClsColor( const Vector &v ){
|
||||
cls_color=v;
|
||||
void Camera::setClsColor(const Vector& v)
|
||||
{
|
||||
cls_color = v;
|
||||
}
|
||||
|
||||
void Camera::setClsMode( bool c,bool z ){
|
||||
cls_argb=c;cls_z=z;
|
||||
void Camera::setClsMode(bool c, bool z)
|
||||
{
|
||||
cls_argb = c;
|
||||
cls_z = z;
|
||||
}
|
||||
|
||||
void Camera::setProjMode( int mode ){
|
||||
proj_mode=mode;
|
||||
void Camera::setProjMode(int mode)
|
||||
{
|
||||
proj_mode = mode;
|
||||
}
|
||||
|
||||
void Camera::setFogColor( const Vector &v ){
|
||||
fog_color=v;
|
||||
void Camera::setFogColor(const Vector& v)
|
||||
{
|
||||
fog_color = v;
|
||||
}
|
||||
|
||||
void Camera::setFogRange( float nr,float fr ){
|
||||
fog_nr=nr;fog_fr=fr;
|
||||
void Camera::setFogRange(float nr, float fr)
|
||||
{
|
||||
fog_nr = nr;
|
||||
fog_fr = fr;
|
||||
}
|
||||
|
||||
void Camera::setFogMode( int mode ){
|
||||
fog_mode=mode;
|
||||
void Camera::setFogMode(int mode)
|
||||
{
|
||||
fog_mode = mode;
|
||||
}
|
||||
|
||||
const Frustum &Camera::getFrustum()const{
|
||||
if( !local_valid ){
|
||||
float ar=(float)vp_h/vp_w;
|
||||
frustum_w=frustum_nr*2/zoom;
|
||||
frustum_h=frustum_nr*2/zoom*ar;
|
||||
new( &local_frustum ) Frustum( frustum_nr,frustum_fr,frustum_w,frustum_h );
|
||||
local_valid=true;
|
||||
const Frustum& Camera::getFrustum() const
|
||||
{
|
||||
if (!local_valid) {
|
||||
float ar = (float)vp_h / vp_w;
|
||||
frustum_w = frustum_nr * 2 / zoom;
|
||||
frustum_h = frustum_nr * 2 / zoom * ar;
|
||||
new (&local_frustum) Frustum(frustum_nr, frustum_fr, frustum_w, frustum_h);
|
||||
local_valid = true;
|
||||
}
|
||||
return local_frustum;
|
||||
}
|
||||
|
||||
float Camera::getFrustumNear()const{
|
||||
float Camera::getFrustumNear() const
|
||||
{
|
||||
return frustum_nr;
|
||||
}
|
||||
|
||||
float Camera::getFrustumFar()const{
|
||||
float Camera::getFrustumFar() const
|
||||
{
|
||||
return frustum_fr;
|
||||
}
|
||||
|
||||
float Camera::getFrustumWidth()const{
|
||||
getFrustum();return frustum_w;
|
||||
}
|
||||
|
||||
float Camera::getFrustumHeight()const{
|
||||
getFrustum();return frustum_h;
|
||||
}
|
||||
|
||||
void Camera::getViewport( int *x,int *y,int *w,int *h )const{
|
||||
*x=vp_x;*y=vp_y;*w=vp_w;*h=vp_h;
|
||||
}
|
||||
|
||||
bool Camera::beginRenderFrame(){
|
||||
if( !proj_mode ) return false;
|
||||
float Camera::getFrustumWidth() const
|
||||
{
|
||||
getFrustum();
|
||||
gx_scene->setViewport( vp_x,vp_y,vp_w,vp_h );
|
||||
gx_scene->clear( &(cls_color.x),1,1,cls_argb,cls_z );
|
||||
if( proj_mode==PROJ_ORTHO ){
|
||||
gx_scene->setOrthoProj( frustum_nr,frustum_fr,frustum_w,frustum_h );
|
||||
}else{
|
||||
gx_scene->setPerspProj( frustum_nr,frustum_fr,frustum_w,frustum_h );
|
||||
return frustum_w;
|
||||
}
|
||||
|
||||
float Camera::getFrustumHeight() const
|
||||
{
|
||||
getFrustum();
|
||||
return frustum_h;
|
||||
}
|
||||
|
||||
void Camera::getViewport(int* x, int* y, int* w, int* h) const
|
||||
{
|
||||
*x = vp_x;
|
||||
*y = vp_y;
|
||||
*w = vp_w;
|
||||
*h = vp_h;
|
||||
}
|
||||
|
||||
bool Camera::beginRenderFrame()
|
||||
{
|
||||
if (!proj_mode)
|
||||
return false;
|
||||
getFrustum();
|
||||
gx_scene->setViewport(vp_x, vp_y, vp_w, vp_h);
|
||||
gx_scene->clear(&(cls_color.x), 1, 1, cls_argb, cls_z);
|
||||
if (proj_mode == PROJ_ORTHO) {
|
||||
gx_scene->setOrthoProj(frustum_nr, frustum_fr, frustum_w, frustum_h);
|
||||
} else {
|
||||
gx_scene->setPerspProj(frustum_nr, frustum_fr, frustum_w, frustum_h);
|
||||
}
|
||||
gx_scene->setFogRange( fog_nr,fog_fr );
|
||||
gx_scene->setFogColor( (float*)&fog_color.x );
|
||||
gx_scene->setFogMode( fog_mode );
|
||||
gx_scene->setFogRange(fog_nr, fog_fr);
|
||||
gx_scene->setFogColor((float*)&fog_color.x);
|
||||
gx_scene->setFogMode(fog_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
+33
-29
@@ -2,53 +2,57 @@
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include "model.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "mirror.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
class Camera : public Object{
|
||||
public:
|
||||
enum{
|
||||
PROJ_NONE=0,PROJ_PERSP=1,PROJ_ORTHO=2
|
||||
};
|
||||
class Camera : public Object {
|
||||
public:
|
||||
enum { PROJ_NONE = 0, PROJ_PERSP = 1, PROJ_ORTHO = 2 };
|
||||
|
||||
Camera();
|
||||
Camera *getCamera(){ return this; }
|
||||
Camera* getCamera()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
//called by user
|
||||
void setZoom( float z );
|
||||
void setRange( float nr,float fr );
|
||||
void setViewport( int x,int y,int w,int h );
|
||||
void setClsColor( const Vector &v );
|
||||
void setClsMode( bool cls_argb,bool cls_z );
|
||||
void setProjMode( int mode );
|
||||
void setFogColor( const Vector &v );
|
||||
void setFogRange( float nr,float fr );
|
||||
void setFogMode( int mode );
|
||||
void setZoom(float z);
|
||||
void setRange(float nr, float fr);
|
||||
void setViewport(int x, int y, int w, int h);
|
||||
void setClsColor(const Vector& v);
|
||||
void setClsMode(bool cls_argb, bool cls_z);
|
||||
void setProjMode(int mode);
|
||||
void setFogColor(const Vector& v);
|
||||
void setFogRange(float nr, float fr);
|
||||
void setFogMode(int mode);
|
||||
|
||||
//called by world
|
||||
bool beginRenderFrame();
|
||||
|
||||
//Camera frustum...
|
||||
float getFrustumNear()const;
|
||||
float getFrustumFar()const;
|
||||
float getFrustumWidth()const;
|
||||
float getFrustumHeight()const;
|
||||
const Frustum &getFrustum()const;
|
||||
void getViewport( int *x,int *y,int *w,int *h )const;
|
||||
int getProjMode()const{ return proj_mode; }
|
||||
float getFrustumNear() const;
|
||||
float getFrustumFar() const;
|
||||
float getFrustumWidth() const;
|
||||
float getFrustumHeight() const;
|
||||
const Frustum& getFrustum() const;
|
||||
void getViewport(int* x, int* y, int* w, int* h) const;
|
||||
int getProjMode() const
|
||||
{
|
||||
return proj_mode;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
float zoom;
|
||||
int vp_x,vp_y,vp_w,vp_h;
|
||||
int vp_x, vp_y, vp_w, vp_h;
|
||||
Vector cls_color;
|
||||
bool cls_argb,cls_z;
|
||||
bool cls_argb, cls_z;
|
||||
int proj_mode;
|
||||
Vector fog_color;
|
||||
float fog_nr,fog_fr;
|
||||
float fog_nr, fog_fr;
|
||||
int fog_mode;
|
||||
float frustum_nr,frustum_fr;
|
||||
mutable float frustum_w,frustum_h;
|
||||
float frustum_nr, frustum_fr;
|
||||
mutable float frustum_w, frustum_h;
|
||||
mutable Frustum local_frustum;
|
||||
mutable bool local_valid;
|
||||
};
|
||||
|
||||
+113
-112
@@ -1,8 +1,8 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "collision.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
const float COLLISION_FLT_EPSILON=.001f;
|
||||
const float COLLISION_FLT_EPSILON = .001f;
|
||||
|
||||
/*
|
||||
//
|
||||
@@ -195,167 +195,168 @@ bool Collision::boxCollide( const Line &line,float radius,const Box &box ){
|
||||
}
|
||||
*/
|
||||
|
||||
bool Collision::update( const Line &line,float t,const Vector &n ){
|
||||
bool Collision::update(const Line& line, float t, const Vector& n)
|
||||
{
|
||||
// if( t<0 || t>time ) return false;
|
||||
|
||||
// if( t<0 || t>time ) return false;
|
||||
if (t > time)
|
||||
return false;
|
||||
Plane p(line * t, n);
|
||||
if (p.n.dot(line.d) >= 0)
|
||||
return false;
|
||||
if (p.distance(line.o) < -COLLISION_FLT_EPSILON)
|
||||
return false;
|
||||
|
||||
if( t>time ) return false;
|
||||
Plane p(line*t,n);
|
||||
if( p.n.dot( line.d )>=0 ) return false;
|
||||
if( p.distance(line.o)<-COLLISION_FLT_EPSILON ) return false;
|
||||
|
||||
time=t;
|
||||
normal=n;
|
||||
time = t;
|
||||
normal = n;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// NEW VERSION
|
||||
//
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxRuntime* gx_runtime;
|
||||
|
||||
bool Collision::sphereCollide( const Line &line,float radius,const Vector &dest,float dest_radius ){
|
||||
bool Collision::sphereCollide(const Line& line, float radius, const Vector& dest, float dest_radius)
|
||||
{
|
||||
radius += dest_radius;
|
||||
Line l(line.o - dest, line.d);
|
||||
|
||||
radius+=dest_radius;
|
||||
Line l( line.o-dest,line.d );
|
||||
float a = l.d.dot(l.d);
|
||||
if (!a)
|
||||
return false;
|
||||
float b = l.o.dot(l.d) * 2;
|
||||
float c = l.o.dot(l.o) - radius * radius;
|
||||
float d = b * b - 4 * a * c;
|
||||
if (d < 0)
|
||||
return false;
|
||||
|
||||
float a=l.d.dot(l.d);
|
||||
if( !a ) return false;
|
||||
float b=l.o.dot(l.d)*2;
|
||||
float c=l.o.dot(l.o)-radius*radius;
|
||||
float d=b*b-4*a*c;
|
||||
if( d<0 ) return false;
|
||||
float t1 = (-b + sqrt(d)) / (2 * a);
|
||||
float t2 = (-b - sqrt(d)) / (2 * a);
|
||||
|
||||
float t1=(-b+sqrt(d))/(2*a);
|
||||
float t2=(-b-sqrt(d))/(2*a);
|
||||
float t = t1 < t2 ? t1 : t2;
|
||||
|
||||
float t=t1<t2 ? t1 : t2;
|
||||
if (t > time)
|
||||
return false;
|
||||
|
||||
if( t>time ) return false;
|
||||
|
||||
return update( line,t,(l*t).normalized() );
|
||||
return update(line, t, (l * t).normalized());
|
||||
}
|
||||
|
||||
//v0,v1 = edge verts
|
||||
//pn = poly normal
|
||||
//en = edge normal
|
||||
static bool edgeTest( const Vector &v0,const Vector &v1,const Vector &pn,const Vector &en,const Line &line,float radius,Collision *curr_coll ){
|
||||
|
||||
Matrix tm=~Matrix( en,(v1-v0).normalized(),pn );
|
||||
Vector sv=tm*(line.o-v0),dv=tm*(line.o+line.d-v0);
|
||||
Line l( sv,dv-sv );
|
||||
static bool edgeTest(const Vector& v0, const Vector& v1, const Vector& pn, const Vector& en, const Line& line,
|
||||
float radius, Collision* curr_coll)
|
||||
{
|
||||
Matrix tm = ~Matrix(en, (v1 - v0).normalized(), pn);
|
||||
Vector sv = tm * (line.o - v0), dv = tm * (line.o + line.d - v0);
|
||||
Line l(sv, dv - sv);
|
||||
//do cylinder test...
|
||||
float a,b,c,d,t1,t2,t;
|
||||
a=(l.d.x*l.d.x+l.d.z*l.d.z);
|
||||
if( !a ) return false; //ray parallel to cylinder
|
||||
b=(l.o.x*l.d.x+l.o.z*l.d.z)*2;
|
||||
c=(l.o.x*l.o.x+l.o.z*l.o.z)-radius*radius;
|
||||
d=b*b-4*a*c;
|
||||
if( d<0 ) return false; //ray misses cylinder
|
||||
t1=(-b+sqrt(d))/(2*a);
|
||||
t2=(-b-sqrt(d))/(2*a);
|
||||
t=t1<t2 ? t1 : t2;
|
||||
if( t>curr_coll->time ) return false; //intersects too far away
|
||||
Vector i=l*t,p;
|
||||
if( i.y>v0.distance(v1) ) return false; //intersection above cylinder
|
||||
if( i.y>=0 ){
|
||||
p.y=i.y;
|
||||
}else{
|
||||
float a, b, c, d, t1, t2, t;
|
||||
a = (l.d.x * l.d.x + l.d.z * l.d.z);
|
||||
if (!a)
|
||||
return false; //ray parallel to cylinder
|
||||
b = (l.o.x * l.d.x + l.o.z * l.d.z) * 2;
|
||||
c = (l.o.x * l.o.x + l.o.z * l.o.z) - radius * radius;
|
||||
d = b * b - 4 * a * c;
|
||||
if (d < 0)
|
||||
return false; //ray misses cylinder
|
||||
t1 = (-b + sqrt(d)) / (2 * a);
|
||||
t2 = (-b - sqrt(d)) / (2 * a);
|
||||
t = t1 < t2 ? t1 : t2;
|
||||
if (t > curr_coll->time)
|
||||
return false; //intersects too far away
|
||||
Vector i = l * t, p;
|
||||
if (i.y > v0.distance(v1))
|
||||
return false; //intersection above cylinder
|
||||
if (i.y >= 0) {
|
||||
p.y = i.y;
|
||||
} else {
|
||||
//below bottom of cylinder...do sphere test...
|
||||
a=l.d.dot(l.d);
|
||||
if( !a ) return false; //ray parallel to sphere
|
||||
b=l.o.dot(l.d)*2;
|
||||
c=l.o.dot(l.o)-radius*radius;
|
||||
d=b*b-4*a*c;
|
||||
if( d<0 ) return false; //ray misses sphere
|
||||
t1=(-b+sqrt(d))/(2*a);
|
||||
t2=(-b-sqrt(d))/(2*a);
|
||||
t=t1<t2 ? t1 : t2;
|
||||
if( t>curr_coll->time ) return false;
|
||||
i=l*t;
|
||||
a = l.d.dot(l.d);
|
||||
if (!a)
|
||||
return false; //ray parallel to sphere
|
||||
b = l.o.dot(l.d) * 2;
|
||||
c = l.o.dot(l.o) - radius * radius;
|
||||
d = b * b - 4 * a * c;
|
||||
if (d < 0)
|
||||
return false; //ray misses sphere
|
||||
t1 = (-b + sqrt(d)) / (2 * a);
|
||||
t2 = (-b - sqrt(d)) / (2 * a);
|
||||
t = t1 < t2 ? t1 : t2;
|
||||
if (t > curr_coll->time)
|
||||
return false;
|
||||
i = l * t;
|
||||
}
|
||||
|
||||
return curr_coll->update( line,t,(~tm*(i-p)).normalized() );
|
||||
return curr_coll->update(line, t, (~tm * (i - p)).normalized());
|
||||
}
|
||||
|
||||
bool Collision::triangleCollide( const Line &line,float radius,const Vector &v0,const Vector &v1,const Vector &v2 ){
|
||||
|
||||
bool Collision::triangleCollide(const Line& line, float radius, const Vector& v0, const Vector& v1, const Vector& v2)
|
||||
{
|
||||
//triangle plane
|
||||
Plane p( v0,v1,v2 );
|
||||
if( p.n.dot( line.d )>=0 ) return false;
|
||||
Plane p(v0, v1, v2);
|
||||
if (p.n.dot(line.d) >= 0)
|
||||
return false;
|
||||
|
||||
//move plane out
|
||||
p.d-=radius;
|
||||
float t=p.t_intersect( line );
|
||||
if( t>time ) return false;
|
||||
p.d -= radius;
|
||||
float t = p.t_intersect(line);
|
||||
if (t > time)
|
||||
return false;
|
||||
|
||||
//edge planes
|
||||
Plane p0( v0+p.n,v1,v0 ),p1( v1+p.n,v2,v1 ),p2( v2+p.n,v0,v2 );
|
||||
Plane p0(v0 + p.n, v1, v0), p1(v1 + p.n, v2, v1), p2(v2 + p.n, v0, v2);
|
||||
|
||||
//intersects triangle?
|
||||
Vector i=line*t;
|
||||
if( p0.distance(i)>=0 && p1.distance(i)>=0 && p2.distance(i)>=0 ){
|
||||
return update( line,t,p.n );
|
||||
Vector i = line * t;
|
||||
if (p0.distance(i) >= 0 && p1.distance(i) >= 0 && p2.distance(i) >= 0) {
|
||||
return update(line, t, p.n);
|
||||
}
|
||||
|
||||
if( radius<=0 ) return false;
|
||||
if (radius <= 0)
|
||||
return false;
|
||||
|
||||
return
|
||||
edgeTest( v0,v1,p.n,p0.n,line,radius,this )|
|
||||
edgeTest( v1,v2,p.n,p1.n,line,radius,this )|
|
||||
edgeTest( v2,v0,p.n,p2.n,line,radius,this );
|
||||
return edgeTest(v0, v1, p.n, p0.n, line, radius, this) | edgeTest(v1, v2, p.n, p1.n, line, radius, this)
|
||||
| edgeTest(v2, v0, p.n, p2.n, line, radius, this);
|
||||
}
|
||||
|
||||
bool Collision::boxCollide( const Line &line,float radius,const Box &box ){
|
||||
bool Collision::boxCollide(const Line& line, float radius, const Box& box)
|
||||
{
|
||||
static int quads[] = {2, 3, 1, 0, 3, 7, 5, 1, 7, 6, 4, 5, 6, 2, 0, 4, 6, 7, 3, 2, 0, 1, 5, 4};
|
||||
|
||||
static int quads[]={
|
||||
2,3,1,0,
|
||||
3,7,5,1,
|
||||
7,6,4,5,
|
||||
6,2,0,4,
|
||||
6,7,3,2,
|
||||
0,1,5,4
|
||||
};
|
||||
bool hit = false;
|
||||
|
||||
bool hit=false;
|
||||
|
||||
for( int n=0;n<24;n+=4 ){
|
||||
Vector
|
||||
v0( box.corner( quads[n] ) ),
|
||||
v1( box.corner( quads[n+1] ) ),
|
||||
v2( box.corner( quads[n+2] ) ),
|
||||
v3( box.corner( quads[n+3] ) );
|
||||
for (int n = 0; n < 24; n += 4) {
|
||||
Vector v0(box.corner(quads[n])), v1(box.corner(quads[n + 1])), v2(box.corner(quads[n + 2])),
|
||||
v3(box.corner(quads[n + 3]));
|
||||
|
||||
//quad plane
|
||||
Plane p( v0,v1,v2 );
|
||||
if( p.n.dot( line.d )>=0 ) continue;
|
||||
Plane p(v0, v1, v2);
|
||||
if (p.n.dot(line.d) >= 0)
|
||||
continue;
|
||||
|
||||
//move plane out
|
||||
p.d-=radius;
|
||||
float t=p.t_intersect( line );
|
||||
if( t>time ) return false;
|
||||
p.d -= radius;
|
||||
float t = p.t_intersect(line);
|
||||
if (t > time)
|
||||
return false;
|
||||
|
||||
//edge planes
|
||||
Plane
|
||||
p0( v0+p.n,v1,v0 ),
|
||||
p1( v1+p.n,v2,v1 ),
|
||||
p2( v2+p.n,v3,v2 ),
|
||||
p3( v3+p.n,v0,v3 );
|
||||
Plane p0(v0 + p.n, v1, v0), p1(v1 + p.n, v2, v1), p2(v2 + p.n, v3, v2), p3(v3 + p.n, v0, v3);
|
||||
|
||||
//intersects triangle?
|
||||
Vector i=line*t;
|
||||
if( p0.distance(i)>=0 && p1.distance(i)>=0 && p2.distance(i)>=0 && p3.distance(i)>=0 ){
|
||||
hit|=update( line,t,p.n );
|
||||
Vector i = line * t;
|
||||
if (p0.distance(i) >= 0 && p1.distance(i) >= 0 && p2.distance(i) >= 0 && p3.distance(i) >= 0) {
|
||||
hit |= update(line, t, p.n);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( radius<=0 ) continue;
|
||||
if (radius <= 0)
|
||||
continue;
|
||||
|
||||
hit|=
|
||||
edgeTest( v0,v1,p.n,p0.n,line,radius,this )|
|
||||
edgeTest( v1,v2,p.n,p1.n,line,radius,this )|
|
||||
edgeTest( v2,v3,p.n,p2.n,line,radius,this )|
|
||||
edgeTest( v3,v0,p.n,p3.n,line,radius,this );
|
||||
hit |= edgeTest(v0, v1, p.n, p0.n, line, radius, this) | edgeTest(v1, v2, p.n, p1.n, line, radius, this)
|
||||
| edgeTest(v2, v3, p.n, p2.n, line, radius, this) | edgeTest(v3, v0, p.n, p3.n, line, radius, this);
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
@@ -6,22 +6,22 @@
|
||||
|
||||
extern const float COLLISION_FLT_EPSILON;
|
||||
|
||||
struct Collision{
|
||||
struct Collision {
|
||||
float time;
|
||||
Vector normal;
|
||||
void *surface;
|
||||
void* surface;
|
||||
unsigned short index;
|
||||
|
||||
Collision():time(1),surface(0),index(~0){}
|
||||
Collision() : time(1), surface(0), index(~0) {}
|
||||
|
||||
bool update( const Line &line,float time,const Vector &normal );
|
||||
bool update(const Line& line, float time, const Vector& normal);
|
||||
|
||||
bool sphereCollide( const Line &src_line,float src_radius,const Vector &dest,float dest_radius );
|
||||
bool sphereCollide( const Line &line,float radius,const Vector &dest,const Vector &radii );
|
||||
bool sphereCollide(const Line& src_line, float src_radius, const Vector& dest, float dest_radius);
|
||||
bool sphereCollide(const Line& line, float radius, const Vector& dest, const Vector& radii);
|
||||
|
||||
bool triangleCollide( const Line &src_line,float src_radius,const Vector &v0,const Vector &v1,const Vector &v2 );
|
||||
bool triangleCollide(const Line& src_line, float src_radius, const Vector& v0, const Vector& v1, const Vector& v2);
|
||||
|
||||
bool boxCollide( const Line &src_line,float src_radius,const Box &box );
|
||||
bool boxCollide(const Line& src_line, float src_radius, const Box& box);
|
||||
};
|
||||
|
||||
#endif
|
||||
+24
-24
@@ -1,42 +1,42 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "emitter.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
Emitter::Emitter(){
|
||||
}
|
||||
Emitter::Emitter() {}
|
||||
|
||||
Emitter::Emitter( const Emitter &t ){
|
||||
}
|
||||
Emitter::Emitter(const Emitter& t) {}
|
||||
|
||||
Emitter::~Emitter(){
|
||||
}
|
||||
Emitter::~Emitter() {}
|
||||
|
||||
void Emitter::beginRender( float tween ){
|
||||
Object::beginRender( tween );
|
||||
void Emitter::beginRender(float tween)
|
||||
{
|
||||
Object::beginRender(tween);
|
||||
|
||||
vel=getRenderTform().v-pos;
|
||||
pos=getRenderTform().v;
|
||||
vel = getRenderTform().v - pos;
|
||||
pos = getRenderTform().v;
|
||||
|
||||
for( int k=0;k<channels.size();++k ){
|
||||
gxChannel *chan=channels[k];
|
||||
if( !chan->isPlaying() ){
|
||||
channels[k]=0;
|
||||
for (int k = 0; k < channels.size(); ++k) {
|
||||
gxChannel* chan = channels[k];
|
||||
if (!chan->isPlaying()) {
|
||||
channels[k] = 0;
|
||||
continue;
|
||||
}
|
||||
chan->set3d( &pos.x,&vel.x );
|
||||
chan->set3d(&pos.x, &vel.x);
|
||||
}
|
||||
}
|
||||
|
||||
gxChannel *Emitter::emitSound( gxSound *sound ){
|
||||
gxChannel* Emitter::emitSound(gxSound* sound)
|
||||
{
|
||||
gxChannel* chan = sound->play3d(&pos.x, &vel.x);
|
||||
|
||||
gxChannel *chan=sound->play3d( &pos.x,&vel.x );
|
||||
|
||||
for( int k=0;k<channels.size();++k ){
|
||||
if( chan=channels[k] ) return chan;
|
||||
if( channels[k] ) continue;
|
||||
channels[k]=chan;
|
||||
for (int k = 0; k < channels.size(); ++k) {
|
||||
if (chan = channels[k])
|
||||
return chan;
|
||||
if (channels[k])
|
||||
continue;
|
||||
channels[k] = chan;
|
||||
return chan;
|
||||
}
|
||||
channels.push_back( chan );
|
||||
channels.push_back(chan);
|
||||
return chan;
|
||||
}
|
||||
@@ -7,24 +7,30 @@
|
||||
class gxSound;
|
||||
class gxChannel;
|
||||
|
||||
class Emitter : public Object{
|
||||
public:
|
||||
class Emitter : public Object {
|
||||
public:
|
||||
Emitter();
|
||||
Emitter( const Emitter &t );
|
||||
Emitter(const Emitter& t);
|
||||
~Emitter();
|
||||
|
||||
//Entity interface
|
||||
Entity *clone(){ return d_new Emitter( *this ); }
|
||||
Emitter *getEmitter(){ return this; }
|
||||
Entity* clone()
|
||||
{
|
||||
return d_new Emitter(*this);
|
||||
}
|
||||
Emitter* getEmitter()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
//Object interface
|
||||
void beginRender( float tween );
|
||||
void beginRender(float tween);
|
||||
|
||||
//Public interface
|
||||
gxChannel *emitSound( gxSound *sound );
|
||||
gxChannel* emitSound(gxSound* sound);
|
||||
|
||||
private:
|
||||
Vector pos,vel;
|
||||
private:
|
||||
Vector pos, vel;
|
||||
|
||||
vector<gxChannel*> channels;
|
||||
};
|
||||
|
||||
+104
-66
@@ -1,79 +1,91 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
//#include "stats.hpp"
|
||||
|
||||
Entity *Entity::_orphans, *Entity::_last_orphan;
|
||||
|
||||
enum {
|
||||
INVALID_LOCALTFORM = 1,
|
||||
INVALID_WORLDTFORM = 2
|
||||
};
|
||||
enum { INVALID_LOCALTFORM = 1, INVALID_WORLDTFORM = 2 };
|
||||
|
||||
void Entity::RemoveParent() {
|
||||
void Entity::RemoveParent()
|
||||
{
|
||||
if (m_parent) {
|
||||
if (m_parent->m_children == this) m_parent->m_children = m_listNext;
|
||||
if (m_parent->m_last_child == this) m_parent->m_last_child = m_listPrev;
|
||||
if (m_parent->m_children == this)
|
||||
m_parent->m_children = m_listNext;
|
||||
if (m_parent->m_last_child == this)
|
||||
m_parent->m_last_child = m_listPrev;
|
||||
} else {
|
||||
if (_orphans == this) _orphans = m_listNext;
|
||||
if (_last_orphan == this) _last_orphan = m_listPrev;
|
||||
if (_orphans == this)
|
||||
_orphans = m_listNext;
|
||||
if (_last_orphan == this)
|
||||
_last_orphan = m_listPrev;
|
||||
}
|
||||
if (m_listNext) m_listNext->m_listPrev = m_listPrev;
|
||||
if (m_listPrev) m_listPrev->m_listNext = m_listNext;
|
||||
if (m_listNext)
|
||||
m_listNext->m_listPrev = m_listPrev;
|
||||
if (m_listPrev)
|
||||
m_listPrev->m_listNext = m_listNext;
|
||||
}
|
||||
|
||||
void Entity::InsertChildToParent() {
|
||||
void Entity::InsertChildToParent()
|
||||
{
|
||||
m_listNext = 0;
|
||||
if (m_parent) {
|
||||
if (m_listPrev = m_parent->m_last_child) m_listPrev->m_listNext = this;
|
||||
else m_parent->m_children = this;
|
||||
if (m_listPrev = m_parent->m_last_child)
|
||||
m_listPrev->m_listNext = this;
|
||||
else
|
||||
m_parent->m_children = this;
|
||||
m_parent->m_last_child = this;
|
||||
} else {
|
||||
if (m_listPrev = _last_orphan) m_listPrev->m_listNext = this;
|
||||
else _orphans = this;
|
||||
if (m_listPrev = _last_orphan)
|
||||
m_listPrev->m_listNext = this;
|
||||
else
|
||||
_orphans = this;
|
||||
_last_orphan = this;
|
||||
}
|
||||
}
|
||||
|
||||
Entity::Entity() :
|
||||
m_listNext(0), m_listPrev(0), m_parent(0), m_children(0), m_last_child(0),
|
||||
m_isVisible(true), m_isEnabled(true),
|
||||
m_localScale(1, 1, 1),
|
||||
invalid(0) {
|
||||
Entity::Entity()
|
||||
: m_listNext(0), m_listPrev(0), m_parent(0), m_children(0), m_last_child(0), m_isVisible(true), m_isEnabled(true),
|
||||
m_localScale(1, 1, 1), invalid(0)
|
||||
{
|
||||
InsertChildToParent();
|
||||
}
|
||||
|
||||
Entity::Entity(const Entity &e) :
|
||||
m_listNext(0), m_listPrev(0), m_parent(0), m_children(0), m_last_child(0),
|
||||
m_name(e.m_name), m_isVisible(e.m_isVisible), m_isEnabled(e.m_isEnabled),
|
||||
m_localPosition(e.m_localPosition),
|
||||
m_localScale(e.m_localScale),
|
||||
m_localRotation(e.m_localRotation),
|
||||
invalid(INVALID_LOCALTFORM | INVALID_WORLDTFORM) {
|
||||
Entity::Entity(const Entity& e)
|
||||
: m_listNext(0), m_listPrev(0), m_parent(0), m_children(0), m_last_child(0), m_name(e.m_name),
|
||||
m_isVisible(e.m_isVisible), m_isEnabled(e.m_isEnabled), m_localPosition(e.m_localPosition),
|
||||
m_localScale(e.m_localScale), m_localRotation(e.m_localRotation), invalid(INVALID_LOCALTFORM | INVALID_WORLDTFORM)
|
||||
{
|
||||
InsertChildToParent();
|
||||
}
|
||||
|
||||
Entity::~Entity() {
|
||||
while (GetChildren()) delete GetChildren();
|
||||
Entity::~Entity()
|
||||
{
|
||||
while (GetChildren())
|
||||
delete GetChildren();
|
||||
RemoveParent();
|
||||
}
|
||||
|
||||
void Entity::InvalidateWorldTransform() {
|
||||
if (invalid & INVALID_WORLDTFORM) return;
|
||||
void Entity::InvalidateWorldTransform()
|
||||
{
|
||||
if (invalid & INVALID_WORLDTFORM)
|
||||
return;
|
||||
invalid |= INVALID_WORLDTFORM;
|
||||
for (Entity *e = m_children; e; e = e->m_listNext) {
|
||||
for (Entity* e = m_children; e; e = e->m_listNext) {
|
||||
e->InvalidateWorldTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::invalidateLocal() {
|
||||
void Entity::invalidateLocal()
|
||||
{
|
||||
invalid |= INVALID_LOCALTFORM;
|
||||
InvalidateWorldTransform();
|
||||
}
|
||||
|
||||
const Transform &Entity::GetLocalTransform()const {
|
||||
if (invalid&INVALID_LOCALTFORM) {
|
||||
const Transform& Entity::GetLocalTransform() const
|
||||
{
|
||||
if (invalid & INVALID_LOCALTFORM) {
|
||||
m_localTransform.m = Matrix(m_localRotation);
|
||||
m_localTransform.m.i *= m_localScale.x;
|
||||
m_localTransform.m.j *= m_localScale.y;
|
||||
@@ -84,16 +96,19 @@ const Transform &Entity::GetLocalTransform()const {
|
||||
return m_localTransform;
|
||||
}
|
||||
|
||||
const Transform &Entity::GetWorldTransform()const {
|
||||
if (invalid&INVALID_WORLDTFORM) {
|
||||
const Transform& Entity::GetWorldTransform() const
|
||||
{
|
||||
if (invalid & INVALID_WORLDTFORM) {
|
||||
m_worldTransform = m_parent ? m_parent->GetWorldTransform() * GetLocalTransform() : GetLocalTransform();
|
||||
invalid &= ~INVALID_WORLDTFORM;
|
||||
}
|
||||
return m_worldTransform;
|
||||
}
|
||||
|
||||
void Entity::SetParent(Entity *p) {
|
||||
if (m_parent == p) return;
|
||||
void Entity::SetParent(Entity* p)
|
||||
{
|
||||
if (m_parent == p)
|
||||
return;
|
||||
|
||||
RemoveParent();
|
||||
|
||||
@@ -104,94 +119,117 @@ void Entity::SetParent(Entity *p) {
|
||||
InvalidateWorldTransform();
|
||||
}
|
||||
|
||||
void Entity::SetName(const string &t) {
|
||||
void Entity::SetName(const string& t)
|
||||
{
|
||||
m_name = t;
|
||||
}
|
||||
|
||||
void Entity::SetVisible(bool visible) {
|
||||
void Entity::SetVisible(bool visible)
|
||||
{
|
||||
m_isVisible = visible;
|
||||
}
|
||||
|
||||
void Entity::SetEnabled(bool enabled) {
|
||||
void Entity::SetEnabled(bool enabled)
|
||||
{
|
||||
m_isEnabled = enabled;
|
||||
}
|
||||
|
||||
void Entity::EnumerateVisible(std::list<Object*> &out) {
|
||||
if (!m_isVisible) return;
|
||||
if (Object *o = getObject()) out.push_back(o);
|
||||
for (Entity *e = m_children; e; e = e->m_listNext) {
|
||||
void Entity::EnumerateVisible(std::list<Object*>& out)
|
||||
{
|
||||
if (!m_isVisible)
|
||||
return;
|
||||
if (Object* o = getObject())
|
||||
out.push_back(o);
|
||||
for (Entity* e = m_children; e; e = e->m_listNext) {
|
||||
e->EnumerateVisible(out);
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::EnumerateEnabled(std::list<Object*> &out) {
|
||||
if (!m_isEnabled) return;
|
||||
if (Object *o = getObject()) out.push_back(o);
|
||||
for (Entity *e = m_children; e; e = e->m_listNext) {
|
||||
void Entity::EnumerateEnabled(std::list<Object*>& out)
|
||||
{
|
||||
if (!m_isEnabled)
|
||||
return;
|
||||
if (Object* o = getObject())
|
||||
out.push_back(o);
|
||||
for (Entity* e = m_children; e; e = e->m_listNext) {
|
||||
e->EnumerateEnabled(out);
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::SetLocalPosition(const Vector &v) {
|
||||
void Entity::SetLocalPosition(const Vector& v)
|
||||
{
|
||||
m_localPosition = v;
|
||||
invalidateLocal();
|
||||
}
|
||||
|
||||
void Entity::SetLocalScale(const Vector &v) {
|
||||
void Entity::SetLocalScale(const Vector& v)
|
||||
{
|
||||
m_localScale = v;
|
||||
invalidateLocal();
|
||||
}
|
||||
|
||||
void Entity::SetLocalRotation(const Quat &q) {
|
||||
void Entity::SetLocalRotation(const Quat& q)
|
||||
{
|
||||
m_localRotation = q.normalized();
|
||||
invalidateLocal();
|
||||
}
|
||||
|
||||
void Entity::SetLocalTransform(const Transform &t) {
|
||||
void Entity::SetLocalTransform(const Transform& t)
|
||||
{
|
||||
m_localPosition = t.v;
|
||||
m_localScale = Vector(t.m.i.length(), t.m.j.length(), t.m.k.length());
|
||||
m_localRotation = matrixQuat(t.m);
|
||||
invalidateLocal();
|
||||
}
|
||||
|
||||
void Entity::SetWorldPosition(const Vector &v) {
|
||||
void Entity::SetWorldPosition(const Vector& v)
|
||||
{
|
||||
SetLocalPosition(m_parent ? -m_parent->GetWorldTransform() * v : v);
|
||||
}
|
||||
|
||||
void Entity::SetWorldScale(const Vector &v) {
|
||||
void Entity::SetWorldScale(const Vector& v)
|
||||
{
|
||||
SetLocalScale(m_parent ? v / m_parent->GetWorldScale() : v);
|
||||
}
|
||||
|
||||
void Entity::SetWorldRotation(const Quat &q) {
|
||||
void Entity::SetWorldRotation(const Quat& q)
|
||||
{
|
||||
SetLocalRotation(m_parent ? -m_parent->GetWorldRotation() * q : q);
|
||||
}
|
||||
|
||||
void Entity::SetWorldTransform(const Transform &t) {
|
||||
void Entity::SetWorldTransform(const Transform& t)
|
||||
{
|
||||
SetLocalTransform(m_parent ? -m_parent->GetWorldTransform() * t : t);
|
||||
}
|
||||
|
||||
const Vector &Entity::GetLocalPosition()const {
|
||||
const Vector& Entity::GetLocalPosition() const
|
||||
{
|
||||
return m_localPosition;
|
||||
}
|
||||
|
||||
const Vector &Entity::GetLocalScale()const {
|
||||
const Vector& Entity::GetLocalScale() const
|
||||
{
|
||||
return m_localScale;
|
||||
}
|
||||
|
||||
const Quat &Entity::GetLocalRotation()const {
|
||||
const Quat& Entity::GetLocalRotation() const
|
||||
{
|
||||
return m_localRotation;
|
||||
}
|
||||
|
||||
const Vector &Entity::GetWorldPosition()const {
|
||||
const Vector& Entity::GetWorldPosition() const
|
||||
{
|
||||
return GetWorldTransform().v;
|
||||
}
|
||||
|
||||
const Vector &Entity::GetWorldScale()const {
|
||||
const Vector& Entity::GetWorldScale() const
|
||||
{
|
||||
m_worldScale = m_parent ? m_parent->GetWorldScale() * m_localScale : m_localScale;
|
||||
return m_worldScale;
|
||||
}
|
||||
|
||||
const Quat &Entity::GetWorldRotation()const {
|
||||
const Quat& Entity::GetWorldRotation() const
|
||||
{
|
||||
m_worldRotation = m_parent ? m_parent->GetWorldRotation() * m_localRotation : m_localRotation;
|
||||
return m_worldRotation;
|
||||
}
|
||||
|
||||
+74
-37
@@ -18,58 +18,95 @@ class MD2Model;
|
||||
|
||||
class Entity {
|
||||
public:
|
||||
|
||||
Entity();
|
||||
Entity(const Entity &e);
|
||||
Entity(const Entity& e);
|
||||
virtual ~Entity();
|
||||
|
||||
virtual Entity *clone() = 0;
|
||||
virtual Entity* clone() = 0;
|
||||
|
||||
//ugly casts!
|
||||
virtual Object *getObject() { return nullptr; }
|
||||
virtual Camera *getCamera() { return nullptr; }
|
||||
virtual Light *getLight() { return nullptr; }
|
||||
virtual Model *getModel() { return nullptr; }
|
||||
virtual Mirror *getMirror() { return nullptr; }
|
||||
virtual Listener *getListener() { return nullptr; }
|
||||
virtual Object* getObject()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual Camera* getCamera()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual Light* getLight()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual Model* getModel()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual Mirror* getMirror()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual Listener* getListener()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SetName(const std::string &t);
|
||||
std::string getName()const { return m_name; }
|
||||
void SetName(const std::string& t);
|
||||
std::string getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void SetParent(Entity *parent);
|
||||
Entity *getParent()const { return m_parent; }
|
||||
void SetParent(Entity* parent);
|
||||
Entity* getParent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
void SetVisible(bool vis);
|
||||
bool IsVisible()const { return m_isVisible; }
|
||||
void EnumerateVisible(std::list<Object*> &out);
|
||||
bool IsVisible() const
|
||||
{
|
||||
return m_isVisible;
|
||||
}
|
||||
void EnumerateVisible(std::list<Object*>& out);
|
||||
|
||||
void SetEnabled(bool ena);
|
||||
bool IsEnabled()const { return m_isEnabled; }
|
||||
void EnumerateEnabled(std::list<Object*> &out);
|
||||
bool IsEnabled() const
|
||||
{
|
||||
return m_isEnabled;
|
||||
}
|
||||
void EnumerateEnabled(std::list<Object*>& out);
|
||||
|
||||
void SetLocalPosition(const Vector &v);
|
||||
const Vector &GetLocalPosition()const;
|
||||
void SetLocalScale(const Vector & v);
|
||||
const Vector &GetLocalScale()const;
|
||||
void SetLocalRotation(const Quat &q);
|
||||
const Quat &GetLocalRotation()const;
|
||||
void SetLocalTransform(const Transform &t);
|
||||
const Transform &GetLocalTransform()const;
|
||||
void SetLocalPosition(const Vector& v);
|
||||
const Vector& GetLocalPosition() const;
|
||||
void SetLocalScale(const Vector& v);
|
||||
const Vector& GetLocalScale() const;
|
||||
void SetLocalRotation(const Quat& q);
|
||||
const Quat& GetLocalRotation() const;
|
||||
void SetLocalTransform(const Transform& t);
|
||||
const Transform& GetLocalTransform() const;
|
||||
|
||||
void SetWorldPosition(const Vector &v);
|
||||
const Vector &GetWorldPosition()const;
|
||||
void SetWorldScale(const Vector &v);
|
||||
const Vector &GetWorldScale()const;
|
||||
void SetWorldRotation(const Quat &q);
|
||||
const Quat &GetWorldRotation()const;
|
||||
void SetWorldTransform(const Transform &t);
|
||||
const Transform &GetWorldTransform()const;
|
||||
void SetWorldPosition(const Vector& v);
|
||||
const Vector& GetWorldPosition() const;
|
||||
void SetWorldScale(const Vector& v);
|
||||
const Vector& GetWorldScale() const;
|
||||
void SetWorldRotation(const Quat& q);
|
||||
const Quat& GetWorldRotation() const;
|
||||
void SetWorldTransform(const Transform& t);
|
||||
const Transform& GetWorldTransform() const;
|
||||
|
||||
Entity* GetChildren()const { return m_children; }
|
||||
Entity* GetSuccessor()const { return m_listNext; }
|
||||
Entity* GetChildren() const
|
||||
{
|
||||
return m_children;
|
||||
}
|
||||
Entity* GetSuccessor() const
|
||||
{
|
||||
return m_listNext;
|
||||
}
|
||||
|
||||
|
||||
static Entity* GetEntityOrphans() { return _orphans; }
|
||||
static Entity* GetEntityOrphans()
|
||||
{
|
||||
return _orphans;
|
||||
}
|
||||
|
||||
private:
|
||||
Entity *m_listNext, *m_listPrev, *m_parent, *m_children, *m_last_child;
|
||||
|
||||
+41
-33
@@ -1,54 +1,62 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
Frustum::Frustum(){
|
||||
}
|
||||
Frustum::Frustum() {}
|
||||
|
||||
Frustum::Frustum( float nr,float fr,float w,float h ){
|
||||
verts[VERT_TLNEAR]=Vector( w*-.5f,h*+.5f,nr );
|
||||
verts[VERT_TRNEAR]=Vector( w*+.5f,h*+.5f,nr );
|
||||
verts[VERT_BRNEAR]=Vector( w*+.5f,h*-.5f,nr );
|
||||
verts[VERT_BLNEAR]=Vector( w*-.5f,h*-.5f,nr );
|
||||
float t=fr/nr;
|
||||
verts[VERT_TLFAR]=verts[VERT_TLNEAR] * t;
|
||||
verts[VERT_TRFAR]=verts[VERT_TRNEAR] * t;
|
||||
verts[VERT_BRFAR]=verts[VERT_BRNEAR] * t;
|
||||
verts[VERT_BLFAR]=verts[VERT_BLNEAR] * t;
|
||||
verts[VERT_EYE]=Vector();
|
||||
Frustum::Frustum(float nr, float fr, float w, float h)
|
||||
{
|
||||
verts[VERT_TLNEAR] = Vector(w * -.5f, h * +.5f, nr);
|
||||
verts[VERT_TRNEAR] = Vector(w * +.5f, h * +.5f, nr);
|
||||
verts[VERT_BRNEAR] = Vector(w * +.5f, h * -.5f, nr);
|
||||
verts[VERT_BLNEAR] = Vector(w * -.5f, h * -.5f, nr);
|
||||
float t = fr / nr;
|
||||
verts[VERT_TLFAR] = verts[VERT_TLNEAR] * t;
|
||||
verts[VERT_TRFAR] = verts[VERT_TRNEAR] * t;
|
||||
verts[VERT_BRFAR] = verts[VERT_BRNEAR] * t;
|
||||
verts[VERT_BLFAR] = verts[VERT_BLNEAR] * t;
|
||||
verts[VERT_EYE] = Vector();
|
||||
makePlanes();
|
||||
}
|
||||
|
||||
Frustum::Frustum( const Frustum &f,const Transform &t ){
|
||||
for( int k=0;k<9;++k ){
|
||||
verts[k]=t*f.verts[k];
|
||||
Frustum::Frustum(const Frustum& f, const Transform& t)
|
||||
{
|
||||
for (int k = 0; k < 9; ++k) {
|
||||
verts[k] = t * f.verts[k];
|
||||
}
|
||||
makePlanes();
|
||||
}
|
||||
|
||||
bool Frustum::cull( const Vector v[],int cnt )const{
|
||||
for( int n=0;n<6;++n ){
|
||||
bool Frustum::cull(const Vector v[], int cnt) const
|
||||
{
|
||||
for (int n = 0; n < 6; ++n) {
|
||||
int k;
|
||||
for( k=0;k<cnt && planes[n].distance( v[k] )<0;++k ){}
|
||||
if( k==cnt ) return false;
|
||||
for (k = 0; k < cnt && planes[n].distance(v[k]) < 0; ++k) {
|
||||
}
|
||||
if (k == cnt)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Frustum::cull( const Box &b )const{
|
||||
bool Frustum::cull(const Box& b) const
|
||||
{
|
||||
Vector v[8];
|
||||
for( int k=0;k<8;++k ) v[k]=b.corner(k);
|
||||
return cull( v,8 );
|
||||
for (int k = 0; k < 8; ++k)
|
||||
v[k] = b.corner(k);
|
||||
return cull(v, 8);
|
||||
}
|
||||
|
||||
void Frustum::makePlanes(){
|
||||
planes[PLANE_TOP]=Plane( verts[VERT_EYE],verts[VERT_TRFAR],verts[VERT_TLFAR] );
|
||||
planes[PLANE_LEFT]=Plane( verts[VERT_EYE],verts[VERT_TLFAR],verts[VERT_BLFAR] );
|
||||
planes[PLANE_BOTTOM]=Plane( verts[VERT_EYE],verts[VERT_BLFAR],verts[VERT_BRFAR] );
|
||||
planes[PLANE_RIGHT]=Plane( verts[VERT_EYE],verts[VERT_BRFAR],verts[VERT_TRFAR] );
|
||||
planes[PLANE_NEAR]=Plane( verts[VERT_TRNEAR],verts[VERT_TLNEAR],verts[VERT_BLNEAR] );
|
||||
planes[PLANE_FAR]=Plane( verts[VERT_TLFAR],verts[VERT_TRFAR],verts[VERT_BRFAR] );
|
||||
if( planes[PLANE_NEAR].distance( verts[VERT_EYE] )>0 ){
|
||||
for( int k=0;k<6;++k ) planes[k]=-planes[k];
|
||||
void Frustum::makePlanes()
|
||||
{
|
||||
planes[PLANE_TOP] = Plane(verts[VERT_EYE], verts[VERT_TRFAR], verts[VERT_TLFAR]);
|
||||
planes[PLANE_LEFT] = Plane(verts[VERT_EYE], verts[VERT_TLFAR], verts[VERT_BLFAR]);
|
||||
planes[PLANE_BOTTOM] = Plane(verts[VERT_EYE], verts[VERT_BLFAR], verts[VERT_BRFAR]);
|
||||
planes[PLANE_RIGHT] = Plane(verts[VERT_EYE], verts[VERT_BRFAR], verts[VERT_TRFAR]);
|
||||
planes[PLANE_NEAR] = Plane(verts[VERT_TRNEAR], verts[VERT_TLNEAR], verts[VERT_BLNEAR]);
|
||||
planes[PLANE_FAR] = Plane(verts[VERT_TLFAR], verts[VERT_TRFAR], verts[VERT_BRFAR]);
|
||||
if (planes[PLANE_NEAR].distance(verts[VERT_EYE]) > 0) {
|
||||
for (int k = 0; k < 6; ++k)
|
||||
planes[k] = -planes[k];
|
||||
}
|
||||
}
|
||||
|
||||
+26
-15
@@ -4,26 +4,37 @@
|
||||
|
||||
#include "geom.hpp"
|
||||
|
||||
class Frustum{
|
||||
public:
|
||||
enum{
|
||||
VERT_TLNEAR=0,VERT_TRNEAR,VERT_BRNEAR,VERT_BLNEAR,
|
||||
VERT_TLFAR,VERT_TRFAR,VERT_BRFAR,VERT_BLFAR,VERT_EYE
|
||||
};
|
||||
enum{
|
||||
PLANE_TOP=0,PLANE_LEFT,PLANE_BOTTOM,PLANE_RIGHT,PLANE_NEAR,PLANE_FAR
|
||||
class Frustum {
|
||||
public:
|
||||
enum {
|
||||
VERT_TLNEAR = 0,
|
||||
VERT_TRNEAR,
|
||||
VERT_BRNEAR,
|
||||
VERT_BLNEAR,
|
||||
VERT_TLFAR,
|
||||
VERT_TRFAR,
|
||||
VERT_BRFAR,
|
||||
VERT_BLFAR,
|
||||
VERT_EYE
|
||||
};
|
||||
enum { PLANE_TOP = 0, PLANE_LEFT, PLANE_BOTTOM, PLANE_RIGHT, PLANE_NEAR, PLANE_FAR };
|
||||
Frustum();
|
||||
Frustum( float nr,float fr,float w,float h );
|
||||
Frustum( const Frustum &f,const Transform &t );
|
||||
Frustum(float nr, float fr, float w, float h);
|
||||
Frustum(const Frustum& f, const Transform& t);
|
||||
|
||||
bool cull( const Box &box )const;
|
||||
bool cull( const Vector vecs[],int cnt )const;
|
||||
bool cull(const Box& box) const;
|
||||
bool cull(const Vector vecs[], int cnt) const;
|
||||
|
||||
const Plane &getPlane( int n )const{ return planes[n]; }
|
||||
const Vector &getVertex( int n )const{ return verts[n]; }
|
||||
const Plane& getPlane(int n) const
|
||||
{
|
||||
return planes[n];
|
||||
}
|
||||
const Vector& getVertex(int n) const
|
||||
{
|
||||
return verts[n];
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
Plane planes[6];
|
||||
Vector verts[9];
|
||||
void makePlanes();
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "geom.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
Matrix Matrix::tmps[64];
|
||||
Transform Transform::tmps[64];
|
||||
|
||||
Quat rotationQuat( float p,float y,float r ){
|
||||
return yawQuat(y)*pitchQuat(p)*rollQuat(r);
|
||||
Quat rotationQuat(float p, float y, float r)
|
||||
{
|
||||
return yawQuat(y) * pitchQuat(p) * rollQuat(r);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+435
-249
@@ -11,167 +11,228 @@ class Matrix;
|
||||
class Transform;
|
||||
|
||||
static float PI = 3.14159265359f; //180 degrees
|
||||
static float TWOPI = PI*2.0f; //360 degrees
|
||||
static float HALFPI = PI*.5f; //90 degrees
|
||||
static float QUARTERPI = PI*.25f; //45 degrees
|
||||
static float TWOPI = PI * 2.0f; //360 degrees
|
||||
static float HALFPI = PI * .5f; //90 degrees
|
||||
static float QUARTERPI = PI * .25f; //45 degrees
|
||||
|
||||
class Vector {
|
||||
public:
|
||||
public:
|
||||
float x, y, z;
|
||||
|
||||
Vector() :x(0), y(0), z(0) {
|
||||
}
|
||||
Vector(float x, float y, float z) :x(x), y(y), z(z) {
|
||||
}
|
||||
operator float*() {
|
||||
Vector() : x(0), y(0), z(0) {}
|
||||
Vector(float x, float y, float z) : x(x), y(y), z(z) {}
|
||||
operator float*()
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
operator const float *() {
|
||||
operator const float*()
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
float &operator[](int n) {
|
||||
float& operator[](int n)
|
||||
{
|
||||
return (&x)[n];
|
||||
}
|
||||
float operator[](int n)const {
|
||||
float operator[](int n) const
|
||||
{
|
||||
return (&x)[n];
|
||||
}
|
||||
Vector operator-()const {
|
||||
Vector operator-() const
|
||||
{
|
||||
return Vector(-x, -y, -z);
|
||||
}
|
||||
Vector operator*(float scale)const {
|
||||
return Vector(x*scale, y*scale, z*scale);
|
||||
Vector operator*(float scale) const
|
||||
{
|
||||
return Vector(x * scale, y * scale, z * scale);
|
||||
}
|
||||
Vector operator*(const Vector &q)const {
|
||||
return Vector(x*q.x, y*q.y, z*q.z);
|
||||
Vector operator*(const Vector& q) const
|
||||
{
|
||||
return Vector(x * q.x, y * q.y, z * q.z);
|
||||
}
|
||||
Vector operator/(float scale)const {
|
||||
Vector operator/(float scale) const
|
||||
{
|
||||
return Vector(x / scale, y / scale, z / scale);
|
||||
}
|
||||
Vector operator/(const Vector &q)const {
|
||||
Vector operator/(const Vector& q) const
|
||||
{
|
||||
return Vector(x / q.x, y / q.y, z / q.z);
|
||||
}
|
||||
Vector operator+(const Vector &q)const {
|
||||
Vector operator+(const Vector& q) const
|
||||
{
|
||||
return Vector(x + q.x, y + q.y, z + q.z);
|
||||
}
|
||||
Vector operator-(const Vector &q)const {
|
||||
Vector operator-(const Vector& q) const
|
||||
{
|
||||
return Vector(x - q.x, y - q.y, z - q.z);
|
||||
}
|
||||
Vector &operator*=(float scale) {
|
||||
x *= scale; y *= scale; z *= scale; return *this;
|
||||
Vector& operator*=(float scale)
|
||||
{
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
z *= scale;
|
||||
return *this;
|
||||
}
|
||||
Vector &operator*=(const Vector &q) {
|
||||
x *= q.x; y *= q.y; z *= q.z; return *this;
|
||||
Vector& operator*=(const Vector& q)
|
||||
{
|
||||
x *= q.x;
|
||||
y *= q.y;
|
||||
z *= q.z;
|
||||
return *this;
|
||||
}
|
||||
Vector &operator/=(float scale) {
|
||||
x /= scale; y /= scale; z /= scale; return *this;
|
||||
Vector& operator/=(float scale)
|
||||
{
|
||||
x /= scale;
|
||||
y /= scale;
|
||||
z /= scale;
|
||||
return *this;
|
||||
}
|
||||
Vector &operator/=(const Vector &q) {
|
||||
x /= q.x; y /= q.y; z /= q.z; return *this;
|
||||
Vector& operator/=(const Vector& q)
|
||||
{
|
||||
x /= q.x;
|
||||
y /= q.y;
|
||||
z /= q.z;
|
||||
return *this;
|
||||
}
|
||||
Vector &operator+=(const Vector &q) {
|
||||
x += q.x; y += q.y; z += q.z; return *this;
|
||||
Vector& operator+=(const Vector& q)
|
||||
{
|
||||
x += q.x;
|
||||
y += q.y;
|
||||
z += q.z;
|
||||
return *this;
|
||||
}
|
||||
Vector &operator-=(const Vector &q) {
|
||||
x -= q.x; y -= q.y; z -= q.z; return *this;
|
||||
Vector& operator-=(const Vector& q)
|
||||
{
|
||||
x -= q.x;
|
||||
y -= q.y;
|
||||
z -= q.z;
|
||||
return *this;
|
||||
}
|
||||
bool operator<(const Vector &q)const {
|
||||
if (fabs(x - q.x) > FLT_EPSILON) return x < q.x ? true : false;
|
||||
if (fabs(y - q.y) > FLT_EPSILON) return y < q.y ? true : false;
|
||||
bool operator<(const Vector& q) const
|
||||
{
|
||||
if (fabs(x - q.x) > FLT_EPSILON)
|
||||
return x < q.x ? true : false;
|
||||
if (fabs(y - q.y) > FLT_EPSILON)
|
||||
return y < q.y ? true : false;
|
||||
return fabs(z - q.z) > FLT_EPSILON && z < q.z;
|
||||
}
|
||||
bool operator==(const Vector &q)const {
|
||||
bool operator==(const Vector& q) const
|
||||
{
|
||||
return fabs(x - q.x) <= FLT_EPSILON && fabs(y - q.y) <= FLT_EPSILON && fabs(z - q.z) <= FLT_EPSILON;
|
||||
}
|
||||
bool operator!=(const Vector &q)const {
|
||||
bool operator!=(const Vector& q) const
|
||||
{
|
||||
return fabs(x - q.x) > FLT_EPSILON || fabs(y - q.y) > FLT_EPSILON || fabs(z - q.z) > FLT_EPSILON;
|
||||
}
|
||||
float dot(const Vector &q)const {
|
||||
return x*q.x + y*q.y + z*q.z;
|
||||
float dot(const Vector& q) const
|
||||
{
|
||||
return x * q.x + y * q.y + z * q.z;
|
||||
}
|
||||
Vector cross(const Vector &q)const {
|
||||
return Vector(y*q.z - z*q.y, z*q.x - x*q.z, x*q.y - y*q.x);
|
||||
Vector cross(const Vector& q) const
|
||||
{
|
||||
return Vector(y * q.z - z * q.y, z * q.x - x * q.z, x * q.y - y * q.x);
|
||||
}
|
||||
float length()const {
|
||||
return sqrtf(x*x + y*y + z*z);
|
||||
float length() const
|
||||
{
|
||||
return sqrtf(x * x + y * y + z * z);
|
||||
}
|
||||
float distance(const Vector &q)const {
|
||||
float dx = x - q.x, dy = y - q.y, dz = z - q.z; return sqrtf(dx*dx + dy*dy + dz*dz);
|
||||
float distance(const Vector& q) const
|
||||
{
|
||||
float dx = x - q.x, dy = y - q.y, dz = z - q.z;
|
||||
return sqrtf(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
Vector normalized()const {
|
||||
float l = length(); return Vector(x / l, y / l, z / l);
|
||||
Vector normalized() const
|
||||
{
|
||||
float l = length();
|
||||
return Vector(x / l, y / l, z / l);
|
||||
}
|
||||
void normalize() {
|
||||
float l = length(); x /= l; y /= l; z /= l;
|
||||
void normalize()
|
||||
{
|
||||
float l = length();
|
||||
x /= l;
|
||||
y /= l;
|
||||
z /= l;
|
||||
}
|
||||
float yaw()const {
|
||||
float yaw() const
|
||||
{
|
||||
return -atan2f(x, z);
|
||||
}
|
||||
float pitch()const {
|
||||
return -atan2f(y, sqrtf(x*x + z*z));
|
||||
float pitch() const
|
||||
{
|
||||
return -atan2f(y, sqrtf(x * x + z * z));
|
||||
}
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
x = y = z = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class Line {
|
||||
public:
|
||||
public:
|
||||
Vector o, d;
|
||||
Line() {
|
||||
}
|
||||
Line(const Vector &o, const Vector &d) :o(o), d(d) {
|
||||
}
|
||||
Line operator+(const Vector &q)const {
|
||||
Line() {}
|
||||
Line(const Vector& o, const Vector& d) : o(o), d(d) {}
|
||||
Line operator+(const Vector& q) const
|
||||
{
|
||||
return Line(o + q, d);
|
||||
}
|
||||
Line operator-(const Vector &q)const {
|
||||
Line operator-(const Vector& q) const
|
||||
{
|
||||
return Line(o - q, d);
|
||||
}
|
||||
Vector operator*(float q)const {
|
||||
return o + d*q;
|
||||
Vector operator*(float q) const
|
||||
{
|
||||
return o + d * q;
|
||||
}
|
||||
Vector nearest(const Vector &q)const {
|
||||
return o + d*(d.dot(q - o) / d.dot(d));
|
||||
Vector nearest(const Vector& q) const
|
||||
{
|
||||
return o + d * (d.dot(q - o) / d.dot(d));
|
||||
}
|
||||
};
|
||||
|
||||
class Plane {
|
||||
public:
|
||||
public:
|
||||
Vector n;
|
||||
float d;
|
||||
|
||||
Plane() :d(0) {
|
||||
}
|
||||
Plane() : d(0) {}
|
||||
//normal/offset form
|
||||
Plane(const Vector &n, float d) :n(n), d(d) {
|
||||
}
|
||||
Plane(const Vector& n, float d) : n(n), d(d) {}
|
||||
//point/normal form
|
||||
Plane(const Vector &p, const Vector &n) :n(n), d(-n.dot(p)) {
|
||||
}
|
||||
Plane(const Vector& p, const Vector& n) : n(n), d(-n.dot(p)) {}
|
||||
//create plane from tri
|
||||
Plane(const Vector &v0, const Vector &v1, const Vector &v2) {
|
||||
n = (v1 - v0).cross(v2 - v0).normalized(); d = -n.dot(v0);
|
||||
Plane(const Vector& v0, const Vector& v1, const Vector& v2)
|
||||
{
|
||||
n = (v1 - v0).cross(v2 - v0).normalized();
|
||||
d = -n.dot(v0);
|
||||
}
|
||||
Plane operator-()const {
|
||||
Plane operator-() const
|
||||
{
|
||||
return Plane(-n, -d);
|
||||
}
|
||||
float t_intersect(const Line &q)const {
|
||||
float t_intersect(const Line& q) const
|
||||
{
|
||||
return -distance(q.o) / n.dot(q.d);
|
||||
}
|
||||
Vector intersect(const Line &q)const {
|
||||
return q*t_intersect(q);
|
||||
Vector intersect(const Line& q) const
|
||||
{
|
||||
return q * t_intersect(q);
|
||||
}
|
||||
Line intersect(const Plane &q)const {
|
||||
Line intersect(const Plane& q) const
|
||||
{
|
||||
Vector lv = n.cross(q.n).normalized();
|
||||
return Line(q.intersect(Line(nearest(n*-d), n.cross(lv))), lv);
|
||||
return Line(q.intersect(Line(nearest(n * -d), n.cross(lv))), lv);
|
||||
}
|
||||
Vector nearest(const Vector &q)const {
|
||||
return q - n*distance(q);
|
||||
Vector nearest(const Vector& q) const
|
||||
{
|
||||
return q - n * distance(q);
|
||||
}
|
||||
void negate() {
|
||||
n = -n; d = -d;
|
||||
void negate()
|
||||
{
|
||||
n = -n;
|
||||
d = -d;
|
||||
}
|
||||
float distance(const Vector &q)const {
|
||||
float distance(const Vector& q) const
|
||||
{
|
||||
return n.dot(q) + d;
|
||||
}
|
||||
};
|
||||
@@ -179,317 +240,436 @@ public:
|
||||
struct Quat {
|
||||
float w;
|
||||
Vector v;
|
||||
Quat() :w(1) {
|
||||
}
|
||||
Quat(float w, const Vector &v) :w(w), v(v) {
|
||||
}
|
||||
Quat operator-()const {
|
||||
Quat() : w(1) {}
|
||||
Quat(float w, const Vector& v) : w(w), v(v) {}
|
||||
Quat operator-() const
|
||||
{
|
||||
return Quat(w, -v);
|
||||
}
|
||||
Quat operator+(const Quat &q)const {
|
||||
Quat operator+(const Quat& q) const
|
||||
{
|
||||
return Quat(w + q.w, v + q.v);
|
||||
}
|
||||
Quat operator-(const Quat &q)const {
|
||||
Quat operator-(const Quat& q) const
|
||||
{
|
||||
return Quat(w - q.w, v - q.v);
|
||||
}
|
||||
Quat operator*(const Quat &q)const {
|
||||
return Quat(w*q.w - v.dot(q.v), q.v.cross(v) + q.v*w + v*q.w);
|
||||
Quat operator*(const Quat& q) const
|
||||
{
|
||||
return Quat(w * q.w - v.dot(q.v), q.v.cross(v) + q.v * w + v * q.w);
|
||||
}
|
||||
Vector operator*(const Vector &q)const {
|
||||
Vector operator*(const Vector& q) const
|
||||
{
|
||||
return (*this * Quat(0, q) * -*this).v;
|
||||
}
|
||||
Quat operator*(float q)const {
|
||||
return Quat(w*q, v*q);
|
||||
Quat operator*(float q) const
|
||||
{
|
||||
return Quat(w * q, v * q);
|
||||
}
|
||||
Quat operator/(float q)const {
|
||||
Quat operator/(float q) const
|
||||
{
|
||||
return Quat(w / q, v / q);
|
||||
}
|
||||
float dot(const Quat &q)const {
|
||||
return v.x*q.v.x + v.y*q.v.y + v.z*q.v.z + w*q.w;
|
||||
float dot(const Quat& q) const
|
||||
{
|
||||
return v.x * q.v.x + v.y * q.v.y + v.z * q.v.z + w * q.w;
|
||||
}
|
||||
float length()const {
|
||||
return sqrtf(w*w + v.x*v.x + v.y*v.y + v.z*v.z);
|
||||
float length() const
|
||||
{
|
||||
return sqrtf(w * w + v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
}
|
||||
void normalize() {
|
||||
void normalize()
|
||||
{
|
||||
*this = *this / length();
|
||||
}
|
||||
Quat normalized()const {
|
||||
Quat normalized() const
|
||||
{
|
||||
return *this / length();
|
||||
}
|
||||
Quat slerpTo(const Quat &q, float a)const {
|
||||
Quat slerpTo(const Quat& q, float a) const
|
||||
{
|
||||
Quat t = q;
|
||||
float d = dot(q), b = 1 - a;
|
||||
if (d < 0) { t.w = -t.w; t.v = -t.v; d = -d; }
|
||||
if (d < 0) {
|
||||
t.w = -t.w;
|
||||
t.v = -t.v;
|
||||
d = -d;
|
||||
}
|
||||
if (d < 1 - FLT_EPSILON) {
|
||||
float om = acosf(d);
|
||||
float si = sinf(om);
|
||||
a = sinf(a*om) / si;
|
||||
b = sinf(b*om) / si;
|
||||
a = sinf(a * om) / si;
|
||||
b = sinf(b * om) / si;
|
||||
}
|
||||
return *this*b + t*a;
|
||||
return *this * b + t * a;
|
||||
}
|
||||
Vector i()const {
|
||||
float xz = v.x*v.z, wy = w*v.y;
|
||||
float xy = v.x*v.y, wz = w*v.z;
|
||||
float yy = v.y*v.y, zz = v.z*v.z;
|
||||
Vector i() const
|
||||
{
|
||||
float xz = v.x * v.z, wy = w * v.y;
|
||||
float xy = v.x * v.y, wz = w * v.z;
|
||||
float yy = v.y * v.y, zz = v.z * v.z;
|
||||
return Vector(1 - 2 * (yy + zz), 2 * (xy - wz), 2 * (xz + wy));
|
||||
}
|
||||
Vector j()const {
|
||||
float yz = v.y*v.z, wx = w*v.x;
|
||||
float xy = v.x*v.y, wz = w*v.z;
|
||||
float xx = v.x*v.x, zz = v.z*v.z;
|
||||
Vector j() const
|
||||
{
|
||||
float yz = v.y * v.z, wx = w * v.x;
|
||||
float xy = v.x * v.y, wz = w * v.z;
|
||||
float xx = v.x * v.x, zz = v.z * v.z;
|
||||
return Vector(2 * (xy + wz), 1 - 2 * (xx + zz), 2 * (yz - wx));
|
||||
}
|
||||
Vector k()const {
|
||||
float xz = v.x*v.z, wy = w*v.y;
|
||||
float yz = v.y*v.z, wx = w*v.x;
|
||||
float xx = v.x*v.x, yy = v.y*v.y;
|
||||
Vector k() const
|
||||
{
|
||||
float xz = v.x * v.z, wy = w * v.y;
|
||||
float yz = v.y * v.z, wx = w * v.x;
|
||||
float xx = v.x * v.x, yy = v.y * v.y;
|
||||
return Vector(2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (xx + yy));
|
||||
}
|
||||
};
|
||||
|
||||
class Matrix {
|
||||
static Matrix tmps[64];
|
||||
static Matrix &alloc_tmp() { static int tmp = 0; return tmps[tmp++ & 63]; }
|
||||
static Matrix& alloc_tmp()
|
||||
{
|
||||
static int tmp = 0;
|
||||
return tmps[tmp++ & 63];
|
||||
}
|
||||
friend class Transform;
|
||||
public:
|
||||
|
||||
public:
|
||||
Vector i, j, k;
|
||||
|
||||
Matrix() :i(Vector(1, 0, 0)), j(Vector(0, 1, 0)), k(Vector(0, 0, 1)) {
|
||||
}
|
||||
Matrix(const Vector &i, const Vector &j, const Vector &k) :i(i), j(j), k(k) {
|
||||
}
|
||||
Matrix(const Quat &q) {
|
||||
float xx = q.v.x*q.v.x, yy = q.v.y*q.v.y, zz = q.v.z*q.v.z;
|
||||
float xy = q.v.x*q.v.y, xz = q.v.x*q.v.z, yz = q.v.y*q.v.z;
|
||||
float wx = q.w*q.v.x, wy = q.w*q.v.y, wz = q.w*q.v.z;
|
||||
Matrix() : i(Vector(1, 0, 0)), j(Vector(0, 1, 0)), k(Vector(0, 0, 1)) {}
|
||||
Matrix(const Vector& i, const Vector& j, const Vector& k) : i(i), j(j), k(k) {}
|
||||
Matrix(const Quat& q)
|
||||
{
|
||||
float xx = q.v.x * q.v.x, yy = q.v.y * q.v.y, zz = q.v.z * q.v.z;
|
||||
float xy = q.v.x * q.v.y, xz = q.v.x * q.v.z, yz = q.v.y * q.v.z;
|
||||
float wx = q.w * q.v.x, wy = q.w * q.v.y, wz = q.w * q.v.z;
|
||||
i = Vector(1 - 2 * (yy + zz), 2 * (xy - wz), 2 * (xz + wy)),
|
||||
j = Vector(2 * (xy + wz), 1 - 2 * (xx + zz), 2 * (yz - wx)),
|
||||
k = Vector(2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (xx + yy));
|
||||
}
|
||||
Matrix(float angle, const Vector &axis) {
|
||||
const Vector &u = axis;
|
||||
Matrix(float angle, const Vector& axis)
|
||||
{
|
||||
const Vector& u = axis;
|
||||
float c = cosf(angle), s = sinf(angle);
|
||||
float x2 = axis.x*axis.x, y2 = axis.y*axis.y, z2 = axis.z*axis.z;
|
||||
i = Vector(x2 + c*(1 - x2), u.x*u.y*(1 - c) - u.z*s, u.z*u.x*(1 - c) + u.y*s);
|
||||
j = Vector(u.x*u.y*(1 - c) + u.z*s, y2 + c*(1 - y2), u.y*u.z*(1 - c) - u.x*s);
|
||||
k = Vector(u.z*u.x*(1 - c) - u.y*s, u.y*u.z*(1 - c) + u.x*s, z2 + c*(1 - z2));
|
||||
float x2 = axis.x * axis.x, y2 = axis.y * axis.y, z2 = axis.z * axis.z;
|
||||
i = Vector(x2 + c * (1 - x2), u.x * u.y * (1 - c) - u.z * s, u.z * u.x * (1 - c) + u.y * s);
|
||||
j = Vector(u.x * u.y * (1 - c) + u.z * s, y2 + c * (1 - y2), u.y * u.z * (1 - c) - u.x * s);
|
||||
k = Vector(u.z * u.x * (1 - c) - u.y * s, u.y * u.z * (1 - c) + u.x * s, z2 + c * (1 - z2));
|
||||
}
|
||||
Vector &operator[](int n) {
|
||||
Vector& operator[](int n)
|
||||
{
|
||||
return (&i)[n];
|
||||
}
|
||||
const Vector &operator[](int n)const {
|
||||
const Vector& operator[](int n) const
|
||||
{
|
||||
return (&i)[n];
|
||||
}
|
||||
Matrix &operator~()const {
|
||||
Matrix &m = alloc_tmp();
|
||||
m.i.x = i.x; m.i.y = j.x; m.i.z = k.x;
|
||||
m.j.x = i.y; m.j.y = j.y; m.j.z = k.y;
|
||||
m.k.x = i.z; m.k.y = j.z; m.k.z = k.z;
|
||||
Matrix& operator~() const
|
||||
{
|
||||
Matrix& m = alloc_tmp();
|
||||
m.i.x = i.x;
|
||||
m.i.y = j.x;
|
||||
m.i.z = k.x;
|
||||
m.j.x = i.y;
|
||||
m.j.y = j.y;
|
||||
m.j.z = k.y;
|
||||
m.k.x = i.z;
|
||||
m.k.y = j.z;
|
||||
m.k.z = k.z;
|
||||
return m;
|
||||
}
|
||||
float determinant()const {
|
||||
return i.x*(j.y*k.z - j.z*k.y) - i.y*(j.x*k.z - j.z*k.x) + i.z*(j.x*k.y - j.y*k.x);
|
||||
float determinant() const
|
||||
{
|
||||
return i.x * (j.y * k.z - j.z * k.y) - i.y * (j.x * k.z - j.z * k.x) + i.z * (j.x * k.y - j.y * k.x);
|
||||
}
|
||||
Matrix &operator-()const {
|
||||
Matrix &m = alloc_tmp();
|
||||
Matrix& operator-() const
|
||||
{
|
||||
Matrix& m = alloc_tmp();
|
||||
float t = 1.0f / determinant();
|
||||
m.i.x = t*(j.y*k.z - j.z*k.y); m.i.y = -t*(i.y*k.z - i.z*k.y); m.i.z = t*(i.y*j.z - i.z*j.y);
|
||||
m.j.x = -t*(j.x*k.z - j.z*k.x); m.j.y = t*(i.x*k.z - i.z*k.x); m.j.z = -t*(i.x*j.z - i.z*j.x);
|
||||
m.k.x = t*(j.x*k.y - j.y*k.x); m.k.y = -t*(i.x*k.y - i.y*k.x); m.k.z = t*(i.x*j.y - i.y*j.x);
|
||||
m.i.x = t * (j.y * k.z - j.z * k.y);
|
||||
m.i.y = -t * (i.y * k.z - i.z * k.y);
|
||||
m.i.z = t * (i.y * j.z - i.z * j.y);
|
||||
m.j.x = -t * (j.x * k.z - j.z * k.x);
|
||||
m.j.y = t * (i.x * k.z - i.z * k.x);
|
||||
m.j.z = -t * (i.x * j.z - i.z * j.x);
|
||||
m.k.x = t * (j.x * k.y - j.y * k.x);
|
||||
m.k.y = -t * (i.x * k.y - i.y * k.x);
|
||||
m.k.z = t * (i.x * j.y - i.y * j.x);
|
||||
return m;
|
||||
}
|
||||
Matrix &cofactor()const {
|
||||
Matrix &m = alloc_tmp();
|
||||
m.i.x = (j.y*k.z - j.z*k.y); m.i.y = -(j.x*k.z - j.z*k.x); m.i.z = (j.x*k.y - j.y*k.x);
|
||||
m.j.x = -(i.y*k.z - i.z*k.y); m.j.y = (i.x*k.z - i.z*k.x); m.j.z = -(i.x*k.y - i.y*k.x);
|
||||
m.k.x = (i.y*j.z - i.z*j.y); m.k.y = -(i.x*j.z - i.z*j.x); m.k.z = (i.x*j.y - i.y*j.x);
|
||||
Matrix& cofactor() const
|
||||
{
|
||||
Matrix& m = alloc_tmp();
|
||||
m.i.x = (j.y * k.z - j.z * k.y);
|
||||
m.i.y = -(j.x * k.z - j.z * k.x);
|
||||
m.i.z = (j.x * k.y - j.y * k.x);
|
||||
m.j.x = -(i.y * k.z - i.z * k.y);
|
||||
m.j.y = (i.x * k.z - i.z * k.x);
|
||||
m.j.z = -(i.x * k.y - i.y * k.x);
|
||||
m.k.x = (i.y * j.z - i.z * j.y);
|
||||
m.k.y = -(i.x * j.z - i.z * j.x);
|
||||
m.k.z = (i.x * j.y - i.y * j.x);
|
||||
return m;
|
||||
}
|
||||
bool operator==(const Matrix &q)const {
|
||||
bool operator==(const Matrix& q) const
|
||||
{
|
||||
return i == q.i && j == q.j && k == q.k;
|
||||
}
|
||||
bool operator!=(const Matrix &q)const {
|
||||
bool operator!=(const Matrix& q) const
|
||||
{
|
||||
return i != q.i || j != q.j || k != q.k;
|
||||
}
|
||||
Vector operator*(const Vector &q)const {
|
||||
return Vector(i.x*q.x + j.x*q.y + k.x*q.z, i.y*q.x + j.y*q.y + k.y*q.z, i.z*q.x + j.z*q.y + k.z*q.z);
|
||||
Vector operator*(const Vector& q) const
|
||||
{
|
||||
return Vector(i.x * q.x + j.x * q.y + k.x * q.z, i.y * q.x + j.y * q.y + k.y * q.z,
|
||||
i.z * q.x + j.z * q.y + k.z * q.z);
|
||||
}
|
||||
Matrix &operator*(const Matrix &q)const {
|
||||
Matrix &m = alloc_tmp();
|
||||
m.i.x = i.x*q.i.x + j.x*q.i.y + k.x*q.i.z; m.i.y = i.y*q.i.x + j.y*q.i.y + k.y*q.i.z; m.i.z = i.z*q.i.x + j.z*q.i.y + k.z*q.i.z;
|
||||
m.j.x = i.x*q.j.x + j.x*q.j.y + k.x*q.j.z; m.j.y = i.y*q.j.x + j.y*q.j.y + k.y*q.j.z; m.j.z = i.z*q.j.x + j.z*q.j.y + k.z*q.j.z;
|
||||
m.k.x = i.x*q.k.x + j.x*q.k.y + k.x*q.k.z; m.k.y = i.y*q.k.x + j.y*q.k.y + k.y*q.k.z; m.k.z = i.z*q.k.x + j.z*q.k.y + k.z*q.k.z;
|
||||
Matrix& operator*(const Matrix& q) const
|
||||
{
|
||||
Matrix& m = alloc_tmp();
|
||||
m.i.x = i.x * q.i.x + j.x * q.i.y + k.x * q.i.z;
|
||||
m.i.y = i.y * q.i.x + j.y * q.i.y + k.y * q.i.z;
|
||||
m.i.z = i.z * q.i.x + j.z * q.i.y + k.z * q.i.z;
|
||||
m.j.x = i.x * q.j.x + j.x * q.j.y + k.x * q.j.z;
|
||||
m.j.y = i.y * q.j.x + j.y * q.j.y + k.y * q.j.z;
|
||||
m.j.z = i.z * q.j.x + j.z * q.j.y + k.z * q.j.z;
|
||||
m.k.x = i.x * q.k.x + j.x * q.k.y + k.x * q.k.z;
|
||||
m.k.y = i.y * q.k.x + j.y * q.k.y + k.y * q.k.z;
|
||||
m.k.z = i.z * q.k.x + j.z * q.k.y + k.z * q.k.z;
|
||||
return m;
|
||||
}
|
||||
void orthogonalize() {
|
||||
void orthogonalize()
|
||||
{
|
||||
k.normalize();
|
||||
i = j.cross(k).normalized();
|
||||
j = k.cross(i);
|
||||
}
|
||||
Matrix &orthogonalized()const {
|
||||
Matrix &m = alloc_tmp();
|
||||
m = *this; m.orthogonalize();
|
||||
Matrix& orthogonalized() const
|
||||
{
|
||||
Matrix& m = alloc_tmp();
|
||||
m = *this;
|
||||
m.orthogonalize();
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
class Box {
|
||||
public:
|
||||
public:
|
||||
Vector a, b;
|
||||
Box() :a(Vector(INFINITY, INFINITY, INFINITY)), b(Vector(-INFINITY, -INFINITY, -INFINITY)) {
|
||||
}
|
||||
Box(const Vector &q) :a(q), b(q) {
|
||||
}
|
||||
Box(const Vector &a, const Vector &b) :a(a), b(b) {
|
||||
}
|
||||
Box(const Line &l) :a(l.o), b(l.o) {
|
||||
Box() : a(Vector(INFINITY, INFINITY, INFINITY)), b(Vector(-INFINITY, -INFINITY, -INFINITY)) {}
|
||||
Box(const Vector& q) : a(q), b(q) {}
|
||||
Box(const Vector& a, const Vector& b) : a(a), b(b) {}
|
||||
Box(const Line& l) : a(l.o), b(l.o)
|
||||
{
|
||||
update(l.o + l.d);
|
||||
}
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
a.x = a.y = a.z = INFINITY;
|
||||
b.x = b.y = b.z = -INFINITY;
|
||||
}
|
||||
bool empty()const {
|
||||
bool empty() const
|
||||
{
|
||||
return b.x < a.x || b.y < a.y || b.z < a.z;
|
||||
}
|
||||
Vector centre()const {
|
||||
return Vector((a.x + b.x)*.5f, (a.y + b.y)*.5f, (a.z + b.z)*.5f);
|
||||
Vector centre() const
|
||||
{
|
||||
return Vector((a.x + b.x) * .5f, (a.y + b.y) * .5f, (a.z + b.z) * .5f);
|
||||
}
|
||||
Vector corner(int n)const {
|
||||
Vector corner(int n) const
|
||||
{
|
||||
return Vector(((n & 1) ? b : a).x, ((n & 2) ? b : a).y, ((n & 4) ? b : a).z);
|
||||
}
|
||||
void update(const Vector &q) {
|
||||
if (q.x < a.x) a.x = q.x; if (q.y < a.y) a.y = q.y; if (q.z < a.z) a.z = q.z;
|
||||
if (q.x > b.x) b.x = q.x; if (q.y > b.y) b.y = q.y; if (q.z > b.z) b.z = q.z;
|
||||
void update(const Vector& q)
|
||||
{
|
||||
if (q.x < a.x)
|
||||
a.x = q.x;
|
||||
if (q.y < a.y)
|
||||
a.y = q.y;
|
||||
if (q.z < a.z)
|
||||
a.z = q.z;
|
||||
if (q.x > b.x)
|
||||
b.x = q.x;
|
||||
if (q.y > b.y)
|
||||
b.y = q.y;
|
||||
if (q.z > b.z)
|
||||
b.z = q.z;
|
||||
}
|
||||
void update(const Box &q) {
|
||||
if (q.a.x < a.x) a.x = q.a.x; if (q.a.y < a.y) a.y = q.a.y; if (q.a.z < a.z) a.z = q.a.z;
|
||||
if (q.b.x > b.x) b.x = q.b.x; if (q.b.y > b.y) b.y = q.b.y; if (q.b.z > b.z) b.z = q.b.z;
|
||||
void update(const Box& q)
|
||||
{
|
||||
if (q.a.x < a.x)
|
||||
a.x = q.a.x;
|
||||
if (q.a.y < a.y)
|
||||
a.y = q.a.y;
|
||||
if (q.a.z < a.z)
|
||||
a.z = q.a.z;
|
||||
if (q.b.x > b.x)
|
||||
b.x = q.b.x;
|
||||
if (q.b.y > b.y)
|
||||
b.y = q.b.y;
|
||||
if (q.b.z > b.z)
|
||||
b.z = q.b.z;
|
||||
}
|
||||
bool overlaps(const Box &q)const {
|
||||
return
|
||||
(b.x < q.b.x ? b.x : q.b.x) >= (a.x > q.a.x ? a.x : q.a.x) &&
|
||||
(b.y < q.b.y ? b.y : q.b.y) >= (a.y > q.a.y ? a.y : q.a.y) &&
|
||||
(b.z < q.b.z ? b.z : q.b.z) >= (a.z > q.a.z ? a.z : q.a.z);
|
||||
bool overlaps(const Box& q) const
|
||||
{
|
||||
return (b.x < q.b.x ? b.x : q.b.x) >= (a.x > q.a.x ? a.x : q.a.x)
|
||||
&& (b.y < q.b.y ? b.y : q.b.y) >= (a.y > q.a.y ? a.y : q.a.y)
|
||||
&& (b.z < q.b.z ? b.z : q.b.z) >= (a.z > q.a.z ? a.z : q.a.z);
|
||||
}
|
||||
void expand(float n) {
|
||||
a.x -= n; a.y -= n; a.z -= n; b.x += n; b.y += n; b.z += n;
|
||||
void expand(float n)
|
||||
{
|
||||
a.x -= n;
|
||||
a.y -= n;
|
||||
a.z -= n;
|
||||
b.x += n;
|
||||
b.y += n;
|
||||
b.z += n;
|
||||
}
|
||||
float width()const {
|
||||
float width() const
|
||||
{
|
||||
return b.x - a.x;
|
||||
}
|
||||
float height()const {
|
||||
float height() const
|
||||
{
|
||||
return b.y - a.y;
|
||||
}
|
||||
float depth()const {
|
||||
float depth() const
|
||||
{
|
||||
return b.z - a.z;
|
||||
}
|
||||
bool contains(const Vector &q) {
|
||||
bool contains(const Vector& q)
|
||||
{
|
||||
return q.x >= a.x && q.x <= b.x && q.y >= a.y && q.y <= b.y && q.z >= a.z && q.z <= b.z;
|
||||
}
|
||||
};
|
||||
|
||||
class Transform {
|
||||
static Transform tmps[64];
|
||||
static Transform &alloc_tmp() { static int tmp = 0; return tmps[tmp++ & 63]; }
|
||||
public:
|
||||
static Transform& alloc_tmp()
|
||||
{
|
||||
static int tmp = 0;
|
||||
return tmps[tmp++ & 63];
|
||||
}
|
||||
|
||||
public:
|
||||
Matrix m;
|
||||
Vector v;
|
||||
|
||||
Transform() {
|
||||
}
|
||||
Transform(const Matrix &m) :m(m) {
|
||||
}
|
||||
Transform(const Vector &v) :v(v) {
|
||||
}
|
||||
Transform(const Matrix &m, const Vector &v) :m(m), v(v) {
|
||||
}
|
||||
Transform &operator-()const {
|
||||
Transform &t = alloc_tmp();
|
||||
t.m = -m; t.v = t.m*-v;
|
||||
Transform() {}
|
||||
Transform(const Matrix& m) : m(m) {}
|
||||
Transform(const Vector& v) : v(v) {}
|
||||
Transform(const Matrix& m, const Vector& v) : m(m), v(v) {}
|
||||
Transform& operator-() const
|
||||
{
|
||||
Transform& t = alloc_tmp();
|
||||
t.m = -m;
|
||||
t.v = t.m * -v;
|
||||
return t;
|
||||
}
|
||||
Transform &operator~()const {
|
||||
Transform &t = alloc_tmp();
|
||||
t.m = ~m; t.v = t.m*-v;
|
||||
Transform& operator~() const
|
||||
{
|
||||
Transform& t = alloc_tmp();
|
||||
t.m = ~m;
|
||||
t.v = t.m * -v;
|
||||
return t;
|
||||
}
|
||||
Vector operator*(const Vector &q)const {
|
||||
return m*q + v;
|
||||
Vector operator*(const Vector& q) const
|
||||
{
|
||||
return m * q + v;
|
||||
}
|
||||
Line operator*(const Line &q)const {
|
||||
Vector t = (*this)*q.o;
|
||||
return Line(t, (*this)*(q.o + q.d) - t);
|
||||
Line operator*(const Line& q) const
|
||||
{
|
||||
Vector t = (*this) * q.o;
|
||||
return Line(t, (*this) * (q.o + q.d) - t);
|
||||
}
|
||||
Box operator*(const Box &q)const {
|
||||
Box t((*this*q.corner(0)));
|
||||
for (int k = 1; k < 8; ++k) t.update(*this*q.corner(k));
|
||||
Box operator*(const Box& q) const
|
||||
{
|
||||
Box t((*this * q.corner(0)));
|
||||
for (int k = 1; k < 8; ++k)
|
||||
t.update(*this * q.corner(k));
|
||||
return t;
|
||||
}
|
||||
Transform &operator*(const Transform &q)const {
|
||||
Transform &t = alloc_tmp();
|
||||
t.m = m*q.m; t.v = m*q.v + v;
|
||||
Transform& operator*(const Transform& q) const
|
||||
{
|
||||
Transform& t = alloc_tmp();
|
||||
t.m = m * q.m;
|
||||
t.v = m * q.v + v;
|
||||
return t;
|
||||
}
|
||||
bool operator==(const Transform &q)const {
|
||||
bool operator==(const Transform& q) const
|
||||
{
|
||||
return m == q.m && v == q.v;
|
||||
}
|
||||
bool operator!=(const Transform &q)const {
|
||||
bool operator!=(const Transform& q) const
|
||||
{
|
||||
return !operator==(q);
|
||||
}
|
||||
};
|
||||
|
||||
inline float transformRadius(float r, const Matrix &t) {
|
||||
inline float transformRadius(float r, const Matrix& t)
|
||||
{
|
||||
static const float sq_3 = sqrtf(1.0f / 3.0f);
|
||||
return (t * Vector(sq_3, sq_3, sq_3)).length()*r;
|
||||
return (t * Vector(sq_3, sq_3, sq_3)).length() * r;
|
||||
}
|
||||
|
||||
inline Matrix pitchMatrix(float q) {
|
||||
inline Matrix pitchMatrix(float q)
|
||||
{
|
||||
return Matrix(Vector(1, 0, 0), Vector(0, cosf(q), sinf(q)), Vector(0, -sinf(q), cosf(q)));
|
||||
}
|
||||
|
||||
inline Matrix yawMatrix(float q) {
|
||||
inline Matrix yawMatrix(float q)
|
||||
{
|
||||
return Matrix(Vector(cosf(q), 0, sinf(q)), Vector(0, 1, 0), Vector(-sinf(q), 0, cosf(q)));
|
||||
}
|
||||
|
||||
inline Matrix rollMatrix(float q) {
|
||||
inline Matrix rollMatrix(float q)
|
||||
{
|
||||
return Matrix(Vector(cosf(q), sinf(q), 0), Vector(-sinf(q), cosf(q), 0), Vector(0, 0, 1));
|
||||
}
|
||||
|
||||
inline float matrixPitch(const Matrix &m) {
|
||||
inline float matrixPitch(const Matrix& m)
|
||||
{
|
||||
return m.k.pitch();
|
||||
// return asinf( -m.k.y );
|
||||
}
|
||||
|
||||
inline float matrixYaw(const Matrix &m) {
|
||||
inline float matrixYaw(const Matrix& m)
|
||||
{
|
||||
return m.k.yaw();
|
||||
//return atan2f( -m.k.x,m.k.z );
|
||||
}
|
||||
|
||||
inline float matrixRoll(const Matrix &m) {
|
||||
inline float matrixRoll(const Matrix& m)
|
||||
{
|
||||
return atan2f(m.i.y, m.j.y);
|
||||
//Matrix t=pitchMatrix( -matrixPitch(m) )*yawMatrix( -matrixYaw(m) )*m;
|
||||
//return atan2f( t.i.y,t.i.x );
|
||||
}
|
||||
|
||||
inline Matrix scaleMatrix(float x, float y, float z) {
|
||||
inline Matrix scaleMatrix(float x, float y, float z)
|
||||
{
|
||||
return Matrix(Vector(x, 0, 0), Vector(0, y, 0), Vector(0, 0, z));
|
||||
}
|
||||
|
||||
inline Matrix scaleMatrix(const Vector &scale) {
|
||||
inline Matrix scaleMatrix(const Vector& scale)
|
||||
{
|
||||
return Matrix(Vector(scale.x, 0, 0), Vector(0, scale.y, 0), Vector(0, 0, scale.z));
|
||||
}
|
||||
|
||||
inline Quat pitchQuat(float p) {
|
||||
inline Quat pitchQuat(float p)
|
||||
{
|
||||
return Quat(cosf(p / -2), Vector(sinf(p / -2), 0, 0));
|
||||
}
|
||||
|
||||
inline Quat yawQuat(float y) {
|
||||
inline Quat yawQuat(float y)
|
||||
{
|
||||
return Quat(cosf(y / 2), Vector(0, sinf(y / 2), 0));
|
||||
}
|
||||
|
||||
inline Quat rollQuat(float r) {
|
||||
inline Quat rollQuat(float r)
|
||||
{
|
||||
return Quat(cosf(r / -2), Vector(0, 0, sinf(r / -2)));
|
||||
}
|
||||
|
||||
@@ -499,29 +679,35 @@ inline Quat rollQuat(float r) {
|
||||
|
||||
Quat rotationQuat(float p, float y, float r);
|
||||
|
||||
inline Matrix rotationMatrix(float p, float y, float r) {
|
||||
return yawMatrix(y)*pitchMatrix(p)*rollMatrix(r);
|
||||
inline Matrix rotationMatrix(float p, float y, float r)
|
||||
{
|
||||
return yawMatrix(y) * pitchMatrix(p) * rollMatrix(r);
|
||||
}
|
||||
|
||||
inline Matrix rotationMatrix(const Vector &rot) {
|
||||
return yawMatrix(rot.y)*pitchMatrix(rot.x)*rollMatrix(rot.z);
|
||||
inline Matrix rotationMatrix(const Vector& rot)
|
||||
{
|
||||
return yawMatrix(rot.y) * pitchMatrix(rot.x) * rollMatrix(rot.z);
|
||||
}
|
||||
|
||||
inline float quatPitch(const Quat &q) {
|
||||
inline float quatPitch(const Quat& q)
|
||||
{
|
||||
return q.k().pitch();
|
||||
}
|
||||
|
||||
inline float quatYaw(const Quat &q) {
|
||||
inline float quatYaw(const Quat& q)
|
||||
{
|
||||
return q.k().yaw();
|
||||
}
|
||||
|
||||
inline float quatRoll(const Quat &q) {
|
||||
inline float quatRoll(const Quat& q)
|
||||
{
|
||||
// Vector i=q.i(),j=q.j();
|
||||
// return atan2f( i.y,j.y );
|
||||
return matrixRoll(q);
|
||||
}
|
||||
|
||||
inline Quat matrixQuat(const Matrix &p) {
|
||||
inline Quat matrixQuat(const Matrix& p)
|
||||
{
|
||||
Matrix m = p;
|
||||
m.orthogonalize();
|
||||
float t = m.i.x + m.j.y + m.k.z, w, x, y, z;
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
#ifndef GROUP_H
|
||||
#define GROUP_H
|
||||
|
||||
class Group{
|
||||
|
||||
class Group {
|
||||
vector<Object*> _objs;
|
||||
|
||||
public:
|
||||
Group( Object *obj );
|
||||
public:
|
||||
Group(Object* obj);
|
||||
~Group();
|
||||
|
||||
const vector<Object*> objs()const{ return _objs; }
|
||||
const vector<Object*> objs() const
|
||||
{
|
||||
return _objs;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
+22
-16
@@ -1,33 +1,39 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "light.hpp"
|
||||
#include "../gxruntime/gxscene.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxScene *gx_scene;
|
||||
extern gxScene* gx_scene;
|
||||
|
||||
Light::Light( int type ){
|
||||
light=gx_scene->createLight( type );
|
||||
Light::Light(int type)
|
||||
{
|
||||
light = gx_scene->createLight(type);
|
||||
}
|
||||
|
||||
Light::~Light(){
|
||||
gx_scene->freeLight( light );
|
||||
Light::~Light()
|
||||
{
|
||||
gx_scene->freeLight(light);
|
||||
}
|
||||
|
||||
void Light::setRange( float r ){
|
||||
light->setRange( r );
|
||||
void Light::setRange(float r)
|
||||
{
|
||||
light->setRange(r);
|
||||
}
|
||||
|
||||
void Light::setColor( const Vector &v ){
|
||||
light->setColor( (float*)&v.x );
|
||||
void Light::setColor(const Vector& v)
|
||||
{
|
||||
light->setColor((float*)&v.x);
|
||||
}
|
||||
|
||||
void Light::setConeAngles( float inner,float outer ){
|
||||
light->setConeAngles( inner,outer );
|
||||
void Light::setConeAngles(float inner, float outer)
|
||||
{
|
||||
light->setConeAngles(inner, outer);
|
||||
}
|
||||
|
||||
bool Light::beginRender( float tween ){
|
||||
Object::beginRender( tween );
|
||||
light->setPosition( &getRenderTform().v.x );
|
||||
light->setDirection( &getRenderTform().m.k.x );
|
||||
bool Light::beginRender(float tween)
|
||||
{
|
||||
Object::beginRender(tween);
|
||||
light->setPosition(&getRenderTform().v.x);
|
||||
light->setDirection(&getRenderTform().m.k.x);
|
||||
return true;
|
||||
}
|
||||
|
||||
+18
-12
@@ -3,29 +3,35 @@
|
||||
#define LIGHT_H
|
||||
|
||||
#include "geom.hpp"
|
||||
#include "gxlight.hpp"
|
||||
#include "object.hpp"
|
||||
#include "../gxruntime/gxlight.hpp"
|
||||
|
||||
class World;
|
||||
|
||||
class Light : public Object{
|
||||
public:
|
||||
Light( int type );
|
||||
class Light : public Object {
|
||||
public:
|
||||
Light(int type);
|
||||
~Light();
|
||||
|
||||
Light *getLight(){ return this; }
|
||||
Light* getLight()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void setRange( float r );
|
||||
void setColor( const Vector &v );
|
||||
void setConeAngles( float inner,float outer );
|
||||
void setRange(float r);
|
||||
void setColor(const Vector& v);
|
||||
void setConeAngles(float inner, float outer);
|
||||
|
||||
bool beginRender( float tween );
|
||||
bool beginRender(float tween);
|
||||
|
||||
gxLight *getGxLight()const{ return light; }
|
||||
gxLight* getGxLight() const
|
||||
{
|
||||
return light;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
friend class World;
|
||||
gxLight *light;
|
||||
gxLight* light;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,34 +1,38 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "listener.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxAudio *gx_audio;
|
||||
extern gxAudio* gx_audio;
|
||||
|
||||
Listener::Listener( float roll,float dopp,float dist ){
|
||||
if( !gx_audio ) return;
|
||||
Listener::Listener(float roll, float dopp, float dist)
|
||||
{
|
||||
if (!gx_audio)
|
||||
return;
|
||||
|
||||
gx_audio->set3dOptions( roll,dopp,dist );
|
||||
gx_audio->set3dOptions(roll, dopp, dist);
|
||||
renderListener();
|
||||
}
|
||||
|
||||
Listener::Listener( const Listener &t ):
|
||||
Object(t){
|
||||
Listener::Listener(const Listener& t) : Object(t) {}
|
||||
|
||||
Listener::~Listener()
|
||||
{
|
||||
if (!gx_audio)
|
||||
return;
|
||||
|
||||
Vector pos, vel, up(0, 1, 1), forward(0, 0, 1);
|
||||
gx_audio->set3dListener(&pos.x, &vel.x, &forward.x, &up.x);
|
||||
}
|
||||
|
||||
Listener::~Listener(){
|
||||
if( !gx_audio ) return;
|
||||
void Listener::renderListener()
|
||||
{
|
||||
if (!gx_audio)
|
||||
return;
|
||||
|
||||
Vector pos,vel,up(0,1,1),forward(0,0,1);
|
||||
gx_audio->set3dListener( &pos.x,&vel.x,&forward.x,&up.x );
|
||||
}
|
||||
|
||||
void Listener::renderListener(){
|
||||
if( !gx_audio ) return;
|
||||
|
||||
const Vector &pos=GetWorldTransform().v;
|
||||
const Vector &vel=getVelocity();
|
||||
const Vector &forward=GetWorldTransform().m.k.normalized();
|
||||
const Vector &up=GetWorldTransform().m.j.normalized();
|
||||
|
||||
gx_audio->set3dListener( &pos.x,&vel.x,&forward.x,&up.x );
|
||||
const Vector& pos = GetWorldTransform().v;
|
||||
const Vector& vel = getVelocity();
|
||||
const Vector& forward = GetWorldTransform().m.k.normalized();
|
||||
const Vector& up = GetWorldTransform().m.j.normalized();
|
||||
|
||||
gx_audio->set3dListener(&pos.x, &vel.x, &forward.x, &up.x);
|
||||
}
|
||||
|
||||
@@ -4,20 +4,26 @@
|
||||
|
||||
#include "object.hpp"
|
||||
|
||||
class Listener : public Object{
|
||||
public:
|
||||
Listener( float roll,float dopp,float dist );
|
||||
Listener( const Listener &t );
|
||||
class Listener : public Object {
|
||||
public:
|
||||
Listener(float roll, float dopp, float dist);
|
||||
Listener(const Listener& t);
|
||||
~Listener();
|
||||
|
||||
//Entity interface
|
||||
Entity *clone(){ return new Listener( *this ); }
|
||||
Listener *getListener(){ return this; }
|
||||
Entity* clone()
|
||||
{
|
||||
return new Listener(*this);
|
||||
}
|
||||
Listener* getListener()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
//Listener interface
|
||||
void renderListener();
|
||||
|
||||
private:
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
+52
-40
@@ -1,77 +1,89 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "meshloader.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
struct Surf{
|
||||
struct Surf {
|
||||
vector<Surface::Triangle> tris;
|
||||
};
|
||||
|
||||
static map<Brush,Surf*> brush_map;
|
||||
static map<Brush, Surf*> brush_map;
|
||||
static vector<Surface::Vertex> verts;
|
||||
|
||||
void MeshLoader::clear(){
|
||||
map<Brush,Surf*>::const_iterator it;
|
||||
for( it=brush_map.begin();it!=brush_map.end();++it ){
|
||||
void MeshLoader::clear()
|
||||
{
|
||||
map<Brush, Surf*>::const_iterator it;
|
||||
for (it = brush_map.begin(); it != brush_map.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
brush_map.clear();
|
||||
verts.clear();
|
||||
}
|
||||
|
||||
int MeshLoader::numVertices(){
|
||||
int MeshLoader::numVertices()
|
||||
{
|
||||
return verts.size();
|
||||
}
|
||||
|
||||
void MeshLoader::addVertex( const Surface::Vertex &v ){
|
||||
verts.push_back( v );
|
||||
void MeshLoader::addVertex(const Surface::Vertex& v)
|
||||
{
|
||||
verts.push_back(v);
|
||||
}
|
||||
|
||||
Surface::Vertex &refVertex( int n ){
|
||||
Surface::Vertex& refVertex(int n)
|
||||
{
|
||||
return verts[n];
|
||||
}
|
||||
|
||||
void MeshLoader::addTriangle( const int verts[3],const Brush &b ){
|
||||
addTriangle( verts[0],verts[1],verts[2],b );
|
||||
void MeshLoader::addTriangle(const int verts[3], const Brush& b)
|
||||
{
|
||||
addTriangle(verts[0], verts[1], verts[2], b);
|
||||
}
|
||||
|
||||
void MeshLoader::addTriangle( int v0,int v1,int v2,const Brush &b ){
|
||||
void MeshLoader::addTriangle(int v0, int v1, int v2, const Brush& b)
|
||||
{
|
||||
//find surface
|
||||
Surf *surf;
|
||||
map<Brush,Surf*>::const_iterator it=brush_map.find( b );
|
||||
if( it!=brush_map.end() ) surf=it->second;
|
||||
else{
|
||||
surf=d_new Surf;
|
||||
brush_map.insert( make_pair( b,surf ) );
|
||||
Surf* surf;
|
||||
map<Brush, Surf*>::const_iterator it = brush_map.find(b);
|
||||
if (it != brush_map.end())
|
||||
surf = it->second;
|
||||
else {
|
||||
surf = d_new Surf;
|
||||
brush_map.insert(make_pair(b, surf));
|
||||
}
|
||||
|
||||
Surface::Triangle tri;
|
||||
tri.verts[0]=v0;tri.verts[1]=v1;tri.verts[2]=v2;
|
||||
surf->tris.push_back( tri );
|
||||
tri.verts[0] = v0;
|
||||
tri.verts[1] = v1;
|
||||
tri.verts[2] = v2;
|
||||
surf->tris.push_back(tri);
|
||||
}
|
||||
|
||||
void MeshLoader::updateMesh( MeshModel *mesh ){
|
||||
map<int,int> vert_map;
|
||||
map<Brush,Surf*>::iterator it;
|
||||
for( it=brush_map.begin();it!=brush_map.end();++it ){
|
||||
void MeshLoader::updateMesh(MeshModel* mesh)
|
||||
{
|
||||
map<int, int> vert_map;
|
||||
map<Brush, Surf*>::iterator it;
|
||||
for (it = brush_map.begin(); it != brush_map.end(); ++it) {
|
||||
vert_map.clear();
|
||||
Brush b=it->first;
|
||||
Surf *t=it->second;
|
||||
Surface *surf=mesh->findSurface( b );
|
||||
if( !surf ) surf=mesh->createSurface( b );
|
||||
for( int k=0;k<t->tris.size();++k ){
|
||||
for( int j=0;j<3;++j ){
|
||||
int n=t->tris[k].verts[j],id;
|
||||
map<int,int>::const_iterator it=vert_map.find( n );
|
||||
if( it!=vert_map.end() ) id=it->second;
|
||||
else{
|
||||
id=surf->numVertices();
|
||||
surf->addVertex( verts[n] );
|
||||
vert_map.insert( make_pair( n,id ) );
|
||||
Brush b = it->first;
|
||||
Surf* t = it->second;
|
||||
Surface* surf = mesh->findSurface(b);
|
||||
if (!surf)
|
||||
surf = mesh->createSurface(b);
|
||||
for (int k = 0; k < t->tris.size(); ++k) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
int n = t->tris[k].verts[j], id;
|
||||
map<int, int>::const_iterator it = vert_map.find(n);
|
||||
if (it != vert_map.end())
|
||||
id = it->second;
|
||||
else {
|
||||
id = surf->numVertices();
|
||||
surf->addVertex(verts[n]);
|
||||
vert_map.insert(make_pair(n, id));
|
||||
}
|
||||
t->tris[k].verts[j]=id;
|
||||
t->tris[k].verts[j] = id;
|
||||
}
|
||||
surf->addTriangle( t->tris[k] );
|
||||
surf->addTriangle(t->tris[k]);
|
||||
}
|
||||
}
|
||||
clear();
|
||||
|
||||
+288
-241
@@ -1,15 +1,15 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "loader_3ds.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "animation.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxRuntime* gx_runtime;
|
||||
|
||||
#ifdef BETA
|
||||
#define _log( X ) gx_runtime->debugLog( (string(X)).c_str() );
|
||||
#define _log(X) gx_runtime->debugLog((string(X)).c_str());
|
||||
#else
|
||||
#define _log( X )
|
||||
#define _log(X)
|
||||
#endif
|
||||
|
||||
class Box;
|
||||
@@ -19,11 +19,11 @@ static int chunk_end;
|
||||
static vector<int> parent_end;
|
||||
static unsigned short anim_len;
|
||||
|
||||
static bool conv,flip_tris;
|
||||
static bool conv, flip_tris;
|
||||
static Transform conv_tform;
|
||||
static bool collapse,animonly;
|
||||
static bool collapse, animonly;
|
||||
|
||||
struct Face3DS{
|
||||
struct Face3DS {
|
||||
int verts[3];
|
||||
Brush brush;
|
||||
};
|
||||
@@ -31,40 +31,47 @@ struct Face3DS{
|
||||
static vector<Face3DS> faces;
|
||||
//static vector<Surface::Vertex> vertices;
|
||||
|
||||
static map<string,Brush> materials_map;
|
||||
static map<string,MeshModel*> name_map;
|
||||
static map<int,MeshModel*> id_map;
|
||||
static map<string, Brush> materials_map;
|
||||
static map<string, MeshModel*> name_map;
|
||||
static map<int, MeshModel*> id_map;
|
||||
|
||||
static int nextChunk(){
|
||||
in.pubseekoff( chunk_end,ios_base::beg );
|
||||
if( chunk_end==parent_end.back() ) return 0;
|
||||
unsigned short id;int len;
|
||||
in.sgetn( (char*)&id,2 );
|
||||
in.sgetn( (char*)&len,4 );
|
||||
chunk_end=(int)in.pubseekoff( 0,ios_base::cur )+len-6;
|
||||
static int nextChunk()
|
||||
{
|
||||
in.pubseekoff(chunk_end, ios_base::beg);
|
||||
if (chunk_end == parent_end.back())
|
||||
return 0;
|
||||
unsigned short id;
|
||||
int len;
|
||||
in.sgetn((char*)&id, 2);
|
||||
in.sgetn((char*)&len, 4);
|
||||
chunk_end = (int)in.pubseekoff(0, ios_base::cur) + len - 6;
|
||||
return id;
|
||||
}
|
||||
|
||||
static void enterChunk(){
|
||||
parent_end.push_back( chunk_end );
|
||||
chunk_end=(int)in.pubseekoff( 0,ios_base::cur );
|
||||
static void enterChunk()
|
||||
{
|
||||
parent_end.push_back(chunk_end);
|
||||
chunk_end = (int)in.pubseekoff(0, ios_base::cur);
|
||||
}
|
||||
|
||||
static void leaveChunk(){
|
||||
chunk_end=parent_end.back();
|
||||
static void leaveChunk()
|
||||
{
|
||||
chunk_end = parent_end.back();
|
||||
parent_end.pop_back();
|
||||
}
|
||||
|
||||
static string parseString(){
|
||||
static string parseString()
|
||||
{
|
||||
string t;
|
||||
while( int c=in.sbumpc() ) t+=char(c);
|
||||
while (int c = in.sbumpc())
|
||||
t += char(c);
|
||||
return t;
|
||||
}
|
||||
|
||||
enum {
|
||||
CHUNK_RGBF = 0x0010,
|
||||
CHUNK_RGBB = 0x0011,
|
||||
// CHUNK_RBGB2 = 0x0012, // ?? NOT HLS.
|
||||
// CHUNK_RBGB2 = 0x0012, // ?? NOT HLS.
|
||||
CHUNK_MAIN = 0x4D4D,
|
||||
CHUNK_SCENE = 0x3D3D,
|
||||
CHUNK_BKGCOLOR = 0x1200,
|
||||
@@ -95,66 +102,72 @@ enum {
|
||||
CHUNK_FRAMES = 0xB008
|
||||
};
|
||||
|
||||
static Vector parseColor(){
|
||||
static Vector parseColor()
|
||||
{
|
||||
Vector v;
|
||||
unsigned char rgb[3];
|
||||
enterChunk();
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_RGBF:
|
||||
in.sgetn( (char*)&v,12 );
|
||||
in.sgetn((char*)&v, 12);
|
||||
break;
|
||||
case CHUNK_RGBB:
|
||||
in.sgetn( (char*)rgb,3 );
|
||||
v=Vector( rgb[0]/255.0f,rgb[1]/255.0f,rgb[2]/255.0f );
|
||||
in.sgetn((char*)rgb, 3);
|
||||
v = Vector(rgb[0] / 255.0f, rgb[1] / 255.0f, rgb[2] / 255.0f);
|
||||
}
|
||||
}
|
||||
leaveChunk();
|
||||
return v;
|
||||
}
|
||||
|
||||
static void parseVertList(){
|
||||
static void parseVertList()
|
||||
{
|
||||
unsigned short cnt;
|
||||
in.sgetn( (char*)&cnt,2 );
|
||||
_log( "VertList cnt="+itoa(cnt) );
|
||||
while( cnt-- ){
|
||||
in.sgetn((char*)&cnt, 2);
|
||||
_log("VertList cnt=" + itoa(cnt));
|
||||
while (cnt--) {
|
||||
Surface::Vertex v;
|
||||
in.sgetn( (char*)&v.coords,12 );
|
||||
if( conv ) v.coords=conv_tform * v.coords;
|
||||
MeshLoader::addVertex( v );
|
||||
in.sgetn((char*)&v.coords, 12);
|
||||
if (conv)
|
||||
v.coords = conv_tform * v.coords;
|
||||
MeshLoader::addVertex(v);
|
||||
}
|
||||
}
|
||||
|
||||
static void parseFaceMat(){
|
||||
string name=parseString();
|
||||
_log( "FaceMat: "+name );
|
||||
Brush mat=materials_map[name];
|
||||
static void parseFaceMat()
|
||||
{
|
||||
string name = parseString();
|
||||
_log("FaceMat: " + name);
|
||||
Brush mat = materials_map[name];
|
||||
unsigned short cnt;
|
||||
in.sgetn( (char*)&cnt,2 );
|
||||
while( cnt-- ){
|
||||
in.sgetn((char*)&cnt, 2);
|
||||
while (cnt--) {
|
||||
unsigned short face;
|
||||
in.sgetn( (char*)&face,2 );
|
||||
faces[face].brush=mat;
|
||||
in.sgetn((char*)&face, 2);
|
||||
faces[face].brush = mat;
|
||||
}
|
||||
}
|
||||
|
||||
static void parseFaceList(){
|
||||
static void parseFaceList()
|
||||
{
|
||||
unsigned short cnt;
|
||||
in.sgetn( (char*)&cnt,2 );
|
||||
_log( "FaceList cnt="+itoa(cnt) );
|
||||
while( cnt-- ){
|
||||
in.sgetn((char*)&cnt, 2);
|
||||
_log("FaceList cnt=" + itoa(cnt));
|
||||
while (cnt--) {
|
||||
unsigned short v[4];
|
||||
in.sgetn( (char*)v,8 );
|
||||
in.sgetn((char*)v, 8);
|
||||
Face3DS face;
|
||||
face.verts[0]=v[0];
|
||||
face.verts[1]=v[1];
|
||||
face.verts[2]=v[2];
|
||||
if( flip_tris ) std::swap( face.verts[1],face.verts[2] );
|
||||
faces.push_back( face );
|
||||
face.verts[0] = v[0];
|
||||
face.verts[1] = v[1];
|
||||
face.verts[2] = v[2];
|
||||
if (flip_tris)
|
||||
std::swap(face.verts[1], face.verts[2]);
|
||||
faces.push_back(face);
|
||||
}
|
||||
enterChunk();
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_FACEMAT:
|
||||
parseFaceMat();
|
||||
break;
|
||||
@@ -163,22 +176,24 @@ static void parseFaceList(){
|
||||
leaveChunk();
|
||||
}
|
||||
|
||||
static void parseMapList(){
|
||||
_log( "MapList" );
|
||||
static void parseMapList()
|
||||
{
|
||||
_log("MapList");
|
||||
unsigned short cnt;
|
||||
in.sgetn( (char*)&cnt,2 );
|
||||
for( int k=0;k<cnt;++k ){
|
||||
in.sgetn((char*)&cnt, 2);
|
||||
for (int k = 0; k < cnt; ++k) {
|
||||
float uv[2];
|
||||
in.sgetn( (char*)uv,8 );
|
||||
Surface::Vertex &v=MeshLoader::refVertex( k );
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=uv[0];
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=1-uv[1];
|
||||
// v->tex_coords[0]=v->tex_coords[1]=Vector( uv[0],1-uv[1],1 );
|
||||
in.sgetn((char*)uv, 8);
|
||||
Surface::Vertex& v = MeshLoader::refVertex(k);
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = uv[0];
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = 1 - uv[1];
|
||||
// v->tex_coords[0]=v->tex_coords[1]=Vector( uv[0],1-uv[1],1 );
|
||||
}
|
||||
}
|
||||
|
||||
static void parseTriMesh( MeshModel *mesh ){
|
||||
_log( "TriMesh" );
|
||||
static void parseTriMesh(MeshModel* mesh)
|
||||
{
|
||||
_log("TriMesh");
|
||||
enterChunk();
|
||||
Transform tform;
|
||||
|
||||
@@ -186,87 +201,93 @@ static void parseTriMesh( MeshModel *mesh ){
|
||||
|
||||
MeshLoader::beginMesh();
|
||||
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_VERTLIST:
|
||||
if( !animonly ) parseVertList();
|
||||
if (!animonly)
|
||||
parseVertList();
|
||||
break;
|
||||
case CHUNK_MAPLIST:
|
||||
if( !animonly ) parseMapList();
|
||||
if (!animonly)
|
||||
parseMapList();
|
||||
break;
|
||||
case CHUNK_FACELIST:
|
||||
if( !animonly ) parseFaceList();
|
||||
if (!animonly)
|
||||
parseFaceList();
|
||||
break;
|
||||
case CHUNK_TRMATRIX:
|
||||
in.sgetn( (char*)&tform,48 );
|
||||
if( conv ) tform=conv_tform * tform * -conv_tform;
|
||||
in.sgetn((char*)&tform, 48);
|
||||
if (conv)
|
||||
tform = conv_tform * tform * -conv_tform;
|
||||
break;
|
||||
}
|
||||
}
|
||||
leaveChunk();
|
||||
|
||||
//should really do something here...
|
||||
// bool neg_x=tform.m.j.cross(tform.m.k).dot(tform.m.i)<0;
|
||||
// bool neg_x=tform.m.j.cross(tform.m.k).dot(tform.m.i)<0;
|
||||
|
||||
int k;
|
||||
|
||||
mesh->SetWorldTransform( tform );
|
||||
mesh->SetWorldTransform(tform);
|
||||
|
||||
if( animonly ){
|
||||
MeshLoader::endMesh( 0 );
|
||||
if (animonly) {
|
||||
MeshLoader::endMesh(0);
|
||||
return;
|
||||
}
|
||||
|
||||
Transform inv_tform=-tform;
|
||||
for( k=0;k<MeshLoader::numVertices();++k ){
|
||||
Surface::Vertex &v=MeshLoader::refVertex( k );
|
||||
v.coords=inv_tform * v.coords;
|
||||
Transform inv_tform = -tform;
|
||||
for (k = 0; k < MeshLoader::numVertices(); ++k) {
|
||||
Surface::Vertex& v = MeshLoader::refVertex(k);
|
||||
v.coords = inv_tform * v.coords;
|
||||
}
|
||||
|
||||
for( k=0;k<faces.size();++k ){
|
||||
const Face3DS &f=faces[k];
|
||||
MeshLoader::addTriangle( f.verts,f.brush );
|
||||
for (k = 0; k < faces.size(); ++k) {
|
||||
const Face3DS& f = faces[k];
|
||||
MeshLoader::addTriangle(f.verts, f.brush);
|
||||
}
|
||||
|
||||
MeshLoader::endMesh( mesh );
|
||||
MeshLoader::endMesh(mesh);
|
||||
mesh->updateNormals();
|
||||
|
||||
faces.clear();
|
||||
}
|
||||
|
||||
static void parseObject( MeshModel *root ){
|
||||
static void parseObject(MeshModel* root)
|
||||
{
|
||||
//skip name
|
||||
string name=parseString();
|
||||
_log( "Object:"+name );
|
||||
MeshModel *mesh=0;
|
||||
string name = parseString();
|
||||
_log("Object:" + name);
|
||||
MeshModel* mesh = 0;
|
||||
|
||||
enterChunk();
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_TRIMESH:
|
||||
mesh=new MeshModel();
|
||||
mesh->SetName( name );
|
||||
mesh->SetParent( root );
|
||||
name_map[name]=mesh;
|
||||
parseTriMesh( mesh );
|
||||
mesh = new MeshModel();
|
||||
mesh->SetName(name);
|
||||
mesh->SetParent(root);
|
||||
name_map[name] = mesh;
|
||||
parseTriMesh(mesh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
leaveChunk();
|
||||
}
|
||||
|
||||
static void parseMaterial(){
|
||||
_log( "Material" );
|
||||
static void parseMaterial()
|
||||
{
|
||||
_log("Material");
|
||||
Brush mat;
|
||||
string name,tex_name;
|
||||
string name, tex_name;
|
||||
enterChunk();
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_MATNAME:
|
||||
name=parseString();
|
||||
name = parseString();
|
||||
break;
|
||||
case CHUNK_DIFFUSE:
|
||||
mat.setColor( parseColor() );
|
||||
mat.setColor(parseColor());
|
||||
break;
|
||||
case CHUNK_AMBIENT:
|
||||
break;
|
||||
@@ -274,10 +295,10 @@ static void parseMaterial(){
|
||||
break;
|
||||
case CHUNK_TEXTURE:
|
||||
enterChunk();
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_MAPFILE:
|
||||
tex_name=parseString();
|
||||
tex_name = parseString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -285,208 +306,233 @@ static void parseMaterial(){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( tex_name.size() ){
|
||||
mat.setTexture( 0,Texture( tex_name,0 ),0 );
|
||||
mat.setColor( Vector( 1,1,1 ) );
|
||||
if (tex_name.size()) {
|
||||
mat.setTexture(0, Texture(tex_name, 0), 0);
|
||||
mat.setColor(Vector(1, 1, 1));
|
||||
}
|
||||
if( name.size() ){
|
||||
materials_map[name]=mat;
|
||||
if (name.size()) {
|
||||
materials_map[name] = mat;
|
||||
}
|
||||
leaveChunk();
|
||||
}
|
||||
|
||||
static void parseScene( MeshModel *root ){
|
||||
_log( "Scene" );
|
||||
static void parseScene(MeshModel* root)
|
||||
{
|
||||
_log("Scene");
|
||||
enterChunk();
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_OBJECT:
|
||||
parseObject( root );
|
||||
parseObject(root);
|
||||
break;
|
||||
case CHUNK_MATERIAL:
|
||||
if( !animonly ) parseMaterial();
|
||||
if (!animonly)
|
||||
parseMaterial();
|
||||
break;
|
||||
}
|
||||
}
|
||||
leaveChunk();
|
||||
}
|
||||
|
||||
static void parseAnimKeys( Animation *anim,int type ){
|
||||
|
||||
int cnt=0;
|
||||
static void parseAnimKeys(Animation* anim, int type)
|
||||
{
|
||||
int cnt = 0;
|
||||
short t_flags;
|
||||
in.sgetn( (char*)&t_flags,2 );
|
||||
in.pubseekoff( 8,ios_base::cur );
|
||||
in.sgetn( (char*)&cnt,2 );
|
||||
in.pubseekoff( 2,ios_base::cur );
|
||||
_log( "ANIM_TRACK: frames="+itoa( cnt ) );
|
||||
Vector pos,axis,scale;
|
||||
in.sgetn((char*)&t_flags, 2);
|
||||
in.pubseekoff(8, ios_base::cur);
|
||||
in.sgetn((char*)&cnt, 2);
|
||||
in.pubseekoff(2, ios_base::cur);
|
||||
_log("ANIM_TRACK: frames=" + itoa(cnt));
|
||||
Vector pos, axis, scale;
|
||||
float angle;
|
||||
Quat quat;
|
||||
for( int k=0;k<cnt;++k ){
|
||||
for (int k = 0; k < cnt; ++k) {
|
||||
int time;
|
||||
short flags;
|
||||
in.sgetn( (char*)&time,4 );
|
||||
in.sgetn( (char*)&flags,2 );
|
||||
float tens=0,cont=0,bias=0,ease_to=0,ease_from=0;
|
||||
if( flags & 1 ) in.sgetn( (char*)&tens,4 );
|
||||
if( flags & 2 ) in.sgetn( (char*)&cont,4 );
|
||||
if( flags & 4 ) in.sgetn( (char*)&bias,4 );
|
||||
if( flags & 8 ) in.sgetn( (char*)&ease_to,4 );
|
||||
if( flags & 16 ) in.sgetn( (char*)&ease_from,4 );
|
||||
switch( type ){
|
||||
in.sgetn((char*)&time, 4);
|
||||
in.sgetn((char*)&flags, 2);
|
||||
float tens = 0, cont = 0, bias = 0, ease_to = 0, ease_from = 0;
|
||||
if (flags & 1)
|
||||
in.sgetn((char*)&tens, 4);
|
||||
if (flags & 2)
|
||||
in.sgetn((char*)&cont, 4);
|
||||
if (flags & 4)
|
||||
in.sgetn((char*)&bias, 4);
|
||||
if (flags & 8)
|
||||
in.sgetn((char*)&ease_to, 4);
|
||||
if (flags & 16)
|
||||
in.sgetn((char*)&ease_from, 4);
|
||||
switch (type) {
|
||||
case 0xb020: //POS_TRACK_TAG
|
||||
in.sgetn( (char*)&pos,12 );
|
||||
if( conv ) pos=conv_tform*pos;
|
||||
// _log( "POS_KEY: time="+itoa(time)+" pos="+ftoa( pos.x )+","+ftoa( pos.y )+","+ftoa( pos.z ) );
|
||||
if( time<=anim_len ) anim->setPositionKey( time,pos );
|
||||
in.sgetn((char*)&pos, 12);
|
||||
if (conv)
|
||||
pos = conv_tform * pos;
|
||||
// _log( "POS_KEY: time="+itoa(time)+" pos="+ftoa( pos.x )+","+ftoa( pos.y )+","+ftoa( pos.z ) );
|
||||
if (time <= anim_len)
|
||||
anim->setPositionKey(time, pos);
|
||||
break;
|
||||
case 0xb021: //ROT_TRACK_TAG
|
||||
in.sgetn( (char*)&angle,4 );
|
||||
in.sgetn( (char*)&axis,12 );
|
||||
// _log( "ROT_KEY: time="+itoa(time)+" angle="+ftoa(angle)+" axis="+ftoa(axis.x)+","+ftoa(axis.y)+","+ftoa(axis.z) );
|
||||
if( axis.length()>FLT_EPSILON ){
|
||||
if( flip_tris ) angle=-angle;
|
||||
if( conv ) axis=conv_tform.m*axis;
|
||||
quat=Quat( cosf( angle/2 ),axis.normalized()*sinf( angle/2 ) )*quat;
|
||||
in.sgetn((char*)&angle, 4);
|
||||
in.sgetn((char*)&axis, 12);
|
||||
// _log( "ROT_KEY: time="+itoa(time)+" angle="+ftoa(angle)+" axis="+ftoa(axis.x)+","+ftoa(axis.y)+","+ftoa(axis.z) );
|
||||
if (axis.length() > FLT_EPSILON) {
|
||||
if (flip_tris)
|
||||
angle = -angle;
|
||||
if (conv)
|
||||
axis = conv_tform.m * axis;
|
||||
quat = Quat(cosf(angle / 2), axis.normalized() * sinf(angle / 2)) * quat;
|
||||
quat.normalize();
|
||||
}
|
||||
if( time<=anim_len ) anim->setRotationKey( time,quat );
|
||||
if (time <= anim_len)
|
||||
anim->setRotationKey(time, quat);
|
||||
break;
|
||||
case 0xb022: //SCL_TRACK_TAG
|
||||
in.sgetn( (char*)&scale,12 );
|
||||
if( conv ) scale=conv_tform.m*scale;
|
||||
// scale.x=fabs(scale.x);scale.y=fabs(scale.y);scale.z=fabs(scale.z);
|
||||
_log( "SCL_KEY: time="+itoa(time)+" scale="+ftoa( scale.x )+","+ftoa( scale.y )+","+ftoa( scale.z ) );
|
||||
if( time<=anim_len ) anim->setScaleKey( time,scale );
|
||||
in.sgetn((char*)&scale, 12);
|
||||
if (conv)
|
||||
scale = conv_tform.m * scale;
|
||||
// scale.x=fabs(scale.x);scale.y=fabs(scale.y);scale.z=fabs(scale.z);
|
||||
_log("SCL_KEY: time=" + itoa(time) + " scale=" + ftoa(scale.x) + "," + ftoa(scale.y) + "," + ftoa(scale.z));
|
||||
if (time <= anim_len)
|
||||
anim->setScaleKey(time, scale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parseMeshInfo( MeshModel *root,float curr_time ){
|
||||
_log( "OBJECT_NODE_TAG" );
|
||||
static void parseMeshInfo(MeshModel* root, float curr_time)
|
||||
{
|
||||
_log("OBJECT_NODE_TAG");
|
||||
enterChunk();
|
||||
string name,inst;
|
||||
string name, inst;
|
||||
Vector pivot;
|
||||
Animation anim;
|
||||
unsigned short id=65535,parent=65535,flags1,flags2;
|
||||
Box box = Box( Vector(),Vector() );
|
||||
unsigned short id = 65535, parent = 65535, flags1, flags2;
|
||||
Box box = Box(Vector(), Vector());
|
||||
Vector box_centre;
|
||||
while( int chunk_id=nextChunk() ){
|
||||
switch( chunk_id ){
|
||||
while (int chunk_id = nextChunk()) {
|
||||
switch (chunk_id) {
|
||||
case 0xb030: //NODE_ID
|
||||
in.sgetn( (char*)&id,2 );
|
||||
_log( "NODE_ID: "+itoa(id) );
|
||||
in.sgetn((char*)&id, 2);
|
||||
_log("NODE_ID: " + itoa(id));
|
||||
break;
|
||||
case 0xb010: //NODE_HDR
|
||||
name=parseString();
|
||||
in.sgetn( (char*)&flags1,2 );
|
||||
in.sgetn( (char*)&flags2,2 );
|
||||
in.sgetn( (char*)&parent,2 );
|
||||
_log( "NODE_HDR: name="+name+" parent="+itoa(parent) );
|
||||
name = parseString();
|
||||
in.sgetn((char*)&flags1, 2);
|
||||
in.sgetn((char*)&flags2, 2);
|
||||
in.sgetn((char*)&parent, 2);
|
||||
_log("NODE_HDR: name=" + name + " parent=" + itoa(parent));
|
||||
break;
|
||||
case 0xb011: //INSTANCE NAME
|
||||
inst=parseString();
|
||||
_log( "INSTANCE_NAME: "+inst );
|
||||
inst = parseString();
|
||||
_log("INSTANCE_NAME: " + inst);
|
||||
break;
|
||||
case 0xb013: //PIVOT
|
||||
in.sgetn( (char*)&pivot,12 );
|
||||
if( conv ) pivot=conv_tform * pivot;
|
||||
_log( "PIVOT: "+ftoa(pivot.x)+","+ftoa(pivot.y)+","+ftoa(pivot.z) );
|
||||
in.sgetn((char*)&pivot, 12);
|
||||
if (conv)
|
||||
pivot = conv_tform * pivot;
|
||||
_log("PIVOT: " + ftoa(pivot.x) + "," + ftoa(pivot.y) + "," + ftoa(pivot.z));
|
||||
break;
|
||||
case 0xb014: //BOUNDBOX
|
||||
in.sgetn( (char*)&(box.a),12 );
|
||||
in.sgetn( (char*)&(box.b),12 );
|
||||
box_centre=box.centre();
|
||||
if( conv ) box_centre=conv_tform * box_centre;
|
||||
_log( "BOUNDBOX: min="+ftoa(box.a.x)+","+ftoa(box.a.y)+","+ftoa(box.a.z)+" max="+ftoa(box.b.x)+","+ftoa(box.b.y)+","+ftoa(box.b.z) );
|
||||
in.sgetn((char*)&(box.a), 12);
|
||||
in.sgetn((char*)&(box.b), 12);
|
||||
box_centre = box.centre();
|
||||
if (conv)
|
||||
box_centre = conv_tform * box_centre;
|
||||
_log("BOUNDBOX: min=" + ftoa(box.a.x) + "," + ftoa(box.a.y) + "," + ftoa(box.a.z) + " max=" + ftoa(box.b.x)
|
||||
+ "," + ftoa(box.b.y) + "," + ftoa(box.b.z));
|
||||
break;
|
||||
case 0xb020: //POS_TRACK_TAG
|
||||
case 0xb021: //ROT_TRACK_TAG
|
||||
case 0xb022: //SCALE_TRACK_TAG
|
||||
if( !collapse ) parseAnimKeys( &anim,chunk_id );
|
||||
if (!collapse)
|
||||
parseAnimKeys(&anim, chunk_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
leaveChunk();
|
||||
|
||||
MeshModel *p=root;
|
||||
if( parent!=65535 ){
|
||||
map<int,MeshModel*>::const_iterator it=id_map.find( parent );
|
||||
if( it==id_map.end() ) return;
|
||||
p=it->second;
|
||||
MeshModel* p = root;
|
||||
if (parent != 65535) {
|
||||
map<int, MeshModel*>::const_iterator it = id_map.find(parent);
|
||||
if (it == id_map.end())
|
||||
return;
|
||||
p = it->second;
|
||||
}
|
||||
MeshModel *mesh=0;
|
||||
if( name=="$$$DUMMY" ){
|
||||
mesh=new MeshModel();
|
||||
mesh->SetName( inst );
|
||||
mesh->SetParent( p );
|
||||
}else{
|
||||
map<string,MeshModel*>::const_iterator it=name_map.find( name );
|
||||
if( it==name_map.end() ) return;
|
||||
mesh=it->second;
|
||||
name_map.erase( name );
|
||||
if( pivot!=Vector() ){
|
||||
mesh->transform( -pivot );
|
||||
MeshModel* mesh = 0;
|
||||
if (name == "$$$DUMMY") {
|
||||
mesh = new MeshModel();
|
||||
mesh->SetName(inst);
|
||||
mesh->SetParent(p);
|
||||
} else {
|
||||
map<string, MeshModel*>::const_iterator it = name_map.find(name);
|
||||
if (it == name_map.end())
|
||||
return;
|
||||
mesh = it->second;
|
||||
name_map.erase(name);
|
||||
if (pivot != Vector()) {
|
||||
mesh->transform(-pivot);
|
||||
}
|
||||
Transform t=
|
||||
mesh->GetWorldTransform();
|
||||
mesh->SetParent( p );
|
||||
mesh->SetWorldTransform( t );
|
||||
Transform t = mesh->GetWorldTransform();
|
||||
mesh->SetParent(p);
|
||||
mesh->SetWorldTransform(t);
|
||||
}
|
||||
|
||||
mesh->setAnimation( anim );
|
||||
mesh->setAnimation(anim);
|
||||
|
||||
if( id!=65535 ) id_map[id]=mesh;
|
||||
if (id != 65535)
|
||||
id_map[id] = mesh;
|
||||
}
|
||||
|
||||
static void parseKeyFramer( MeshModel *root ){
|
||||
_log( "KeyFramer" );
|
||||
static void parseKeyFramer(MeshModel* root)
|
||||
{
|
||||
_log("KeyFramer");
|
||||
enterChunk();
|
||||
string file_3ds;
|
||||
unsigned short rev,curr_time=0;
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
unsigned short rev, curr_time = 0;
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case 0xb009: //CURR_TIME
|
||||
in.sgetn( (char*)&curr_time,2 );
|
||||
_log( "CURR_TIME: "+itoa(curr_time) );
|
||||
in.sgetn((char*)&curr_time, 2);
|
||||
_log("CURR_TIME: " + itoa(curr_time));
|
||||
break;
|
||||
case 0xb00a: //KFHDR
|
||||
in.sgetn( (char*)&rev,2 );
|
||||
file_3ds=parseString();
|
||||
in.sgetn( (char*)&anim_len,2 );
|
||||
_log( "KFHDR: revision="+itoa(rev)+" 3dsfile="+file_3ds+" anim_len="+itoa(anim_len) );
|
||||
in.sgetn((char*)&rev, 2);
|
||||
file_3ds = parseString();
|
||||
in.sgetn((char*)&anim_len, 2);
|
||||
_log("KFHDR: revision=" + itoa(rev) + " 3dsfile=" + file_3ds + " anim_len=" + itoa(anim_len));
|
||||
break;
|
||||
case 0xb002: //object keyframer data...
|
||||
parseMeshInfo( root,curr_time );
|
||||
parseMeshInfo(root, curr_time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !collapse ){
|
||||
root->setAnimator( new Animator( root,anim_len ) );
|
||||
if (!collapse) {
|
||||
root->setAnimator(new Animator(root, anim_len));
|
||||
}
|
||||
|
||||
leaveChunk();
|
||||
}
|
||||
|
||||
static MeshModel *parseFile(){
|
||||
unsigned short id;int len;
|
||||
in.sgetn( (char*)&id,2 );
|
||||
in.sgetn( (char*)&len,4 );
|
||||
if( id!=CHUNK_MAIN ) return 0;
|
||||
chunk_end=(int)in.pubseekoff( 0,ios_base::cur )+len-6;
|
||||
static MeshModel* parseFile()
|
||||
{
|
||||
unsigned short id;
|
||||
int len;
|
||||
in.sgetn((char*)&id, 2);
|
||||
in.sgetn((char*)&len, 4);
|
||||
if (id != CHUNK_MAIN)
|
||||
return 0;
|
||||
chunk_end = (int)in.pubseekoff(0, ios_base::cur) + len - 6;
|
||||
|
||||
enterChunk();
|
||||
MeshModel *root=new MeshModel();
|
||||
while( int id=nextChunk() ){
|
||||
switch( id ){
|
||||
MeshModel* root = new MeshModel();
|
||||
while (int id = nextChunk()) {
|
||||
switch (id) {
|
||||
case CHUNK_SCENE:
|
||||
parseScene( root );
|
||||
parseScene(root);
|
||||
break;
|
||||
case CHUNK_KEYFRAMER:
|
||||
parseKeyFramer( root );
|
||||
parseKeyFramer(root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -494,23 +540,24 @@ static MeshModel *parseFile(){
|
||||
return root;
|
||||
}
|
||||
|
||||
MeshModel *Loader_3DS::load( const string &filename,const Transform &t,int hint ){
|
||||
|
||||
conv_tform=t;
|
||||
conv=flip_tris=false;
|
||||
if( conv_tform!=Transform() ){
|
||||
conv=true;
|
||||
if( conv_tform.m.i.cross(conv_tform.m.j).dot(conv_tform.m.k)<0 ) flip_tris=true;
|
||||
MeshModel* Loader_3DS::load(const string& filename, const Transform& t, int hint)
|
||||
{
|
||||
conv_tform = t;
|
||||
conv = flip_tris = false;
|
||||
if (conv_tform != Transform()) {
|
||||
conv = true;
|
||||
if (conv_tform.m.i.cross(conv_tform.m.j).dot(conv_tform.m.k) < 0)
|
||||
flip_tris = true;
|
||||
}
|
||||
|
||||
collapse=!!(hint&MeshLoader::HINT_COLLAPSE);
|
||||
animonly=!!(hint&MeshLoader::HINT_ANIMONLY);
|
||||
collapse = !!(hint & MeshLoader::HINT_COLLAPSE);
|
||||
animonly = !!(hint & MeshLoader::HINT_ANIMONLY);
|
||||
|
||||
if( !in.open( filename.c_str(),ios_base::in|ios_base::binary ) ){
|
||||
if (!in.open(filename.c_str(), ios_base::in | ios_base::binary)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MeshModel *root=parseFile();
|
||||
MeshModel* root = parseFile();
|
||||
in.close();
|
||||
|
||||
materials_map.clear();
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "meshloader.hpp"
|
||||
|
||||
class Loader_3DS : public MeshLoader{
|
||||
public:
|
||||
MeshModel *load( const string &f,const Transform &conv,int hint );
|
||||
class Loader_3DS : public MeshLoader {
|
||||
public:
|
||||
MeshModel* load(const string& f, const Transform& conv, int hint);
|
||||
};
|
||||
|
||||
#endif
|
||||
+229
-181
@@ -1,13 +1,13 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "loader_b3d.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "pivot.hpp"
|
||||
#include "meshutil.hpp"
|
||||
#include "pivot.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
//#define SHOW_BONES
|
||||
|
||||
static FILE *in;
|
||||
static FILE* in;
|
||||
static vector<int> chunk_stack;
|
||||
static vector<Texture> textures;
|
||||
static vector<Brush> brushes;
|
||||
@@ -16,177 +16,218 @@ static vector<Object*> bones;
|
||||
static bool collapse;
|
||||
static bool animonly;
|
||||
|
||||
static int swap_endian( int n ){
|
||||
return ((n&0xff)<<24)|((n&0xff00)<<8)|((n&0xff0000)>>8)|((n&0xff000000)>>24);
|
||||
static int swap_endian(int n)
|
||||
{
|
||||
return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
static void clear(){
|
||||
static void clear()
|
||||
{
|
||||
bones.clear();
|
||||
brushes.clear();
|
||||
textures.clear();
|
||||
chunk_stack.clear();
|
||||
}
|
||||
|
||||
static int readChunk(){
|
||||
static int readChunk()
|
||||
{
|
||||
int header[2];
|
||||
if( fread( header,8,1,in )<1 ) return 0;
|
||||
chunk_stack.push_back( ftell( in )+header[1] );
|
||||
return swap_endian( header[0] );
|
||||
if (fread(header, 8, 1, in) < 1)
|
||||
return 0;
|
||||
chunk_stack.push_back(ftell(in) + header[1]);
|
||||
return swap_endian(header[0]);
|
||||
}
|
||||
|
||||
static void exitChunk(){
|
||||
fseek( in,chunk_stack.back(),SEEK_SET );
|
||||
static void exitChunk()
|
||||
{
|
||||
fseek(in, chunk_stack.back(), SEEK_SET);
|
||||
chunk_stack.pop_back();
|
||||
}
|
||||
|
||||
static int chunkSize(){
|
||||
return chunk_stack.back()-ftell( in );
|
||||
static int chunkSize()
|
||||
{
|
||||
return chunk_stack.back() - ftell(in);
|
||||
}
|
||||
|
||||
static void read( void *buf,int n ){
|
||||
fread( buf,n,1,in );
|
||||
static void read(void* buf, int n)
|
||||
{
|
||||
fread(buf, n, 1, in);
|
||||
}
|
||||
|
||||
static void skip( int n ){
|
||||
fseek( in,n,SEEK_CUR );
|
||||
static void skip(int n)
|
||||
{
|
||||
fseek(in, n, SEEK_CUR);
|
||||
}
|
||||
|
||||
static int readInt(){
|
||||
static int readInt()
|
||||
{
|
||||
int n;
|
||||
read( &n,4 );
|
||||
read(&n, 4);
|
||||
return n;
|
||||
}
|
||||
|
||||
static void readIntArray( int t[],int n ){
|
||||
read( t,n*4 );
|
||||
static void readIntArray(int t[], int n)
|
||||
{
|
||||
read(t, n * 4);
|
||||
}
|
||||
|
||||
static float readFloat(){
|
||||
static float readFloat()
|
||||
{
|
||||
float n;
|
||||
read( &n,4 );
|
||||
read(&n, 4);
|
||||
return n;
|
||||
}
|
||||
|
||||
static void readFloatArray( float t[],int n ){
|
||||
read( t,n*4 );
|
||||
static void readFloatArray(float t[], int n)
|
||||
{
|
||||
read(t, n * 4);
|
||||
}
|
||||
|
||||
static void readColor( unsigned *t ){
|
||||
float r=readFloat();if(r<0) r=0;else if(r>1) r=1;
|
||||
float g=readFloat();if(g<0) g=0;else if(g>1) g=1;
|
||||
float b=readFloat();if(b<0) b=0;else if(b>1) b=1;
|
||||
float a=readFloat();if(a<0) a=0;else if(a>1) a=1;
|
||||
*t=(int(a*255)<<24)|(int(r*255)<<16)|(int(g*255)<<8)|int(b*255);
|
||||
static void readColor(unsigned* t)
|
||||
{
|
||||
float r = readFloat();
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
else if (r > 1)
|
||||
r = 1;
|
||||
float g = readFloat();
|
||||
if (g < 0)
|
||||
g = 0;
|
||||
else if (g > 1)
|
||||
g = 1;
|
||||
float b = readFloat();
|
||||
if (b < 0)
|
||||
b = 0;
|
||||
else if (b > 1)
|
||||
b = 1;
|
||||
float a = readFloat();
|
||||
if (a < 0)
|
||||
a = 0;
|
||||
else if (a > 1)
|
||||
a = 1;
|
||||
*t = (int(a * 255) << 24) | (int(r * 255) << 16) | (int(g * 255) << 8) | int(b * 255);
|
||||
}
|
||||
|
||||
static string readString(){
|
||||
static string readString()
|
||||
{
|
||||
string t;
|
||||
for(;;){
|
||||
for (;;) {
|
||||
char c;
|
||||
read( &c,1 );
|
||||
if( !c ) return t;
|
||||
t+=c;
|
||||
read(&c, 1);
|
||||
if (!c)
|
||||
return t;
|
||||
t += c;
|
||||
}
|
||||
}
|
||||
|
||||
static void readTextures(){
|
||||
while( chunkSize() ){
|
||||
string name=readString();
|
||||
int flags=readInt();
|
||||
int blend=readInt();
|
||||
float pos[2],scl[2];
|
||||
readFloatArray( pos,2 );
|
||||
readFloatArray( scl,2 );
|
||||
float rot=readFloat();
|
||||
static void readTextures()
|
||||
{
|
||||
while (chunkSize()) {
|
||||
string name = readString();
|
||||
int flags = readInt();
|
||||
int blend = readInt();
|
||||
float pos[2], scl[2];
|
||||
readFloatArray(pos, 2);
|
||||
readFloatArray(scl, 2);
|
||||
float rot = readFloat();
|
||||
|
||||
//create texture
|
||||
Texture tex( name,flags & 0xffff );
|
||||
Texture tex(name, flags & 0xffff);
|
||||
|
||||
tex.setBlend( blend );
|
||||
if( flags & 0x10000 ) tex.setFlags( gxScene::TEX_COORDS2 );
|
||||
tex.setBlend(blend);
|
||||
if (flags & 0x10000)
|
||||
tex.setFlags(gxScene::TEX_COORDS2);
|
||||
|
||||
if( pos[0]!=0 || pos[1]!=0 ) tex.setPosition( pos[0],pos[1] );
|
||||
if( scl[0]!=1 || scl[1]!=1 ) tex.setScale( scl[0],scl[1] );
|
||||
if( rot!=0 ) tex.setRotation( rot );
|
||||
if (pos[0] != 0 || pos[1] != 0)
|
||||
tex.setPosition(pos[0], pos[1]);
|
||||
if (scl[0] != 1 || scl[1] != 1)
|
||||
tex.setScale(scl[0], scl[1]);
|
||||
if (rot != 0)
|
||||
tex.setRotation(rot);
|
||||
|
||||
textures.push_back( tex );
|
||||
textures.push_back(tex);
|
||||
}
|
||||
}
|
||||
|
||||
static void readBrushes(){
|
||||
int n_texs=readInt();
|
||||
static void readBrushes()
|
||||
{
|
||||
int n_texs = readInt();
|
||||
|
||||
int tex_id[8]={-1,-1,-1,-1,-1,-1,-1,-1};
|
||||
int tex_id[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
|
||||
while( chunkSize() ){
|
||||
string name=readString();
|
||||
while (chunkSize()) {
|
||||
string name = readString();
|
||||
float col[4];
|
||||
readFloatArray( col,4 );
|
||||
float shi=readFloat();
|
||||
int blend=readInt();
|
||||
int fx=readInt();
|
||||
readIntArray( tex_id,n_texs );
|
||||
readFloatArray(col, 4);
|
||||
float shi = readFloat();
|
||||
int blend = readInt();
|
||||
int fx = readInt();
|
||||
readIntArray(tex_id, n_texs);
|
||||
|
||||
Brush bru;
|
||||
|
||||
bru.setColor( Vector( col[0],col[1],col[2] ) );
|
||||
bru.setAlpha( col[3] );
|
||||
bru.setShininess( shi );
|
||||
bru.setBlend( blend );
|
||||
bru.setFX( fx );
|
||||
bru.setColor(Vector(col[0], col[1], col[2]));
|
||||
bru.setAlpha(col[3]);
|
||||
bru.setShininess(shi);
|
||||
bru.setBlend(blend);
|
||||
bru.setFX(fx);
|
||||
|
||||
for( int k=0;k<8;++k ){
|
||||
if( tex_id[k]<0 ) continue;
|
||||
bru.setTexture( k,textures[tex_id[k]],0 );
|
||||
for (int k = 0; k < 8; ++k) {
|
||||
if (tex_id[k] < 0)
|
||||
continue;
|
||||
bru.setTexture(k, textures[tex_id[k]], 0);
|
||||
}
|
||||
|
||||
brushes.push_back( bru );
|
||||
brushes.push_back(bru);
|
||||
}
|
||||
}
|
||||
|
||||
static int readVertices(){
|
||||
static int readVertices()
|
||||
{
|
||||
int flags = readInt();
|
||||
int tc_sets = readInt();
|
||||
int tc_size = readInt();
|
||||
|
||||
int flags=readInt();
|
||||
int tc_sets=readInt();
|
||||
int tc_size=readInt();
|
||||
|
||||
float tc[4]={0};
|
||||
float tc[4] = {0};
|
||||
|
||||
Surface::Vertex t;
|
||||
while( chunkSize() ){
|
||||
readFloatArray( t.coords,3 );
|
||||
if( flags&1 ){
|
||||
readFloatArray( t.normal,3 );
|
||||
while (chunkSize()) {
|
||||
readFloatArray(t.coords, 3);
|
||||
if (flags & 1) {
|
||||
readFloatArray(t.normal, 3);
|
||||
}
|
||||
if( flags&2 ){
|
||||
readColor( &t.color );
|
||||
if (flags & 2) {
|
||||
readColor(&t.color);
|
||||
}
|
||||
for( int k=0;k<tc_sets;++k ){
|
||||
readFloatArray( tc,tc_size );
|
||||
if( k<2 ) memcpy( t.tex_coords[k],tc,8 );
|
||||
for (int k = 0; k < tc_sets; ++k) {
|
||||
readFloatArray(tc, tc_size);
|
||||
if (k < 2)
|
||||
memcpy(t.tex_coords[k], tc, 8);
|
||||
}
|
||||
MeshLoader::addVertex( t );
|
||||
MeshLoader::addVertex(t);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void readTriangles(){
|
||||
int brush_id=readInt();
|
||||
Brush b=brush_id>=0 ? brushes[brush_id] : Brush();
|
||||
while( chunkSize() ){
|
||||
static void readTriangles()
|
||||
{
|
||||
int brush_id = readInt();
|
||||
Brush b = brush_id >= 0 ? brushes[brush_id] : Brush();
|
||||
while (chunkSize()) {
|
||||
int verts[3];
|
||||
readIntArray( verts,3 );
|
||||
MeshLoader::addTriangle( verts,b );
|
||||
readIntArray(verts, 3);
|
||||
MeshLoader::addTriangle(verts, b);
|
||||
}
|
||||
}
|
||||
|
||||
static int readMesh(){
|
||||
int flags=0;
|
||||
while( chunkSize() ){
|
||||
switch( readChunk() ){
|
||||
static int readMesh()
|
||||
{
|
||||
int flags = 0;
|
||||
while (chunkSize()) {
|
||||
switch (readChunk()) {
|
||||
case 'VRTS':
|
||||
flags=readVertices();
|
||||
flags = readVertices();
|
||||
break;
|
||||
case 'TRIS':
|
||||
readTriangles();
|
||||
@@ -197,149 +238,156 @@ static int readMesh(){
|
||||
return flags;
|
||||
}
|
||||
|
||||
static Object *readBone(){
|
||||
|
||||
static Object* readBone()
|
||||
{
|
||||
#ifdef SHOW_BONES
|
||||
Brush b;
|
||||
b.setColor( Vector( 1,0,0 ) );
|
||||
b.setAlpha( .75f );
|
||||
MeshModel *bone=MeshUtil::createSphere( b,16 );
|
||||
b.setColor(Vector(1, 0, 0));
|
||||
b.setAlpha(.75f);
|
||||
MeshModel* bone = MeshUtil::createSphere(b, 16);
|
||||
Transform t;
|
||||
t.m.i.x=.1f;
|
||||
t.m.j.y=.1f;
|
||||
t.m.k.z=.1f;
|
||||
bone->transform( t );
|
||||
t.m.i.x = .1f;
|
||||
t.m.j.y = .1f;
|
||||
t.m.k.z = .1f;
|
||||
bone->transform(t);
|
||||
#else
|
||||
Pivot *bone=new Pivot();
|
||||
Pivot* bone = new Pivot();
|
||||
#endif
|
||||
|
||||
bones.push_back( bone );
|
||||
bones.push_back(bone);
|
||||
|
||||
while( chunkSize() ){
|
||||
int vert=readInt();
|
||||
float weight=readFloat();
|
||||
MeshLoader::addBone( vert,weight,bones.size() );
|
||||
while (chunkSize()) {
|
||||
int vert = readInt();
|
||||
float weight = readFloat();
|
||||
MeshLoader::addBone(vert, weight, bones.size());
|
||||
}
|
||||
return bone;
|
||||
}
|
||||
|
||||
static void readKeys( Animation &anim ){
|
||||
int flags=readInt();
|
||||
while( chunkSize() ){
|
||||
int frame=readInt();
|
||||
if( flags&1 ){
|
||||
static void readKeys(Animation& anim)
|
||||
{
|
||||
int flags = readInt();
|
||||
while (chunkSize()) {
|
||||
int frame = readInt();
|
||||
if (flags & 1) {
|
||||
float pos[3];
|
||||
readFloatArray( pos,3 );
|
||||
anim.setPositionKey( frame,Vector(pos[0],pos[1],pos[2]) );
|
||||
readFloatArray(pos, 3);
|
||||
anim.setPositionKey(frame, Vector(pos[0], pos[1], pos[2]));
|
||||
}
|
||||
if( flags&2 ){
|
||||
if (flags & 2) {
|
||||
float scl[3];
|
||||
readFloatArray( scl,3 );
|
||||
anim.setScaleKey( frame,Vector(scl[0],scl[1],scl[2]) );
|
||||
readFloatArray(scl, 3);
|
||||
anim.setScaleKey(frame, Vector(scl[0], scl[1], scl[2]));
|
||||
}
|
||||
if( flags&4 ){
|
||||
if (flags & 4) {
|
||||
float rot[4];
|
||||
readFloatArray( rot,4 );
|
||||
anim.setRotationKey( frame,Quat(rot[0],Vector(rot[1],rot[2],rot[3])) );
|
||||
readFloatArray(rot, 4);
|
||||
anim.setRotationKey(frame, Quat(rot[0], Vector(rot[1], rot[2], rot[3])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Object *readObject( Object *parent ){
|
||||
static Object* readObject(Object* parent)
|
||||
{
|
||||
Object* obj = 0;
|
||||
|
||||
Object *obj=0;
|
||||
|
||||
string name=readString();
|
||||
float pos[3],scl[3],rot[4];
|
||||
readFloatArray( pos,3 );
|
||||
readFloatArray( scl,3 );
|
||||
readFloatArray( rot,4 );
|
||||
string name = readString();
|
||||
float pos[3], scl[3], rot[4];
|
||||
readFloatArray(pos, 3);
|
||||
readFloatArray(scl, 3);
|
||||
readFloatArray(rot, 4);
|
||||
|
||||
Animation keys;
|
||||
int anim_len=0;
|
||||
MeshModel *mesh=0;
|
||||
int mesh_flags,mesh_brush;
|
||||
int anim_len = 0;
|
||||
MeshModel* mesh = 0;
|
||||
int mesh_flags, mesh_brush;
|
||||
|
||||
while( chunkSize() ){
|
||||
switch( readChunk() ){
|
||||
while (chunkSize()) {
|
||||
switch (readChunk()) {
|
||||
case 'MESH':
|
||||
MeshLoader::beginMesh();
|
||||
obj=mesh=new MeshModel();
|
||||
mesh_brush=readInt();
|
||||
mesh_flags=readMesh();
|
||||
obj = mesh = new MeshModel();
|
||||
mesh_brush = readInt();
|
||||
mesh_flags = readMesh();
|
||||
break;
|
||||
case 'BONE':
|
||||
obj=readBone();
|
||||
obj = readBone();
|
||||
break;
|
||||
case 'KEYS':
|
||||
readKeys( keys );
|
||||
readKeys(keys);
|
||||
break;
|
||||
case 'ANIM':
|
||||
readInt();
|
||||
anim_len=readInt();
|
||||
anim_len = readInt();
|
||||
readFloat();
|
||||
break;
|
||||
case 'NODE':
|
||||
if( !obj ) obj=new MeshModel();
|
||||
readObject( obj );
|
||||
if (!obj)
|
||||
obj = new MeshModel();
|
||||
readObject(obj);
|
||||
break;
|
||||
}
|
||||
exitChunk();
|
||||
}
|
||||
|
||||
if( !obj ) obj=new MeshModel();
|
||||
if (!obj)
|
||||
obj = new MeshModel();
|
||||
|
||||
obj->SetName( name );
|
||||
obj->SetLocalPosition( Vector( pos[0],pos[1],pos[2] ) );
|
||||
obj->SetLocalScale( Vector( scl[0],scl[1],scl[2] ) );
|
||||
obj->SetLocalRotation( Quat( rot[0],Vector( rot[1],rot[2],rot[3] ) ) );
|
||||
obj->setAnimation( keys );
|
||||
obj->SetName(name);
|
||||
obj->SetLocalPosition(Vector(pos[0], pos[1], pos[2]));
|
||||
obj->SetLocalScale(Vector(scl[0], scl[1], scl[2]));
|
||||
obj->SetLocalRotation(Quat(rot[0], Vector(rot[1], rot[2], rot[3])));
|
||||
obj->setAnimation(keys);
|
||||
|
||||
if( mesh ){
|
||||
MeshLoader::endMesh( mesh );
|
||||
if( !(mesh_flags&1) ) mesh->updateNormals();
|
||||
if( mesh_brush!=-1 ) mesh->setBrush( brushes[mesh_brush] );
|
||||
if (mesh) {
|
||||
MeshLoader::endMesh(mesh);
|
||||
if (!(mesh_flags & 1))
|
||||
mesh->updateNormals();
|
||||
if (mesh_brush != -1)
|
||||
mesh->setBrush(brushes[mesh_brush]);
|
||||
}
|
||||
|
||||
if( mesh && bones.size() ){
|
||||
bones.insert( bones.begin(),mesh );
|
||||
mesh->setAnimator( new Animator( bones,anim_len ) );
|
||||
if (mesh && bones.size()) {
|
||||
bones.insert(bones.begin(), mesh);
|
||||
mesh->setAnimator(new Animator(bones, anim_len));
|
||||
mesh->createBones();
|
||||
bones.clear();
|
||||
}else if( anim_len ){
|
||||
obj->setAnimator( new Animator( obj,anim_len ) );
|
||||
} else if (anim_len) {
|
||||
obj->setAnimator(new Animator(obj, anim_len));
|
||||
}
|
||||
|
||||
if( parent ) obj->SetParent( parent );
|
||||
if (parent)
|
||||
obj->SetParent(parent);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
MeshModel *Loader_B3D::load( const string &f,const Transform &conv,int hint ){
|
||||
MeshModel* Loader_B3D::load(const string& f, const Transform& conv, int hint)
|
||||
{
|
||||
collapse = !!(hint & MeshLoader::HINT_COLLAPSE);
|
||||
animonly = !!(hint & MeshLoader::HINT_ANIMONLY);
|
||||
|
||||
collapse=!!(hint&MeshLoader::HINT_COLLAPSE);
|
||||
animonly=!!(hint&MeshLoader::HINT_ANIMONLY);
|
||||
|
||||
in=fopen( f.c_str(),"rb" );
|
||||
if( !in ) return 0;
|
||||
in = fopen(f.c_str(), "rb");
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
::clear();
|
||||
|
||||
int tag=readChunk();
|
||||
if( tag!='BB3D' ){
|
||||
fclose( in );
|
||||
int tag = readChunk();
|
||||
if (tag != 'BB3D') {
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int version=readInt();
|
||||
if( version>1 ){
|
||||
fclose( in );
|
||||
int version = readInt();
|
||||
if (version > 1) {
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Object *obj=0;
|
||||
while( chunkSize() ){
|
||||
switch( readChunk() ){
|
||||
Object* obj = 0;
|
||||
while (chunkSize()) {
|
||||
switch (readChunk()) {
|
||||
case 'TEXS':
|
||||
readTextures();
|
||||
break;
|
||||
@@ -347,12 +395,12 @@ MeshModel *Loader_B3D::load( const string &f,const Transform &conv,int hint ){
|
||||
readBrushes();
|
||||
break;
|
||||
case 'NODE':
|
||||
obj=readObject( 0 );
|
||||
obj = readObject(0);
|
||||
break;
|
||||
}
|
||||
exitChunk();
|
||||
}
|
||||
fclose( in );
|
||||
fclose(in);
|
||||
|
||||
::clear();
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "meshloader.hpp"
|
||||
|
||||
class Loader_B3D : public MeshLoader{
|
||||
public:
|
||||
MeshModel *load( const string &f,const Transform &conv,int hint );
|
||||
class Loader_B3D : public MeshLoader {
|
||||
public:
|
||||
MeshModel* load(const string& f, const Transform& conv, int hint);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+275
-232
@@ -1,102 +1,114 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "loader_x.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "animation.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "pivot.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
#include <windows.h>
|
||||
//#include <dxfile.h>
|
||||
#include "../gxruntime/GraphicsRuntime.hpp"
|
||||
#include <d3d9types.h>
|
||||
#include <d3dx9xof.h>
|
||||
#include <rmxfguid.h>
|
||||
#include <rmxftmpl.h>
|
||||
#include "../gxruntime/GraphicsRuntime.hpp"
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
static map<string,MeshModel*> frames_map;
|
||||
extern gxRuntime* gx_runtime;
|
||||
static map<string, MeshModel*> frames_map;
|
||||
static int anim_len;
|
||||
|
||||
static bool conv,flip_tris;
|
||||
static bool conv, flip_tris;
|
||||
static Transform conv_tform;
|
||||
static bool collapse,animonly;
|
||||
static bool collapse, animonly;
|
||||
|
||||
static void parseAnimKey(ID3DXFileData *fileData, MeshModel *e) {
|
||||
static void parseAnimKey(ID3DXFileData* fileData, MeshModel* e)
|
||||
{
|
||||
DWORD sz;
|
||||
int* data;
|
||||
if (fileData->GetData(0, &sz, (void**)&data) < 0)
|
||||
return;
|
||||
|
||||
DWORD sz;int *data;
|
||||
if( fileData->GetData( 0,&sz,(void**)&data )<0 ) return;
|
||||
|
||||
int type=*data++;
|
||||
int cnt=*data++;
|
||||
Animation anim=e->getAnimation();
|
||||
for( int k=0;k<cnt;++k ){
|
||||
int time=*data++;
|
||||
int n=*data++;
|
||||
if( time>anim_len ) anim_len=time;
|
||||
switch( type ){
|
||||
int type = *data++;
|
||||
int cnt = *data++;
|
||||
Animation anim = e->getAnimation();
|
||||
for (int k = 0; k < cnt; ++k) {
|
||||
int time = *data++;
|
||||
int n = *data++;
|
||||
if (time > anim_len)
|
||||
anim_len = time;
|
||||
switch (type) {
|
||||
case 0:
|
||||
if( n==4 ){
|
||||
Quat rot=*(Quat*)data;
|
||||
if( conv ){
|
||||
if( fabs(rot.w)<1-FLT_EPSILON ){
|
||||
if (n == 4) {
|
||||
Quat rot = *(Quat*)data;
|
||||
if (conv) {
|
||||
if (fabs(rot.w) < 1 - FLT_EPSILON) {
|
||||
rot.normalize();
|
||||
//quat-to-axis/angle
|
||||
float half=acosf( rot.w );
|
||||
if( flip_tris ) half=-half;
|
||||
rot=Quat( cosf( half ),(conv_tform.m*rot.v).normalized()*sinf( half ) );
|
||||
}else rot=Quat();
|
||||
float half = acosf(rot.w);
|
||||
if (flip_tris)
|
||||
half = -half;
|
||||
rot = Quat(cosf(half), (conv_tform.m * rot.v).normalized() * sinf(half));
|
||||
} else
|
||||
rot = Quat();
|
||||
}
|
||||
anim.setRotationKey( time,rot );
|
||||
anim.setRotationKey(time, rot);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if( n==3 ){
|
||||
Vector scl=*(Vector*)data;
|
||||
if( conv ) scl=conv_tform.m * scl;
|
||||
scl.x=fabs(scl.x);scl.y=fabs(scl.y);scl.z=fabs(scl.z);
|
||||
anim.setScaleKey( time,scl );
|
||||
if (n == 3) {
|
||||
Vector scl = *(Vector*)data;
|
||||
if (conv)
|
||||
scl = conv_tform.m * scl;
|
||||
scl.x = fabs(scl.x);
|
||||
scl.y = fabs(scl.y);
|
||||
scl.z = fabs(scl.z);
|
||||
anim.setScaleKey(time, scl);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if( n==3 ){
|
||||
Vector pos=*(Vector*)data;
|
||||
if( conv ) pos=conv_tform*pos;
|
||||
anim.setPositionKey( time,pos );
|
||||
if (n == 3) {
|
||||
Vector pos = *(Vector*)data;
|
||||
if (conv)
|
||||
pos = conv_tform * pos;
|
||||
anim.setPositionKey(time, pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
data+=n;
|
||||
data += n;
|
||||
}
|
||||
e->setAnimation( anim );
|
||||
e->setAnimation(anim);
|
||||
}
|
||||
|
||||
static void parseAnim(ID3DXFileData *fileData) {
|
||||
const GUID *guid;
|
||||
IDirectXFileObject *childObj;
|
||||
IDirectXFileData *childData;
|
||||
IDirectXFileDataReference *childRef;
|
||||
MeshModel *frame=0;
|
||||
static void parseAnim(ID3DXFileData* fileData)
|
||||
{
|
||||
const GUID* guid;
|
||||
IDirectXFileObject* childObj;
|
||||
IDirectXFileData* childData;
|
||||
IDirectXFileDataReference* childRef;
|
||||
MeshModel* frame = 0;
|
||||
|
||||
//find the frame reference
|
||||
for( ;fileData->GetNextObject( &childObj )>=0;childObj->Release() ){
|
||||
if( childObj->QueryInterface( IID_IDirectXFileDataReference,(void**)&childRef )>=0 ){
|
||||
if( childRef->Resolve( &childData )>=0 ){
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
if( *guid==TID_D3DRMFrame ){
|
||||
char name[80];DWORD len=80;
|
||||
if( childData->GetName( name,&len )>=0 ){
|
||||
map<string,MeshModel*>::iterator it=frames_map.find( name );
|
||||
if( it!=frames_map.end() ) frame=it->second;
|
||||
for (; fileData->GetNextObject(&childObj) >= 0; childObj->Release()) {
|
||||
if (childObj->QueryInterface(IID_IDirectXFileDataReference, (void**)&childRef) >= 0) {
|
||||
if (childRef->Resolve(&childData) >= 0) {
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
if (*guid == TID_D3DRMFrame) {
|
||||
char name[80];
|
||||
DWORD len = 80;
|
||||
if (childData->GetName(name, &len) >= 0) {
|
||||
map<string, MeshModel*>::iterator it = frames_map.find(name);
|
||||
if (it != frames_map.end())
|
||||
frame = it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
childData->Release();
|
||||
}
|
||||
childRef->Release();
|
||||
}else if( frame && childObj->QueryInterface( IID_IDirectXFileData,(void**)&childData )>=0 ){
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
if( *guid==TID_D3DRMAnimationKey ){
|
||||
parseAnimKey( childData,frame );
|
||||
} else if (frame && childObj->QueryInterface(IID_IDirectXFileData, (void**)&childData) >= 0) {
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
if (*guid == TID_D3DRMAnimationKey) {
|
||||
parseAnimKey(childData, frame);
|
||||
}
|
||||
}
|
||||
childData->Release();
|
||||
@@ -104,43 +116,51 @@ static void parseAnim(ID3DXFileData *fileData) {
|
||||
}
|
||||
}
|
||||
|
||||
static void parseAnimSet( IDirectXFileData *fileData ){
|
||||
const GUID *guid;
|
||||
IDirectXFileObject *childObj;
|
||||
IDirectXFileData *childData;
|
||||
static void parseAnimSet(IDirectXFileData* fileData)
|
||||
{
|
||||
const GUID* guid;
|
||||
IDirectXFileObject* childObj;
|
||||
IDirectXFileData* childData;
|
||||
|
||||
for( ;fileData->GetNextObject( &childObj )>=0;childObj->Release() ){
|
||||
if( childObj->QueryInterface( IID_IDirectXFileData,(void**)&childData )<0 ) continue;
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
if( *guid==TID_D3DRMAnimation ){
|
||||
parseAnim( childData );
|
||||
for (; fileData->GetNextObject(&childObj) >= 0; childObj->Release()) {
|
||||
if (childObj->QueryInterface(IID_IDirectXFileData, (void**)&childData) < 0)
|
||||
continue;
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
if (*guid == TID_D3DRMAnimation) {
|
||||
parseAnim(childData);
|
||||
}
|
||||
}
|
||||
childData->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static Brush parseMaterial( IDirectXFileData *fileData ){
|
||||
const GUID *guid;
|
||||
IDirectXFileObject *childObj;
|
||||
IDirectXFileData *childData;
|
||||
static Brush parseMaterial(IDirectXFileData* fileData)
|
||||
{
|
||||
const GUID* guid;
|
||||
IDirectXFileObject* childObj;
|
||||
IDirectXFileData* childData;
|
||||
|
||||
Brush brush;
|
||||
|
||||
DWORD sz;float *data;
|
||||
if( fileData->GetData( 0,&sz,(void**)&data )<0 ) return brush;
|
||||
DWORD sz;
|
||||
float* data;
|
||||
if (fileData->GetData(0, &sz, (void**)&data) < 0)
|
||||
return brush;
|
||||
|
||||
brush.setColor( Vector( data[0],data[1],data[2] ) );
|
||||
if( data[3] ) brush.setAlpha( data[3] );
|
||||
brush.setColor(Vector(data[0], data[1], data[2]));
|
||||
if (data[3])
|
||||
brush.setAlpha(data[3]);
|
||||
|
||||
for( ;fileData->GetNextObject( &childObj )>=0;childObj->Release() ){
|
||||
if( childObj->QueryInterface( IID_IDirectXFileData,(void**)&childData )<0 ) continue;
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
if( *guid==TID_D3DRMTextureFilename ){
|
||||
DWORD sz;char **data;
|
||||
if( childData->GetData( 0,&sz,(void**)&data )>=0 ){
|
||||
brush.setTexture( 0,Texture( *data,0 ),0 );
|
||||
brush.setColor( Vector( 1,1,1 ) );
|
||||
for (; fileData->GetNextObject(&childObj) >= 0; childObj->Release()) {
|
||||
if (childObj->QueryInterface(IID_IDirectXFileData, (void**)&childData) < 0)
|
||||
continue;
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
if (*guid == TID_D3DRMTextureFilename) {
|
||||
DWORD sz;
|
||||
char** data;
|
||||
if (childData->GetData(0, &sz, (void**)&data) >= 0) {
|
||||
brush.setTexture(0, Texture(*data, 0), 0);
|
||||
brush.setColor(Vector(1, 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,27 +170,27 @@ static Brush parseMaterial( IDirectXFileData *fileData ){
|
||||
return brush;
|
||||
}
|
||||
|
||||
static void parseMaterialList( IDirectXFileData *fileData,vector<Brush> &mats ){
|
||||
|
||||
const GUID *guid;
|
||||
IDirectXFileObject *childObj;
|
||||
IDirectXFileData *childData;
|
||||
IDirectXFileDataReference *childRef;
|
||||
static void parseMaterialList(IDirectXFileData* fileData, vector<Brush>& mats)
|
||||
{
|
||||
const GUID* guid;
|
||||
IDirectXFileObject* childObj;
|
||||
IDirectXFileData* childData;
|
||||
IDirectXFileDataReference* childRef;
|
||||
|
||||
//iterate through child objects...
|
||||
for( ;fileData->GetNextObject( &childObj )>=0;childObj->Release() ){
|
||||
if( childObj->QueryInterface( IID_IDirectXFileData,(void**)&childData )>=0 ){
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
if( *guid==TID_D3DRMMaterial ){
|
||||
mats.push_back( parseMaterial( childData ) );
|
||||
for (; fileData->GetNextObject(&childObj) >= 0; childObj->Release()) {
|
||||
if (childObj->QueryInterface(IID_IDirectXFileData, (void**)&childData) >= 0) {
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
if (*guid == TID_D3DRMMaterial) {
|
||||
mats.push_back(parseMaterial(childData));
|
||||
}
|
||||
}
|
||||
childData->Release();
|
||||
}else if( childObj->QueryInterface( IID_IDirectXFileDataReference,(void**)&childRef )>=0 ){
|
||||
if( childRef->Resolve( &childData )>=0 ){
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
if( *guid==TID_D3DRMMaterial ){
|
||||
mats.push_back( parseMaterial( childData ) );
|
||||
} else if (childObj->QueryInterface(IID_IDirectXFileDataReference, (void**)&childRef) >= 0) {
|
||||
if (childRef->Resolve(&childData) >= 0) {
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
if (*guid == TID_D3DRMMaterial) {
|
||||
mats.push_back(parseMaterial(childData));
|
||||
}
|
||||
}
|
||||
childData->Release();
|
||||
@@ -180,19 +200,21 @@ static void parseMaterialList( IDirectXFileData *fileData,vector<Brush> &mats ){
|
||||
}
|
||||
}
|
||||
|
||||
struct FaceX{
|
||||
int *data,mat_index;
|
||||
FaceX( int *d ):data(d),mat_index(0){}
|
||||
struct FaceX {
|
||||
int *data, mat_index;
|
||||
FaceX(int* d) : data(d), mat_index(0) {}
|
||||
};
|
||||
|
||||
static void parseMesh( IDirectXFileData *fileData,MeshModel *mesh ){
|
||||
static void parseMesh(IDirectXFileData* fileData, MeshModel* mesh)
|
||||
{
|
||||
const GUID* guid;
|
||||
IDirectXFileObject* childObj;
|
||||
IDirectXFileData* childData;
|
||||
|
||||
const GUID *guid;
|
||||
IDirectXFileObject *childObj;
|
||||
IDirectXFileData *childData;
|
||||
|
||||
DWORD sz;int *data;
|
||||
if( fileData->GetData( 0,&sz,(void**)&data )<0 ) return;
|
||||
DWORD sz;
|
||||
int* data;
|
||||
if (fileData->GetData(0, &sz, (void**)&data) < 0)
|
||||
return;
|
||||
|
||||
//stuff...
|
||||
vector<FaceX> faces;
|
||||
@@ -201,131 +223,144 @@ static void parseMesh( IDirectXFileData *fileData,MeshModel *mesh ){
|
||||
MeshLoader::beginMesh();
|
||||
|
||||
//setup vertices
|
||||
int num_verts=*data++;
|
||||
int num_verts = *data++;
|
||||
int k;
|
||||
for( k=0;k<num_verts;++k ){
|
||||
for (k = 0; k < num_verts; ++k) {
|
||||
Surface::Vertex v;
|
||||
v.coords=*(Vector*)data;
|
||||
if( conv ) v.coords=conv_tform * v.coords;
|
||||
v.color=0xffffffff;//Vector(1,1,1);
|
||||
MeshLoader::addVertex( v );
|
||||
data+=3;
|
||||
v.coords = *(Vector*)data;
|
||||
if (conv)
|
||||
v.coords = conv_tform * v.coords;
|
||||
v.color = 0xffffffff; //Vector(1,1,1);
|
||||
MeshLoader::addVertex(v);
|
||||
data += 3;
|
||||
}
|
||||
|
||||
//setup faces
|
||||
int num_faces=*data++;
|
||||
for( k=0;k<num_faces;++k ){
|
||||
faces.push_back( FaceX( data ) );
|
||||
data+=*data+1;
|
||||
int num_faces = *data++;
|
||||
for (k = 0; k < num_faces; ++k) {
|
||||
faces.push_back(FaceX(data));
|
||||
data += *data + 1;
|
||||
}
|
||||
|
||||
bool normals=false;
|
||||
bool normals = false;
|
||||
|
||||
//get material and texture info
|
||||
for( ;fileData->GetNextObject( &childObj )>=0;childObj->Release() ){
|
||||
if( childObj->QueryInterface( IID_IDirectXFileData,(void**)&childData )<0 ) continue;
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
DWORD sz;int *data;
|
||||
if( childData->GetData( 0,&sz,(void**)&data )>=0 ){
|
||||
if( *guid==TID_D3DRMMeshMaterialList ){
|
||||
int num_mats=*data++;
|
||||
int num_faces=*data++;
|
||||
for( int k=0;k<num_faces;++k ){
|
||||
faces[k].mat_index=*data++;
|
||||
for (; fileData->GetNextObject(&childObj) >= 0; childObj->Release()) {
|
||||
if (childObj->QueryInterface(IID_IDirectXFileData, (void**)&childData) < 0)
|
||||
continue;
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
DWORD sz;
|
||||
int* data;
|
||||
if (childData->GetData(0, &sz, (void**)&data) >= 0) {
|
||||
if (*guid == TID_D3DRMMeshMaterialList) {
|
||||
int num_mats = *data++;
|
||||
int num_faces = *data++;
|
||||
for (int k = 0; k < num_faces; ++k) {
|
||||
faces[k].mat_index = *data++;
|
||||
}
|
||||
parseMaterialList( childData,mats );
|
||||
}else if( *guid==TID_D3DRMMeshTextureCoords ){
|
||||
int num_coords=*data++;
|
||||
if( num_coords==num_verts ){
|
||||
float *coords=(float*)data;
|
||||
for( int k=0;k<num_coords;++k ){
|
||||
Surface::Vertex &v=MeshLoader::refVertex(k);
|
||||
float tu=*coords++;float tv=*coords++;
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=tu;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=tv;
|
||||
parseMaterialList(childData, mats);
|
||||
} else if (*guid == TID_D3DRMMeshTextureCoords) {
|
||||
int num_coords = *data++;
|
||||
if (num_coords == num_verts) {
|
||||
float* coords = (float*)data;
|
||||
for (int k = 0; k < num_coords; ++k) {
|
||||
Surface::Vertex& v = MeshLoader::refVertex(k);
|
||||
float tu = *coords++;
|
||||
float tv = *coords++;
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = tu;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = tv;
|
||||
}
|
||||
}
|
||||
}else if( *guid==TID_D3DRMMeshVertexColors ){
|
||||
int num_colors=*data++;
|
||||
if( num_colors==num_verts ){
|
||||
for( int k=0;k<num_colors;++k ){
|
||||
Surface::Vertex &v=MeshLoader::refVertex(*data++);
|
||||
float *t=(float*)data;
|
||||
v.color=0xff000000|(int(t[0]*255)<<16)|(int(t[1]*255)<<8)|int(t[2]*255);
|
||||
// v.color=Vector( t[0],t[1],t[2] );
|
||||
data+=4;
|
||||
} else if (*guid == TID_D3DRMMeshVertexColors) {
|
||||
int num_colors = *data++;
|
||||
if (num_colors == num_verts) {
|
||||
for (int k = 0; k < num_colors; ++k) {
|
||||
Surface::Vertex& v = MeshLoader::refVertex(*data++);
|
||||
float* t = (float*)data;
|
||||
v.color = 0xff000000 | (int(t[0] * 255) << 16) | (int(t[1] * 255) << 8) | int(t[2] * 255);
|
||||
// v.color=Vector( t[0],t[1],t[2] );
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
}else if( *guid==TID_D3DRMMeshNormals ){
|
||||
int num_normals=*data++;
|
||||
if( num_normals==num_verts ){
|
||||
Matrix co=conv_tform.m.cofactor();
|
||||
for( int k=0;k<num_normals;++k ){
|
||||
Surface::Vertex &v=MeshLoader::refVertex(k);
|
||||
v.normal=(co * *(Vector*)data).normalized();
|
||||
data+=3;
|
||||
} else if (*guid == TID_D3DRMMeshNormals) {
|
||||
int num_normals = *data++;
|
||||
if (num_normals == num_verts) {
|
||||
Matrix co = conv_tform.m.cofactor();
|
||||
for (int k = 0; k < num_normals; ++k) {
|
||||
Surface::Vertex& v = MeshLoader::refVertex(k);
|
||||
v.normal = (co * *(Vector*)data).normalized();
|
||||
data += 3;
|
||||
}
|
||||
normals=true;
|
||||
normals = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
childData->Release();
|
||||
}
|
||||
if( !mats.size() ) mats.push_back( Brush() );
|
||||
if (!mats.size())
|
||||
mats.push_back(Brush());
|
||||
|
||||
for( size_t k=0;k<faces.size();++k ){
|
||||
const FaceX &f=faces[k];
|
||||
int *data=f.data;
|
||||
int cnt=*data++;if( cnt<3 ) continue;
|
||||
for (size_t k = 0; k < faces.size(); ++k) {
|
||||
const FaceX& f = faces[k];
|
||||
int* data = f.data;
|
||||
int cnt = *data++;
|
||||
if (cnt < 3)
|
||||
continue;
|
||||
int tri[3];
|
||||
tri[0]=data[0];
|
||||
for( int j=2;j<cnt;++j ){
|
||||
tri[1]=data[j-1+flip_tris];
|
||||
tri[2]=data[j-flip_tris];
|
||||
MeshLoader::addTriangle( tri,mats[f.mat_index] );
|
||||
tri[0] = data[0];
|
||||
for (int j = 2; j < cnt; ++j) {
|
||||
tri[1] = data[j - 1 + flip_tris];
|
||||
tri[2] = data[j - flip_tris];
|
||||
MeshLoader::addTriangle(tri, mats[f.mat_index]);
|
||||
}
|
||||
}
|
||||
|
||||
MeshLoader::endMesh( mesh );
|
||||
MeshLoader::endMesh(mesh);
|
||||
|
||||
if( !normals ) mesh->updateNormals();
|
||||
if (!normals)
|
||||
mesh->updateNormals();
|
||||
}
|
||||
|
||||
static MeshModel *parseFrame( IDirectXFileData *fileData ){
|
||||
static MeshModel* parseFrame(IDirectXFileData* fileData)
|
||||
{
|
||||
MeshModel* e = new MeshModel();
|
||||
|
||||
MeshModel *e=new MeshModel();
|
||||
const GUID* guid;
|
||||
IDirectXFileObject* childObj;
|
||||
IDirectXFileData* childData;
|
||||
|
||||
const GUID *guid;
|
||||
IDirectXFileObject *childObj;
|
||||
IDirectXFileData *childData;
|
||||
char name[80];
|
||||
DWORD len = 80;
|
||||
if (fileData->GetName(name, &len) < 0)
|
||||
return e;
|
||||
|
||||
char name[80];DWORD len=80;
|
||||
if( fileData->GetName( name,&len )<0 ) return e;
|
||||
|
||||
e->SetName( name );
|
||||
frames_map[name]=e;
|
||||
e->SetName(name);
|
||||
frames_map[name] = e;
|
||||
|
||||
//iterate through child objects...
|
||||
for( ;fileData->GetNextObject( &childObj )>=0;childObj->Release() ){
|
||||
if( childObj->QueryInterface( IID_IDirectXFileData,(void**)&childData )<0 ) continue;
|
||||
if( childData->GetType( &guid )>=0 ){
|
||||
if( *guid==TID_D3DRMFrameTransformMatrix ){
|
||||
DWORD size;D3DMATRIX *data;
|
||||
if( childData->GetData( 0,&size,(void**)&data )>=0 ){
|
||||
Transform tform=Transform( Matrix(
|
||||
Vector( data->_11,data->_12,data->_13 ),
|
||||
Vector( data->_21,data->_22,data->_23 ),
|
||||
Vector( data->_31,data->_32,data->_33 ) ),
|
||||
Vector( data->_41,data->_42,data->_43 ) );
|
||||
if( conv ) tform=conv_tform * tform * -conv_tform;
|
||||
e->SetLocalTransform( tform );
|
||||
for (; fileData->GetNextObject(&childObj) >= 0; childObj->Release()) {
|
||||
if (childObj->QueryInterface(IID_IDirectXFileData, (void**)&childData) < 0)
|
||||
continue;
|
||||
if (childData->GetType(&guid) >= 0) {
|
||||
if (*guid == TID_D3DRMFrameTransformMatrix) {
|
||||
DWORD size;
|
||||
D3DMATRIX* data;
|
||||
if (childData->GetData(0, &size, (void**)&data) >= 0) {
|
||||
Transform tform = Transform(Matrix(Vector(data->_11, data->_12, data->_13),
|
||||
Vector(data->_21, data->_22, data->_23),
|
||||
Vector(data->_31, data->_32, data->_33)),
|
||||
Vector(data->_41, data->_42, data->_43));
|
||||
if (conv)
|
||||
tform = conv_tform * tform * -conv_tform;
|
||||
e->SetLocalTransform(tform);
|
||||
}
|
||||
}else if( *guid==TID_D3DRMMesh ){
|
||||
if( !animonly ) parseMesh( childData,e );
|
||||
}else if( *guid==TID_D3DRMFrame ){
|
||||
MeshModel *t=parseFrame( childData );
|
||||
t->SetParent( e );
|
||||
} else if (*guid == TID_D3DRMMesh) {
|
||||
if (!animonly)
|
||||
parseMesh(childData, e);
|
||||
} else if (*guid == TID_D3DRMFrame) {
|
||||
MeshModel* t = parseFrame(childData);
|
||||
t->SetParent(e);
|
||||
}
|
||||
}
|
||||
childData->Release();
|
||||
@@ -333,39 +368,45 @@ static MeshModel *parseFrame( IDirectXFileData *fileData ){
|
||||
return e;
|
||||
}
|
||||
|
||||
static MeshModel *parseFile( const string &file ){
|
||||
static MeshModel* parseFile(const string& file)
|
||||
{
|
||||
const GUID* guid;
|
||||
IDirectXFile* xfile;
|
||||
IDirectXFileData* fileData;
|
||||
IDirectXFileEnumObject* enumObj;
|
||||
|
||||
const GUID *guid;
|
||||
IDirectXFile *xfile;
|
||||
IDirectXFileData *fileData;
|
||||
IDirectXFileEnumObject *enumObj;
|
||||
if (DirectXFileCreate(&xfile) < 0)
|
||||
return 0;
|
||||
|
||||
if( DirectXFileCreate( &xfile )<0 ) return 0;
|
||||
|
||||
if( xfile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,D3DRM_XTEMPLATE_BYTES )<0 ){
|
||||
xfile->Release();return 0;
|
||||
if (xfile->RegisterTemplates((VOID*)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES) < 0) {
|
||||
xfile->Release();
|
||||
return 0;
|
||||
}
|
||||
if( xfile->CreateEnumObject( (void*)file.c_str(),DXFILELOAD_FROMFILE,&enumObj )<0 ){
|
||||
xfile->Release();return 0;
|
||||
if (xfile->CreateEnumObject((void*)file.c_str(), DXFILELOAD_FROMFILE, &enumObj) < 0) {
|
||||
xfile->Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
anim_len=0;
|
||||
MeshModel *e=new MeshModel();
|
||||
for( ;enumObj->GetNextDataObject( &fileData )>=0;fileData->Release() ){
|
||||
if( fileData->GetType( &guid )<0 ) continue;
|
||||
anim_len = 0;
|
||||
MeshModel* e = new MeshModel();
|
||||
for (; enumObj->GetNextDataObject(&fileData) >= 0; fileData->Release()) {
|
||||
if (fileData->GetType(&guid) < 0)
|
||||
continue;
|
||||
|
||||
if( *guid==TID_D3DRMMesh ){
|
||||
if( !animonly) parseMesh( fileData,e );
|
||||
}else if( *guid==TID_D3DRMFrame ){
|
||||
MeshModel *t=parseFrame( fileData );
|
||||
t->SetParent( e );
|
||||
}else if( *guid==TID_D3DRMAnimationSet ){
|
||||
if( !collapse ) parseAnimSet( fileData );
|
||||
if (*guid == TID_D3DRMMesh) {
|
||||
if (!animonly)
|
||||
parseMesh(fileData, e);
|
||||
} else if (*guid == TID_D3DRMFrame) {
|
||||
MeshModel* t = parseFrame(fileData);
|
||||
t->SetParent(e);
|
||||
} else if (*guid == TID_D3DRMAnimationSet) {
|
||||
if (!collapse)
|
||||
parseAnimSet(fileData);
|
||||
}
|
||||
}
|
||||
|
||||
if( !collapse ){
|
||||
e->setAnimator( new Animator( e,anim_len ) );
|
||||
if (!collapse) {
|
||||
e->setAnimator(new Animator(e, anim_len));
|
||||
}
|
||||
|
||||
enumObj->Release();
|
||||
@@ -373,17 +414,19 @@ static MeshModel *parseFile( const string &file ){
|
||||
return e;
|
||||
}
|
||||
|
||||
MeshModel *Loader_X::load( const string &filename,const Transform &t,int hint ){
|
||||
conv_tform=t;
|
||||
conv=flip_tris=false;
|
||||
if( conv_tform!=Transform() ){
|
||||
conv=true;
|
||||
if( conv_tform.m.i.cross(conv_tform.m.j).dot(conv_tform.m.k)<0 ) flip_tris=true;
|
||||
MeshModel* Loader_X::load(const string& filename, const Transform& t, int hint)
|
||||
{
|
||||
conv_tform = t;
|
||||
conv = flip_tris = false;
|
||||
if (conv_tform != Transform()) {
|
||||
conv = true;
|
||||
if (conv_tform.m.i.cross(conv_tform.m.j).dot(conv_tform.m.k) < 0)
|
||||
flip_tris = true;
|
||||
}
|
||||
collapse=!!(hint&MeshLoader::HINT_COLLAPSE);
|
||||
animonly=!!(hint&MeshLoader::HINT_ANIMONLY);
|
||||
collapse = !!(hint & MeshLoader::HINT_COLLAPSE);
|
||||
animonly = !!(hint & MeshLoader::HINT_ANIMONLY);
|
||||
|
||||
MeshModel *e=parseFile( filename );
|
||||
MeshModel* e = parseFile(filename);
|
||||
frames_map.clear();
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "meshloader.hpp"
|
||||
|
||||
class Loader_X : public MeshLoader{
|
||||
public:
|
||||
MeshModel *load( const string &f,const Transform &conv,int hint );
|
||||
class Loader_X : public MeshLoader {
|
||||
public:
|
||||
MeshModel* load(const string& f, const Transform& conv, int hint);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,129 +1,145 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "md2rep.hpp"
|
||||
#include "md2model.hpp"
|
||||
#include "md2rep.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
struct MD2Model::Rep : public MD2Rep{
|
||||
struct MD2Model::Rep : public MD2Rep {
|
||||
int ref_cnt;
|
||||
|
||||
Rep( const string &f):MD2Rep( f ),
|
||||
ref_cnt(1){
|
||||
}
|
||||
Rep(const string& f) : MD2Rep(f), ref_cnt(1) {}
|
||||
};
|
||||
|
||||
MD2Model::MD2Model( const string &f ):
|
||||
rep( new Rep( f ) ),
|
||||
anim_mode(0),anim_time(0),
|
||||
render_a(0),render_b(0),render_t(0),trans_verts(0){
|
||||
}
|
||||
MD2Model::MD2Model(const string& f)
|
||||
: rep(new Rep(f)), anim_mode(0), anim_time(0), render_a(0), render_b(0), render_t(0), trans_verts(0)
|
||||
{}
|
||||
|
||||
MD2Model::MD2Model( const MD2Model &t ):
|
||||
Model(t),rep( t.rep ),
|
||||
anim_mode(0),anim_time(0),
|
||||
render_a(0),render_b(0),render_t(0),trans_verts(0){
|
||||
MD2Model::MD2Model(const MD2Model& t)
|
||||
: Model(t), rep(t.rep), anim_mode(0), anim_time(0), render_a(0), render_b(0), render_t(0), trans_verts(0)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
|
||||
MD2Model::~MD2Model(){
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
if( trans_verts ) delete[] trans_verts;
|
||||
MD2Model::~MD2Model()
|
||||
{
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
if (trans_verts)
|
||||
delete[] trans_verts;
|
||||
}
|
||||
|
||||
void MD2Model::startMD2Anim( int first,int last,int mode,float speed,float trans ){
|
||||
void MD2Model::startMD2Anim(int first, int last, int mode, float speed, float trans)
|
||||
{
|
||||
if (last < first)
|
||||
std::swap(first, last);
|
||||
|
||||
if( last<first ) std::swap( first,last );
|
||||
if (first < 0)
|
||||
first = 0;
|
||||
else if (first >= rep->numFrames())
|
||||
first = rep->numFrames() - 1;
|
||||
|
||||
if( first<0 ) first=0;
|
||||
else if( first>=rep->numFrames() ) first=rep->numFrames()-1;
|
||||
if (last < 0)
|
||||
last = 0;
|
||||
else if (last >= rep->numFrames())
|
||||
last = rep->numFrames() - 1;
|
||||
|
||||
if( last<0 ) last=0;
|
||||
else if( last>=rep->numFrames() ) last=rep->numFrames()-1;
|
||||
if (trans > 0) {
|
||||
if (!trans_verts)
|
||||
trans_verts = new MD2Rep::Vert[rep->numVertices()];
|
||||
|
||||
if( trans>0 ){
|
||||
if( !trans_verts ) trans_verts=new MD2Rep::Vert[rep->numVertices()];
|
||||
|
||||
if( anim_mode & 0x8000 ) rep->render( trans_verts,anim_time,trans_time );
|
||||
else rep->render( trans_verts,render_a,render_b,render_t );
|
||||
trans_speed=1.0f/trans;
|
||||
trans_time=0;
|
||||
mode|=0x8000;
|
||||
if (anim_mode & 0x8000)
|
||||
rep->render(trans_verts, anim_time, trans_time);
|
||||
else
|
||||
rep->render(trans_verts, render_a, render_b, render_t);
|
||||
trans_speed = 1.0f / trans;
|
||||
trans_time = 0;
|
||||
mode |= 0x8000;
|
||||
}
|
||||
|
||||
anim_first=first;
|
||||
anim_last=last;
|
||||
anim_len=last-first;
|
||||
anim_speed=speed;
|
||||
anim_time=((mode&0x7fff)==Animator::ANIM_MODE_LOOP || anim_speed>=0) ? anim_first : anim_last;
|
||||
anim_mode=mode;
|
||||
anim_first = first;
|
||||
anim_last = last;
|
||||
anim_len = last - first;
|
||||
anim_speed = speed;
|
||||
anim_time = ((mode & 0x7fff) == Animator::ANIM_MODE_LOOP || anim_speed >= 0) ? anim_first : anim_last;
|
||||
anim_mode = mode;
|
||||
|
||||
if( !anim_speed || !anim_len ){
|
||||
render_a=render_b=anim_time;
|
||||
render_t=0;
|
||||
anim_mode&=0x8000;
|
||||
if (!anim_speed || !anim_len) {
|
||||
render_a = render_b = anim_time;
|
||||
render_t = 0;
|
||||
anim_mode &= 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
void MD2Model::animate( float e ){
|
||||
Model::animate( e );
|
||||
if( !anim_mode ) return;
|
||||
if( anim_mode & 0x8000 ){
|
||||
trans_time+=trans_speed;
|
||||
if( trans_time<1 ) return;
|
||||
anim_mode&=~0x8000;
|
||||
if( !anim_mode ) return;
|
||||
void MD2Model::animate(float e)
|
||||
{
|
||||
Model::animate(e);
|
||||
if (!anim_mode)
|
||||
return;
|
||||
if (anim_mode & 0x8000) {
|
||||
trans_time += trans_speed;
|
||||
if (trans_time < 1)
|
||||
return;
|
||||
anim_mode &= ~0x8000;
|
||||
if (!anim_mode)
|
||||
return;
|
||||
}
|
||||
anim_time=anim_time+anim_speed * e;
|
||||
if( anim_time<anim_first ){
|
||||
switch( anim_mode ){
|
||||
anim_time = anim_time + anim_speed * e;
|
||||
if (anim_time < anim_first) {
|
||||
switch (anim_mode) {
|
||||
case Animator::ANIM_MODE_LOOP:
|
||||
anim_time+=anim_len;
|
||||
anim_time += anim_len;
|
||||
break;
|
||||
case Animator::ANIM_MODE_PINGPONG:
|
||||
anim_time=anim_first+(anim_first-anim_time);
|
||||
anim_speed=-anim_speed;
|
||||
anim_time = anim_first + (anim_first - anim_time);
|
||||
anim_speed = -anim_speed;
|
||||
break;
|
||||
default:
|
||||
anim_time=anim_first;
|
||||
anim_mode=0;
|
||||
anim_time = anim_first;
|
||||
anim_mode = 0;
|
||||
break;
|
||||
}
|
||||
}else if( anim_time>=anim_last ){
|
||||
switch( anim_mode ){
|
||||
} else if (anim_time >= anim_last) {
|
||||
switch (anim_mode) {
|
||||
case Animator::ANIM_MODE_LOOP:
|
||||
anim_time-=anim_len;
|
||||
anim_time -= anim_len;
|
||||
break;
|
||||
case Animator::ANIM_MODE_PINGPONG:
|
||||
anim_time=anim_last-(anim_time-anim_last);
|
||||
anim_speed=-anim_speed;
|
||||
anim_time = anim_last - (anim_time - anim_last);
|
||||
anim_speed = -anim_speed;
|
||||
break;
|
||||
default:
|
||||
anim_time=anim_last;
|
||||
anim_mode=0;
|
||||
anim_time = anim_last;
|
||||
anim_mode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
render_a=floor(anim_time);render_b=render_a+1;
|
||||
if( anim_mode==Animator::ANIM_MODE_LOOP && render_b==anim_last ) render_b=anim_first;
|
||||
render_t=anim_time-render_a;
|
||||
render_a = floor(anim_time);
|
||||
render_b = render_a + 1;
|
||||
if (anim_mode == Animator::ANIM_MODE_LOOP && render_b == anim_last)
|
||||
render_b = anim_first;
|
||||
render_t = anim_time - render_a;
|
||||
}
|
||||
|
||||
bool MD2Model::render( const RenderContext &rc ){
|
||||
bool MD2Model::render(const RenderContext& rc)
|
||||
{
|
||||
static Frustum f;
|
||||
new( &f ) Frustum( rc.getWorldFrustum(),-getRenderTform() );
|
||||
if( !f.cull( rep->getBox() ) ) return false;
|
||||
new (&f) Frustum(rc.getWorldFrustum(), -getRenderTform());
|
||||
if (!f.cull(rep->getBox()))
|
||||
return false;
|
||||
|
||||
if( anim_mode & 0x8000 ){
|
||||
rep->render( this,trans_verts,anim_time,trans_time );
|
||||
}else{
|
||||
rep->render( this,render_a,render_b,render_t );
|
||||
if (anim_mode & 0x8000) {
|
||||
rep->render(this, trans_verts, anim_time, trans_time);
|
||||
} else {
|
||||
rep->render(this, render_a, render_b, render_t);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int MD2Model::getMD2AnimLength()const{
|
||||
int MD2Model::getMD2AnimLength() const
|
||||
{
|
||||
return rep->numFrames();
|
||||
}
|
||||
|
||||
bool MD2Model::getValid()const{
|
||||
return rep->numFrames()>0;
|
||||
bool MD2Model::getValid() const
|
||||
{
|
||||
return rep->numFrames() > 0;
|
||||
}
|
||||
|
||||
@@ -2,50 +2,62 @@
|
||||
#ifndef MD2MODEL_H
|
||||
#define MD2MODEL_H
|
||||
|
||||
#include "model.hpp"
|
||||
#include "md2rep.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
class MD2Model : public Model{
|
||||
public:
|
||||
MD2Model( const string &filename );
|
||||
MD2Model( const MD2Model &t );
|
||||
class MD2Model : public Model {
|
||||
public:
|
||||
MD2Model(const string& filename);
|
||||
MD2Model(const MD2Model& t);
|
||||
~MD2Model();
|
||||
|
||||
//Entity interface
|
||||
Entity *clone(){ return new MD2Model( *this ); }
|
||||
MD2Model *getMD2Model(){ return this; }
|
||||
Entity* clone()
|
||||
{
|
||||
return new MD2Model(*this);
|
||||
}
|
||||
MD2Model* getMD2Model()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
//Object interface
|
||||
void animate( float elapsed );
|
||||
void animate(float elapsed);
|
||||
|
||||
//Model interface
|
||||
bool render( const RenderContext &rc );
|
||||
bool render(const RenderContext& rc);
|
||||
|
||||
//MD2 interface
|
||||
void startMD2Anim( int first,int last,int mode,float speed,float trans );
|
||||
void startMD2Anim(int first, int last, int mode, float speed, float trans);
|
||||
|
||||
int getMD2AnimLength()const;
|
||||
bool getMD2Animating()const{ return !!anim_mode; }
|
||||
float getMD2AnimTime()const{ return anim_time; }
|
||||
int getMD2AnimLength() const;
|
||||
bool getMD2Animating() const
|
||||
{
|
||||
return !!anim_mode;
|
||||
}
|
||||
float getMD2AnimTime() const
|
||||
{
|
||||
return anim_time;
|
||||
}
|
||||
|
||||
bool getValid()const;
|
||||
bool getValid() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Rep;
|
||||
Rep *rep;
|
||||
Rep* rep;
|
||||
|
||||
int anim_mode;
|
||||
float anim_time,anim_speed;
|
||||
int anim_first,anim_last,anim_len;
|
||||
float anim_time, anim_speed;
|
||||
int anim_first, anim_last, anim_len;
|
||||
|
||||
float render_t;
|
||||
int render_a,render_b;
|
||||
int render_a, render_b;
|
||||
|
||||
float trans_time,trans_speed;
|
||||
MD2Rep::Vert *trans_verts;
|
||||
float trans_time, trans_speed;
|
||||
MD2Rep::Vert* trans_verts;
|
||||
|
||||
//Unimplemented
|
||||
MD2Model &operator=( const MD2Model & );
|
||||
MD2Model& operator=(const MD2Model&);
|
||||
};
|
||||
|
||||
#endif
|
||||
+287
-256
@@ -1,17 +1,16 @@
|
||||
|
||||
#include "std.h"
|
||||
#include "md2model.h"
|
||||
#include "md2norms.h"
|
||||
#include "std.h"
|
||||
|
||||
static Vector *normals;
|
||||
static float white[]={1,1,1};
|
||||
static Vector* normals;
|
||||
static float white[] = {1, 1, 1};
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxRuntime* gx_runtime;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
struct MD2Model::Rep{
|
||||
|
||||
struct md2_header{
|
||||
struct MD2Model::Rep {
|
||||
struct md2_header {
|
||||
int magic;
|
||||
int version;
|
||||
int skinWidth;
|
||||
@@ -31,144 +30,147 @@ struct MD2Model::Rep{
|
||||
int offsetEnd;
|
||||
};
|
||||
|
||||
struct md2_vertex{
|
||||
unsigned char x,y,z,n;
|
||||
struct md2_vertex {
|
||||
unsigned char x, y, z, n;
|
||||
};
|
||||
|
||||
struct md2_texcoord{
|
||||
unsigned short s,t;
|
||||
struct md2_texcoord {
|
||||
unsigned short s, t;
|
||||
};
|
||||
|
||||
struct md2_triangle{
|
||||
unsigned short verts[3],tex_coords[3];
|
||||
struct md2_triangle {
|
||||
unsigned short verts[3], tex_coords[3];
|
||||
};
|
||||
|
||||
struct Frame{
|
||||
Vector scale,trans;
|
||||
struct Frame {
|
||||
Vector scale, trans;
|
||||
vector<md2_vertex> verts;
|
||||
};
|
||||
|
||||
struct TexCoords{
|
||||
float u,v;
|
||||
struct TexCoords {
|
||||
float u, v;
|
||||
};
|
||||
|
||||
int ref_cnt;
|
||||
|
||||
int num_verts,num_frames;
|
||||
int num_verts, num_frames;
|
||||
|
||||
vector<Frame> frames;
|
||||
vector<TexCoords> tex_coords;
|
||||
gxMesh *mesh;
|
||||
gxMesh* mesh;
|
||||
|
||||
Box box;
|
||||
|
||||
ModelModel::Rep( const string &file ):
|
||||
ref_cnt(1),mesh(0){
|
||||
|
||||
ModelModel::Rep(const string& file) : ref_cnt(1), mesh(0)
|
||||
{
|
||||
filebuf in;
|
||||
Header header;
|
||||
|
||||
if( !in.open( file.c_str(),ios_base::in|ios_base::binary ) ) return;
|
||||
if( in.sgetn( (char*)&header,sizeof(header) )!=sizeof(header) ) return;
|
||||
if( header.magic!='2PDI' || header.version!=8 ) return;
|
||||
if (!in.open(file.c_str(), ios_base::in | ios_base::binary))
|
||||
return;
|
||||
if (in.sgetn((char*)&header, sizeof(header)) != sizeof(header))
|
||||
return;
|
||||
if (header.magic != '2PDI' || header.version != 8)
|
||||
return;
|
||||
|
||||
//read tex coords
|
||||
in.pubseekpos( header.offsetTexCoords );
|
||||
TexCoord *coords=d_new TexCoord[header.numTexCoords];
|
||||
in.sgetn( (char*)coords,header.numTexCoords*sizeof(TexCoord) );
|
||||
in.pubseekpos(header.offsetTexCoords);
|
||||
TexCoord* coords = d_new TexCoord[header.numTexCoords];
|
||||
in.sgetn((char*)coords, header.numTexCoords * sizeof(TexCoord));
|
||||
|
||||
vector<VertInfo> verts;
|
||||
map<VertInfo,int> info_map;
|
||||
map<VertInfo, int> info_map;
|
||||
|
||||
//build triangles
|
||||
vector<Triangle> triangles;
|
||||
in.pubseekpos( header.offsetTriangles );
|
||||
triangles.resize( header.numTriangles );
|
||||
for( k=0;k<triangles.size();++k ){
|
||||
unsigned short v[3],t[3];
|
||||
in.sgetn( (char*)v,6 );
|
||||
in.sgetn( (char*)t,6 );
|
||||
for( int j=0;j<3;++j ){
|
||||
unsigned char tu=coords[ t[j] ].s*256.0f/header.skinWidth;
|
||||
unsigned char tv=coords[ t[j] ].t*256.0f/header.skinHeight;
|
||||
VertInfo i( v[j],tu,tv );
|
||||
map<VertInfo,int>::iterator it=info_map.find( i );
|
||||
if( it==info_map.end() ){
|
||||
info_map[i]=triangles[k].v[j]=verts.size();
|
||||
verts.push_back( i );
|
||||
}else{
|
||||
triangles[k].v[j]=it->second;
|
||||
in.pubseekpos(header.offsetTriangles);
|
||||
triangles.resize(header.numTriangles);
|
||||
for (k = 0; k < triangles.size(); ++k) {
|
||||
unsigned short v[3], t[3];
|
||||
in.sgetn((char*)v, 6);
|
||||
in.sgetn((char*)t, 6);
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
unsigned char tu = coords[t[j]].s * 256.0f / header.skinWidth;
|
||||
unsigned char tv = coords[t[j]].t * 256.0f / header.skinHeight;
|
||||
VertInfo i(v[j], tu, tv);
|
||||
map<VertInfo, int>::iterator it = info_map.find(i);
|
||||
if (it == info_map.end()) {
|
||||
info_map[i] = triangles[k].v[j] = verts.size();
|
||||
verts.push_back(i);
|
||||
} else {
|
||||
triangles[k].v[j] = it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete coords;
|
||||
|
||||
//load frames
|
||||
string tt="MD2 Frames:"+itoa( header.numFrames );
|
||||
gx_runtime->debugLog( tt.c_str() );
|
||||
string tt = "MD2 Frames:" + itoa(header.numFrames);
|
||||
gx_runtime->debugLog(tt.c_str());
|
||||
|
||||
in.pubseekpos( header.offsetFrames );
|
||||
frames.resize( header.numFrames );
|
||||
MD2Vertex *md2_verts=d_new MD2Vertex[header.numVertices];
|
||||
in.pubseekpos(header.offsetFrames);
|
||||
frames.resize(header.numFrames);
|
||||
MD2Vertex* md2_verts = d_new MD2Vertex[header.numVertices];
|
||||
|
||||
for( k=0;k<frames.size();++k ){
|
||||
|
||||
Frame &frame=frames[k];
|
||||
for (k = 0; k < frames.size(); ++k) {
|
||||
Frame& frame = frames[k];
|
||||
|
||||
//read frame header;
|
||||
in.sgetn( (char*)&frame.scale,12 );
|
||||
in.sgetn( (char*)&frame.trans,12 );
|
||||
in.sgetn( frame.name,16 );
|
||||
in.sgetn((char*)&frame.scale, 12);
|
||||
in.sgetn((char*)&frame.trans, 12);
|
||||
in.sgetn(frame.name, 16);
|
||||
|
||||
frame.trans=Vector(frame.trans.y,frame.trans.z,frame.trans.x);
|
||||
frame.scale=Vector(frame.scale.y,frame.scale.z,frame.scale.x);
|
||||
frame.trans = Vector(frame.trans.y, frame.trans.z, frame.trans.x);
|
||||
frame.scale = Vector(frame.scale.y, frame.scale.z, frame.scale.x);
|
||||
|
||||
//read frame verts...
|
||||
in.sgetn( (char*)md2_verts,header.numVertices*4 );
|
||||
in.sgetn((char*)md2_verts, header.numVertices * 4);
|
||||
|
||||
frame.vertices.resize( verts.size() );
|
||||
for( int j=0;j<verts.size();++j ){
|
||||
Vertex &v=frame.vertices[j];
|
||||
const VertInfo &i=verts[j];
|
||||
const MD2Vertex &m=md2_verts[i.index];
|
||||
v.x=m.y;v.y=m.z;v.z=m.x;
|
||||
v.u=i.u;v.v=i.v;v.n=m.n;
|
||||
frame.vertices.resize(verts.size());
|
||||
for (int j = 0; j < verts.size(); ++j) {
|
||||
Vertex& v = frame.vertices[j];
|
||||
const VertInfo& i = verts[j];
|
||||
const MD2Vertex& m = md2_verts[i.index];
|
||||
v.x = m.y;
|
||||
v.y = m.z;
|
||||
v.z = m.x;
|
||||
v.u = i.u;
|
||||
v.v = i.v;
|
||||
v.n = m.n;
|
||||
}
|
||||
}
|
||||
delete md2_verts;
|
||||
|
||||
//create initial mesh
|
||||
mesh=gx_graphics->createMesh( verts.size(),triangles.size(),0 );
|
||||
mesh = gx_graphics->createMesh(verts.size(), triangles.size(), 0);
|
||||
mesh->lock();
|
||||
for( k=0;k<triangles.size();++k ){
|
||||
const Triangle &t=triangles[k];
|
||||
mesh->setTriangle( k,t.v[0],t.v[2],t.v[1] );
|
||||
for (k = 0; k < triangles.size(); ++k) {
|
||||
const Triangle& t = triangles[k];
|
||||
mesh->setTriangle(k, t.v[0], t.v[2], t.v[1]);
|
||||
}
|
||||
mesh->unlock();
|
||||
|
||||
//calculate bounding box.
|
||||
for( k=0;k<header.numFrames;++k ){
|
||||
const Frame &frame=frames[k];
|
||||
const Vector &scale=frame.scale;
|
||||
const Vector &trans=frame.trans;
|
||||
for( int n=0;n<frame.vertices.size();++n ){
|
||||
const Vertex &v=frame.vertices[n];
|
||||
box.update( Vector( v.x,v.y,v.z ) * scale + trans );
|
||||
for (k = 0; k < header.numFrames; ++k) {
|
||||
const Frame& frame = frames[k];
|
||||
const Vector& scale = frame.scale;
|
||||
const Vector& trans = frame.trans;
|
||||
for (int n = 0; n < frame.vertices.size(); ++n) {
|
||||
const Vertex& v = frame.vertices[n];
|
||||
box.update(Vector(v.x, v.y, v.z) * scale + trans);
|
||||
}
|
||||
}
|
||||
|
||||
if( !normals ){
|
||||
normals=(Vector*)md2norms;
|
||||
for( int k=0;k<sizeof(md2norms)/12;++k ){
|
||||
normals[k]=Vector(normals[k].y,normals[k].z,normals[k].x);
|
||||
if (!normals) {
|
||||
normals = (Vector*)md2norms;
|
||||
for (int k = 0; k < sizeof(md2norms) / 12; ++k) {
|
||||
normals[k] = Vector(normals[k].y, normals[k].z, normals[k].x);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
|
||||
#pragma pack( push,1 )
|
||||
|
||||
struct Header{
|
||||
struct Header {
|
||||
int magic;
|
||||
int version;
|
||||
int skinWidth;
|
||||
@@ -188,286 +190,315 @@ struct MD2Model::Rep{
|
||||
int offsetEnd;
|
||||
};
|
||||
|
||||
struct MD2Vertex{
|
||||
unsigned char x,y,z,n;
|
||||
struct MD2Vertex {
|
||||
unsigned char x, y, z, n;
|
||||
};
|
||||
|
||||
struct Vertex{
|
||||
unsigned char x,y,z,u,v,n;
|
||||
struct Vertex {
|
||||
unsigned char x, y, z, u, v, n;
|
||||
};
|
||||
|
||||
struct Triangle{
|
||||
struct Triangle {
|
||||
unsigned short v[3]; //index into vertices
|
||||
};
|
||||
|
||||
struct Frame{
|
||||
struct Frame {
|
||||
Vector scale;
|
||||
Vector trans;
|
||||
char name[16];
|
||||
vector<Vertex> vertices;
|
||||
};
|
||||
|
||||
struct TexCoord{
|
||||
short s,t;
|
||||
struct TexCoord {
|
||||
short s, t;
|
||||
};
|
||||
|
||||
struct VertInfo{
|
||||
struct VertInfo {
|
||||
unsigned short index;
|
||||
unsigned char u,v;
|
||||
VertInfo( unsigned short i,char u,char v ):index(i),u(u),v(v){
|
||||
}
|
||||
bool operator<( const VertInfo &t )const{
|
||||
if( index<t.index ) return true;
|
||||
if( t.index<index ) return false;
|
||||
if( u<t.u ) return true;
|
||||
if( t.u<u ) return false;
|
||||
return v<t.v;
|
||||
unsigned char u, v;
|
||||
VertInfo(unsigned short i, char u, char v) : index(i), u(u), v(v) {}
|
||||
bool operator<(const VertInfo& t) const
|
||||
{
|
||||
if (index < t.index)
|
||||
return true;
|
||||
if (t.index < index)
|
||||
return false;
|
||||
if (u < t.u)
|
||||
return true;
|
||||
if (t.u < u)
|
||||
return false;
|
||||
return v < t.v;
|
||||
}
|
||||
};
|
||||
|
||||
#pragma pack( pop )
|
||||
#pragma pack(pop)
|
||||
|
||||
int ref_cnt;
|
||||
Header header;
|
||||
vector<Frame> frames;
|
||||
gxMesh *mesh;
|
||||
gxMesh* mesh;
|
||||
Box box;
|
||||
|
||||
Rep( const string &file );
|
||||
Rep(const string& file);
|
||||
~Rep();
|
||||
|
||||
void render( MD2Model *model,float render_t,int render_a,int render_b );
|
||||
};
|
||||
|
||||
MD2Model::Rep::Rep( const string &file ):
|
||||
ref_cnt(1),mesh(0){
|
||||
void render(MD2Model * model, float render_t, int render_a, int render_b);
|
||||
};
|
||||
|
||||
MD2Model::Rep::Rep(const string& file) : ref_cnt(1), mesh(0)
|
||||
{
|
||||
filebuf in;
|
||||
if( !in.open( file.c_str(),ios_base::in|ios_base::binary ) ){
|
||||
if (!in.open(file.c_str(), ios_base::in | ios_base::binary)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( in.sgetn( (char*)&header,sizeof(header) )!=sizeof(header) ){
|
||||
if (in.sgetn((char*)&header, sizeof(header)) != sizeof(header)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( header.magic!='2PDI' || header.version!=8 ){
|
||||
if (header.magic != '2PDI' || header.version != 8) {
|
||||
return;
|
||||
}
|
||||
|
||||
int k;
|
||||
|
||||
//read tex coords
|
||||
in.pubseekpos( header.offsetTexCoords );
|
||||
TexCoord *coords=d_new TexCoord[header.numTexCoords];
|
||||
in.sgetn( (char*)coords,header.numTexCoords*sizeof(TexCoord) );
|
||||
in.pubseekpos(header.offsetTexCoords);
|
||||
TexCoord* coords = d_new TexCoord[header.numTexCoords];
|
||||
in.sgetn((char*)coords, header.numTexCoords * sizeof(TexCoord));
|
||||
|
||||
vector<VertInfo> verts;
|
||||
map<VertInfo,int> info_map;
|
||||
map<VertInfo, int> info_map;
|
||||
|
||||
//build triangles
|
||||
vector<Triangle> triangles;
|
||||
in.pubseekpos( header.offsetTriangles );
|
||||
triangles.resize( header.numTriangles );
|
||||
for( k=0;k<triangles.size();++k ){
|
||||
unsigned short v[3],t[3];
|
||||
in.sgetn( (char*)v,6 );
|
||||
in.sgetn( (char*)t,6 );
|
||||
for( int j=0;j<3;++j ){
|
||||
unsigned char tu=coords[ t[j] ].s*256.0f/header.skinWidth;
|
||||
unsigned char tv=coords[ t[j] ].t*256.0f/header.skinHeight;
|
||||
VertInfo i( v[j],tu,tv );
|
||||
map<VertInfo,int>::iterator it=info_map.find( i );
|
||||
if( it==info_map.end() ){
|
||||
info_map[i]=triangles[k].v[j]=verts.size();
|
||||
verts.push_back( i );
|
||||
}else{
|
||||
triangles[k].v[j]=it->second;
|
||||
in.pubseekpos(header.offsetTriangles);
|
||||
triangles.resize(header.numTriangles);
|
||||
for (k = 0; k < triangles.size(); ++k) {
|
||||
unsigned short v[3], t[3];
|
||||
in.sgetn((char*)v, 6);
|
||||
in.sgetn((char*)t, 6);
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
unsigned char tu = coords[t[j]].s * 256.0f / header.skinWidth;
|
||||
unsigned char tv = coords[t[j]].t * 256.0f / header.skinHeight;
|
||||
VertInfo i(v[j], tu, tv);
|
||||
map<VertInfo, int>::iterator it = info_map.find(i);
|
||||
if (it == info_map.end()) {
|
||||
info_map[i] = triangles[k].v[j] = verts.size();
|
||||
verts.push_back(i);
|
||||
} else {
|
||||
triangles[k].v[j] = it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete coords;
|
||||
|
||||
//load frames
|
||||
string tt="MD2 Frames:"+itoa( header.numFrames );
|
||||
gx_runtime->debugLog( tt.c_str() );
|
||||
string tt = "MD2 Frames:" + itoa(header.numFrames);
|
||||
gx_runtime->debugLog(tt.c_str());
|
||||
|
||||
in.pubseekpos( header.offsetFrames );
|
||||
frames.resize( header.numFrames );
|
||||
MD2Vertex *md2_verts=d_new MD2Vertex[header.numVertices];
|
||||
in.pubseekpos(header.offsetFrames);
|
||||
frames.resize(header.numFrames);
|
||||
MD2Vertex* md2_verts = d_new MD2Vertex[header.numVertices];
|
||||
|
||||
for( k=0;k<frames.size();++k ){
|
||||
|
||||
Frame &frame=frames[k];
|
||||
for (k = 0; k < frames.size(); ++k) {
|
||||
Frame& frame = frames[k];
|
||||
|
||||
//read frame header;
|
||||
in.sgetn( (char*)&frame.scale,12 );
|
||||
in.sgetn( (char*)&frame.trans,12 );
|
||||
in.sgetn( frame.name,16 );
|
||||
in.sgetn((char*)&frame.scale, 12);
|
||||
in.sgetn((char*)&frame.trans, 12);
|
||||
in.sgetn(frame.name, 16);
|
||||
|
||||
frame.trans=Vector(frame.trans.y,frame.trans.z,frame.trans.x);
|
||||
frame.scale=Vector(frame.scale.y,frame.scale.z,frame.scale.x);
|
||||
frame.trans = Vector(frame.trans.y, frame.trans.z, frame.trans.x);
|
||||
frame.scale = Vector(frame.scale.y, frame.scale.z, frame.scale.x);
|
||||
|
||||
//read frame verts...
|
||||
in.sgetn( (char*)md2_verts,header.numVertices*4 );
|
||||
in.sgetn((char*)md2_verts, header.numVertices * 4);
|
||||
|
||||
frame.vertices.resize( verts.size() );
|
||||
for( int j=0;j<verts.size();++j ){
|
||||
Vertex &v=frame.vertices[j];
|
||||
const VertInfo &i=verts[j];
|
||||
const MD2Vertex &m=md2_verts[i.index];
|
||||
v.x=m.y;v.y=m.z;v.z=m.x;
|
||||
v.u=i.u;v.v=i.v;v.n=m.n;
|
||||
frame.vertices.resize(verts.size());
|
||||
for (int j = 0; j < verts.size(); ++j) {
|
||||
Vertex& v = frame.vertices[j];
|
||||
const VertInfo& i = verts[j];
|
||||
const MD2Vertex& m = md2_verts[i.index];
|
||||
v.x = m.y;
|
||||
v.y = m.z;
|
||||
v.z = m.x;
|
||||
v.u = i.u;
|
||||
v.v = i.v;
|
||||
v.n = m.n;
|
||||
}
|
||||
}
|
||||
delete md2_verts;
|
||||
|
||||
//create initial mesh
|
||||
mesh=gx_graphics->createMesh( verts.size(),triangles.size(),0 );
|
||||
mesh = gx_graphics->createMesh(verts.size(), triangles.size(), 0);
|
||||
mesh->lock();
|
||||
for( k=0;k<triangles.size();++k ){
|
||||
const Triangle &t=triangles[k];
|
||||
mesh->setTriangle( k,t.v[0],t.v[2],t.v[1] );
|
||||
for (k = 0; k < triangles.size(); ++k) {
|
||||
const Triangle& t = triangles[k];
|
||||
mesh->setTriangle(k, t.v[0], t.v[2], t.v[1]);
|
||||
}
|
||||
mesh->unlock();
|
||||
|
||||
//calculate bounding box.
|
||||
for( k=0;k<header.numFrames;++k ){
|
||||
const Frame &frame=frames[k];
|
||||
const Vector &scale=frame.scale;
|
||||
const Vector &trans=frame.trans;
|
||||
for( int n=0;n<frame.vertices.size();++n ){
|
||||
const Vertex &v=frame.vertices[n];
|
||||
box.update( Vector( v.x,v.y,v.z ) * scale + trans );
|
||||
for (k = 0; k < header.numFrames; ++k) {
|
||||
const Frame& frame = frames[k];
|
||||
const Vector& scale = frame.scale;
|
||||
const Vector& trans = frame.trans;
|
||||
for (int n = 0; n < frame.vertices.size(); ++n) {
|
||||
const Vertex& v = frame.vertices[n];
|
||||
box.update(Vector(v.x, v.y, v.z) * scale + trans);
|
||||
}
|
||||
}
|
||||
|
||||
if( !normals ){
|
||||
normals=(Vector*)md2norms;
|
||||
for( int k=0;k<sizeof(md2norms)/12;++k ){
|
||||
normals[k]=Vector(normals[k].y,normals[k].z,normals[k].x);
|
||||
if (!normals) {
|
||||
normals = (Vector*)md2norms;
|
||||
for (int k = 0; k < sizeof(md2norms) / 12; ++k) {
|
||||
normals[k] = Vector(normals[k].y, normals[k].z, normals[k].x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MD2Model::Rep::~Rep(){
|
||||
if( mesh ) gx_graphics->freeMesh( mesh );
|
||||
}
|
||||
MD2Model::Rep::~Rep()
|
||||
{
|
||||
if (mesh)
|
||||
gx_graphics->freeMesh(mesh);
|
||||
}
|
||||
|
||||
void MD2Model::Rep::render( MD2Model *model,float render_t,int render_a,int render_b ){
|
||||
void MD2Model::Rep::render(MD2Model* model, float render_t, int render_a, int render_b)
|
||||
{
|
||||
const Frame& frame_a = frames[render_a];
|
||||
const Vector& scale_a = frame_a.scale;
|
||||
const Vector& trans_a = frame_a.trans;
|
||||
|
||||
const Frame &frame_a=frames[render_a];
|
||||
const Vector &scale_a=frame_a.scale;
|
||||
const Vector &trans_a=frame_a.trans;
|
||||
|
||||
const Frame &frame_b=frames[render_b];
|
||||
const Vector &scale_b=frame_b.scale;
|
||||
const Vector &trans_b=frame_b.trans;
|
||||
const Frame& frame_b = frames[render_b];
|
||||
const Vector& scale_b = frame_b.scale;
|
||||
const Vector& trans_b = frame_b.trans;
|
||||
|
||||
mesh->lock();
|
||||
int k;
|
||||
for( k=0;k<frame_a.vertices.size();++k ){
|
||||
const Vertex &v_a=frame_a.vertices[k];
|
||||
const Vector &n_a=normals[v_a.n];
|
||||
Vector t_a( v_a.x*scale_a.x+trans_a.x,v_a.y*scale_a.y+trans_a.y,v_a.z*scale_a.z+trans_a.z );
|
||||
for (k = 0; k < frame_a.vertices.size(); ++k) {
|
||||
const Vertex& v_a = frame_a.vertices[k];
|
||||
const Vector& n_a = normals[v_a.n];
|
||||
Vector t_a(v_a.x * scale_a.x + trans_a.x, v_a.y * scale_a.y + trans_a.y, v_a.z * scale_a.z + trans_a.z);
|
||||
|
||||
const Vertex &v_b=frame_b.vertices[k];
|
||||
const Vector &n_b=normals[v_b.n];
|
||||
Vector t_b( v_b.x*scale_b.x+trans_b.x,v_b.y*scale_b.y+trans_b.y,v_b.z*scale_b.z+trans_b.z );
|
||||
const Vertex& v_b = frame_b.vertices[k];
|
||||
const Vector& n_b = normals[v_b.n];
|
||||
Vector t_b(v_b.x * scale_b.x + trans_b.x, v_b.y * scale_b.y + trans_b.y, v_b.z * scale_b.z + trans_b.z);
|
||||
|
||||
Vector t=(t_b-t_a)*render_t+t_a;
|
||||
Vector n=(n_b-n_a)*render_t+n_a;
|
||||
float tex_coords[]={ v_a.u/256.0f,v_a.v/256.0f,1,0,0,1 };
|
||||
mesh->setVertex( k,&t.x,&n.x,white,tex_coords );
|
||||
Vector t = (t_b - t_a) * render_t + t_a;
|
||||
Vector n = (n_b - n_a) * render_t + n_a;
|
||||
float tex_coords[] = {v_a.u / 256.0f, v_a.v / 256.0f, 1, 0, 0, 1};
|
||||
mesh->setVertex(k, &t.x, &n.x, white, tex_coords);
|
||||
}
|
||||
mesh->unlock();
|
||||
|
||||
model->enqueue( mesh,0,frame_a.vertices.size(),0,header.numTriangles );
|
||||
}
|
||||
model->enqueue(mesh, 0, frame_a.vertices.size(), 0, header.numTriangles);
|
||||
}
|
||||
|
||||
MD2Model::MD2Model( const string &f ):
|
||||
rep( d_new Rep( f ) ),
|
||||
anim_mode(0),anim_time(0),
|
||||
render_a(0),render_b(0),render_t(0){
|
||||
}
|
||||
MD2Model::MD2Model(const string& f)
|
||||
: rep(d_new Rep(f)), anim_mode(0), anim_time(0), render_a(0), render_b(0), render_t(0)
|
||||
{}
|
||||
|
||||
MD2Model::MD2Model( const MD2Model &t ):
|
||||
Model(t),rep( t.rep ),
|
||||
anim_mode(0),anim_time(0),
|
||||
render_a(0),render_b(0),render_t(0){
|
||||
MD2Model::MD2Model(const MD2Model& t)
|
||||
: Model(t), rep(t.rep), anim_mode(0), anim_time(0), render_a(0), render_b(0), render_t(0)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
MD2Model::~MD2Model(){
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
}
|
||||
MD2Model::~MD2Model()
|
||||
{
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
}
|
||||
|
||||
void MD2Model::startMD2Anim( int first,int last,int mode,float speed ){
|
||||
if( !speed && !mode ){ anim_mode=0;return; }
|
||||
if( first<0 ) first=0;
|
||||
else if( first>=rep->header.numFrames ) first=rep->header.numFrames-1;
|
||||
if( last<0 ) last=0;
|
||||
else if( last>=rep->header.numFrames ) last=rep->header.numFrames-1;
|
||||
if( first==last ){ anim_mode=0;render_a=render_b=first;render_t=0;return; }
|
||||
if( last<first ) std::swap( first,last );
|
||||
anim_first=first;
|
||||
anim_last=last;
|
||||
anim_len=last-first;
|
||||
anim_speed=speed;
|
||||
anim_time=speed>0 ? first : last;
|
||||
anim_mode=mode;
|
||||
}
|
||||
void MD2Model::startMD2Anim(int first, int last, int mode, float speed)
|
||||
{
|
||||
if (!speed && !mode) {
|
||||
anim_mode = 0;
|
||||
return;
|
||||
}
|
||||
if (first < 0)
|
||||
first = 0;
|
||||
else if (first >= rep->header.numFrames)
|
||||
first = rep->header.numFrames - 1;
|
||||
if (last < 0)
|
||||
last = 0;
|
||||
else if (last >= rep->header.numFrames)
|
||||
last = rep->header.numFrames - 1;
|
||||
if (first == last) {
|
||||
anim_mode = 0;
|
||||
render_a = render_b = first;
|
||||
render_t = 0;
|
||||
return;
|
||||
}
|
||||
if (last < first)
|
||||
std::swap(first, last);
|
||||
anim_first = first;
|
||||
anim_last = last;
|
||||
anim_len = last - first;
|
||||
anim_speed = speed;
|
||||
anim_time = speed > 0 ? first : last;
|
||||
anim_mode = mode;
|
||||
}
|
||||
|
||||
void MD2Model::animate( float e ){
|
||||
Model::animate( e );
|
||||
if( !anim_mode ) return;
|
||||
anim_time=anim_time+anim_speed * e;
|
||||
if( anim_time<anim_first ){
|
||||
switch( anim_mode ){
|
||||
void MD2Model::animate(float e)
|
||||
{
|
||||
Model::animate(e);
|
||||
if (!anim_mode)
|
||||
return;
|
||||
anim_time = anim_time + anim_speed * e;
|
||||
if (anim_time < anim_first) {
|
||||
switch (anim_mode) {
|
||||
case ANIM_MODE_LOOP:
|
||||
anim_time+=anim_len;
|
||||
anim_time += anim_len;
|
||||
break;
|
||||
case ANIM_MODE_PINGPONG:
|
||||
anim_time=anim_first+(anim_first-anim_time);
|
||||
anim_speed=-anim_speed;
|
||||
anim_time = anim_first + (anim_first - anim_time);
|
||||
anim_speed = -anim_speed;
|
||||
break;
|
||||
default:
|
||||
anim_time=anim_first;
|
||||
anim_mode=0;
|
||||
anim_time = anim_first;
|
||||
anim_mode = 0;
|
||||
break;
|
||||
}
|
||||
}else if( anim_time>=anim_last ){
|
||||
switch( anim_mode ){
|
||||
} else if (anim_time >= anim_last) {
|
||||
switch (anim_mode) {
|
||||
case ANIM_MODE_LOOP:
|
||||
anim_time-=anim_len;
|
||||
anim_time -= anim_len;
|
||||
break;
|
||||
case ANIM_MODE_PINGPONG:
|
||||
anim_time=anim_last-(anim_time-anim_last);
|
||||
anim_speed=-anim_speed;
|
||||
anim_time = anim_last - (anim_time - anim_last);
|
||||
anim_speed = -anim_speed;
|
||||
break;
|
||||
default:
|
||||
anim_time=anim_last;
|
||||
anim_mode=0;
|
||||
anim_time = anim_last;
|
||||
anim_mode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
render_a=floor(anim_time);render_b=render_a+1;
|
||||
if( anim_mode==ANIM_MODE_LOOP && render_b==anim_last ) render_b=anim_first;
|
||||
render_t=anim_time-render_a;
|
||||
}
|
||||
render_a = floor(anim_time);
|
||||
render_b = render_a + 1;
|
||||
if (anim_mode == ANIM_MODE_LOOP && render_b == anim_last)
|
||||
render_b = anim_first;
|
||||
render_t = anim_time - render_a;
|
||||
}
|
||||
|
||||
void MD2Model::render( const RenderContext &rc ){
|
||||
void MD2Model::render(const RenderContext& rc)
|
||||
{
|
||||
static Frustum f;
|
||||
new( &f ) Frustum( rc.getWorldFrustum(),-getRenderTform() );
|
||||
if( !f.cull( rep->box ) ) return;
|
||||
new (&f) Frustum(rc.getWorldFrustum(), -getRenderTform());
|
||||
if (!f.cull(rep->box))
|
||||
return;
|
||||
|
||||
rep->render( this,render_t,render_a,render_b );
|
||||
}
|
||||
rep->render(this, render_t, render_a, render_b);
|
||||
}
|
||||
|
||||
int MD2Model::getMD2AnimLength()const{
|
||||
int MD2Model::getMD2AnimLength() const
|
||||
{
|
||||
return rep->frames.size();
|
||||
}
|
||||
}
|
||||
|
||||
bool MD2Model::getValid()const{
|
||||
return rep->mesh!=0;
|
||||
}
|
||||
bool MD2Model::getValid() const
|
||||
{
|
||||
return rep->mesh != 0;
|
||||
}
|
||||
|
||||
+56
-164
@@ -1,167 +1,59 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "md2norms.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
float md2norms[162][3]={
|
||||
{-0.525731f, 0.000000f, 0.850651f},
|
||||
{-0.442863f, 0.238856f, 0.864188f},
|
||||
{-0.295242f, 0.000000f, 0.955423f},
|
||||
{-0.309017f, 0.500000f, 0.809017f},
|
||||
{-0.162460f, 0.262866f, 0.951056f},
|
||||
{0.000000f, 0.000000f, 1.000000f},
|
||||
{0.000000f, 0.850651f, 0.525731f},
|
||||
{-0.147621f, 0.716567f, 0.681718f},
|
||||
{0.147621f, 0.716567f, 0.681718f},
|
||||
{0.000000f, 0.525731f, 0.850651f},
|
||||
{0.309017f, 0.500000f, 0.809017f},
|
||||
{0.525731f, 0.000000f, 0.850651f},
|
||||
{0.295242f, 0.000000f, 0.955423f},
|
||||
{0.442863f, 0.238856f, 0.864188f},
|
||||
{0.162460f, 0.262866f, 0.951056f},
|
||||
{-0.681718f, 0.147621f, 0.716567f},
|
||||
{-0.809017f, 0.309017f, 0.500000f},
|
||||
{-0.587785f, 0.425325f, 0.688191f},
|
||||
{-0.850651f, 0.525731f, 0.000000f},
|
||||
{-0.864188f, 0.442863f, 0.238856f},
|
||||
{-0.716567f, 0.681718f, 0.147621f},
|
||||
{-0.688191f, 0.587785f, 0.425325f},
|
||||
{-0.500000f, 0.809017f, 0.309017f},
|
||||
{-0.238856f, 0.864188f, 0.442863f},
|
||||
{-0.425325f, 0.688191f, 0.587785f},
|
||||
{-0.716567f, 0.681718f, -0.147621f},
|
||||
{-0.500000f, 0.809017f, -0.309017f},
|
||||
{-0.525731f, 0.850651f, 0.000000f},
|
||||
{0.000000f, 0.850651f, -0.525731f},
|
||||
{-0.238856f, 0.864188f, -0.442863f},
|
||||
{0.000000f, 0.955423f, -0.295242f},
|
||||
{-0.262866f, 0.951056f, -0.162460f},
|
||||
{0.000000f, 1.000000f, 0.000000f},
|
||||
{0.000000f, 0.955423f, 0.295242f},
|
||||
{-0.262866f, 0.951056f, 0.162460f},
|
||||
{0.238856f, 0.864188f, 0.442863f},
|
||||
{0.262866f, 0.951056f, 0.162460f},
|
||||
{0.500000f, 0.809017f, 0.309017f},
|
||||
{0.238856f, 0.864188f, -0.442863f},
|
||||
{0.262866f, 0.951056f, -0.162460f},
|
||||
{0.500000f, 0.809017f, -0.309017f},
|
||||
{0.850651f, 0.525731f, 0.000000f},
|
||||
{0.716567f, 0.681718f, 0.147621f},
|
||||
{0.716567f, 0.681718f, -0.147621f},
|
||||
{0.525731f, 0.850651f, 0.000000f},
|
||||
{0.425325f, 0.688191f, 0.587785f},
|
||||
{0.864188f, 0.442863f, 0.238856f},
|
||||
{0.688191f, 0.587785f, 0.425325f},
|
||||
{0.809017f, 0.309017f, 0.500000f},
|
||||
{0.681718f, 0.147621f, 0.716567f},
|
||||
{0.587785f, 0.425325f, 0.688191f},
|
||||
{0.955423f, 0.295242f, 0.000000f},
|
||||
{1.000000f, 0.000000f, 0.000000f},
|
||||
{0.951056f, 0.162460f, 0.262866f},
|
||||
{0.850651f, -0.525731f, 0.000000f},
|
||||
{0.955423f, -0.295242f, 0.000000f},
|
||||
{0.864188f, -0.442863f, 0.238856f},
|
||||
{0.951056f, -0.162460f, 0.262866f},
|
||||
{0.809017f, -0.309017f, 0.500000f},
|
||||
{0.681718f, -0.147621f, 0.716567f},
|
||||
{0.850651f, 0.000000f, 0.525731f},
|
||||
{0.864188f, 0.442863f, -0.238856f},
|
||||
{0.809017f, 0.309017f, -0.500000f},
|
||||
{0.951056f, 0.162460f, -0.262866f},
|
||||
{0.525731f, 0.000000f, -0.850651f},
|
||||
{0.681718f, 0.147621f, -0.716567f},
|
||||
{0.681718f, -0.147621f, -0.716567f},
|
||||
{0.850651f, 0.000000f, -0.525731f},
|
||||
{0.809017f, -0.309017f, -0.500000f},
|
||||
{0.864188f, -0.442863f, -0.238856f},
|
||||
{0.951056f, -0.162460f, -0.262866f},
|
||||
{0.147621f, 0.716567f, -0.681718f},
|
||||
{0.309017f, 0.500000f, -0.809017f},
|
||||
{0.425325f, 0.688191f, -0.587785f},
|
||||
{0.442863f, 0.238856f, -0.864188f},
|
||||
{0.587785f, 0.425325f, -0.688191f},
|
||||
{0.688191f, 0.587785f, -0.425325f},
|
||||
{-0.147621f, 0.716567f, -0.681718f},
|
||||
{-0.309017f, 0.500000f, -0.809017f},
|
||||
{0.000000f, 0.525731f, -0.850651f},
|
||||
{-0.525731f, 0.000000f, -0.850651f},
|
||||
{-0.442863f, 0.238856f, -0.864188f},
|
||||
{-0.295242f, 0.000000f, -0.955423f},
|
||||
{-0.162460f, 0.262866f, -0.951056f},
|
||||
{0.000000f, 0.000000f, -1.000000f},
|
||||
{0.295242f, 0.000000f, -0.955423f},
|
||||
{0.162460f, 0.262866f, -0.951056f},
|
||||
{-0.442863f, -0.238856f, -0.864188f},
|
||||
{-0.309017f, -0.500000f, -0.809017f},
|
||||
{-0.162460f, -0.262866f, -0.951056f},
|
||||
{0.000000f, -0.850651f, -0.525731f},
|
||||
{-0.147621f, -0.716567f, -0.681718f},
|
||||
{0.147621f, -0.716567f, -0.681718f},
|
||||
{0.000000f, -0.525731f, -0.850651f},
|
||||
{0.309017f, -0.500000f, -0.809017f},
|
||||
{0.442863f, -0.238856f, -0.864188f},
|
||||
{0.162460f, -0.262866f, -0.951056f},
|
||||
{0.238856f, -0.864188f, -0.442863f},
|
||||
{0.500000f, -0.809017f, -0.309017f},
|
||||
{0.425325f, -0.688191f, -0.587785f},
|
||||
{0.716567f, -0.681718f, -0.147621f},
|
||||
{0.688191f, -0.587785f, -0.425325f},
|
||||
{0.587785f, -0.425325f, -0.688191f},
|
||||
{0.000000f, -0.955423f, -0.295242f},
|
||||
{0.000000f, -1.000000f, 0.000000f},
|
||||
{0.262866f, -0.951056f, -0.162460f},
|
||||
{0.000000f, -0.850651f, 0.525731f},
|
||||
{0.000000f, -0.955423f, 0.295242f},
|
||||
{0.238856f, -0.864188f, 0.442863f},
|
||||
{0.262866f, -0.951056f, 0.162460f},
|
||||
{0.500000f, -0.809017f, 0.309017f},
|
||||
{0.716567f, -0.681718f, 0.147621f},
|
||||
{0.525731f, -0.850651f, 0.000000f},
|
||||
{-0.238856f, -0.864188f, -0.442863f},
|
||||
{-0.500000f, -0.809017f, -0.309017f},
|
||||
{-0.262866f, -0.951056f, -0.162460f},
|
||||
{-0.850651f, -0.525731f, 0.000000f},
|
||||
{-0.716567f, -0.681718f, -0.147621f},
|
||||
{-0.716567f, -0.681718f, 0.147621f},
|
||||
{-0.525731f, -0.850651f, 0.000000f},
|
||||
{-0.500000f, -0.809017f, 0.309017f},
|
||||
{-0.238856f, -0.864188f, 0.442863f},
|
||||
{-0.262866f, -0.951056f, 0.162460f},
|
||||
{-0.864188f, -0.442863f, 0.238856f},
|
||||
{-0.809017f, -0.309017f, 0.500000f},
|
||||
{-0.688191f, -0.587785f, 0.425325f},
|
||||
{-0.681718f, -0.147621f, 0.716567f},
|
||||
{-0.442863f, -0.238856f, 0.864188f},
|
||||
{-0.587785f, -0.425325f, 0.688191f},
|
||||
{-0.309017f, -0.500000f, 0.809017f},
|
||||
{-0.147621f, -0.716567f, 0.681718f},
|
||||
{-0.425325f, -0.688191f, 0.587785f},
|
||||
{-0.162460f, -0.262866f, 0.951056f},
|
||||
{0.442863f, -0.238856f, 0.864188f},
|
||||
{0.162460f, -0.262866f, 0.951056f},
|
||||
{0.309017f, -0.500000f, 0.809017f},
|
||||
{0.147621f, -0.716567f, 0.681718f},
|
||||
{0.000000f, -0.525731f, 0.850651f},
|
||||
{0.425325f, -0.688191f, 0.587785f},
|
||||
{0.587785f, -0.425325f, 0.688191f},
|
||||
{0.688191f, -0.587785f, 0.425325f},
|
||||
{-0.955423f, 0.295242f, 0.000000f},
|
||||
{-0.951056f, 0.162460f, 0.262866f},
|
||||
{-1.000000f, 0.000000f, 0.000000f},
|
||||
{-0.850651f, 0.000000f, 0.525731f},
|
||||
{-0.955423f, -0.295242f, 0.000000f},
|
||||
{-0.951056f, -0.162460f, 0.262866f},
|
||||
{-0.864188f, 0.442863f, -0.238856f},
|
||||
{-0.951056f, 0.162460f, -0.262866f},
|
||||
{-0.809017f, 0.309017f, -0.500000f},
|
||||
{-0.864188f, -0.442863f, -0.238856f},
|
||||
{-0.951056f, -0.162460f, -0.262866f},
|
||||
{-0.809017f, -0.309017f, -0.500000f},
|
||||
{-0.681718f, 0.147621f, -0.716567f},
|
||||
{-0.681718f, -0.147621f, -0.716567f},
|
||||
{-0.850651f, 0.000000f, -0.525731f},
|
||||
{-0.688191f, 0.587785f, -0.425325f},
|
||||
{-0.587785f, 0.425325f, -0.688191f},
|
||||
{-0.425325f, 0.688191f, -0.587785f},
|
||||
{-0.425325f, -0.688191f, -0.587785f},
|
||||
{-0.587785f, -0.425325f, -0.688191f},
|
||||
{-0.688191f, -0.587785f, -0.425325f} };
|
||||
float md2norms[162][3] = {
|
||||
{-0.525731f, 0.000000f, 0.850651f}, {-0.442863f, 0.238856f, 0.864188f}, {-0.295242f, 0.000000f, 0.955423f},
|
||||
{-0.309017f, 0.500000f, 0.809017f}, {-0.162460f, 0.262866f, 0.951056f}, {0.000000f, 0.000000f, 1.000000f},
|
||||
{0.000000f, 0.850651f, 0.525731f}, {-0.147621f, 0.716567f, 0.681718f}, {0.147621f, 0.716567f, 0.681718f},
|
||||
{0.000000f, 0.525731f, 0.850651f}, {0.309017f, 0.500000f, 0.809017f}, {0.525731f, 0.000000f, 0.850651f},
|
||||
{0.295242f, 0.000000f, 0.955423f}, {0.442863f, 0.238856f, 0.864188f}, {0.162460f, 0.262866f, 0.951056f},
|
||||
{-0.681718f, 0.147621f, 0.716567f}, {-0.809017f, 0.309017f, 0.500000f}, {-0.587785f, 0.425325f, 0.688191f},
|
||||
{-0.850651f, 0.525731f, 0.000000f}, {-0.864188f, 0.442863f, 0.238856f}, {-0.716567f, 0.681718f, 0.147621f},
|
||||
{-0.688191f, 0.587785f, 0.425325f}, {-0.500000f, 0.809017f, 0.309017f}, {-0.238856f, 0.864188f, 0.442863f},
|
||||
{-0.425325f, 0.688191f, 0.587785f}, {-0.716567f, 0.681718f, -0.147621f}, {-0.500000f, 0.809017f, -0.309017f},
|
||||
{-0.525731f, 0.850651f, 0.000000f}, {0.000000f, 0.850651f, -0.525731f}, {-0.238856f, 0.864188f, -0.442863f},
|
||||
{0.000000f, 0.955423f, -0.295242f}, {-0.262866f, 0.951056f, -0.162460f}, {0.000000f, 1.000000f, 0.000000f},
|
||||
{0.000000f, 0.955423f, 0.295242f}, {-0.262866f, 0.951056f, 0.162460f}, {0.238856f, 0.864188f, 0.442863f},
|
||||
{0.262866f, 0.951056f, 0.162460f}, {0.500000f, 0.809017f, 0.309017f}, {0.238856f, 0.864188f, -0.442863f},
|
||||
{0.262866f, 0.951056f, -0.162460f}, {0.500000f, 0.809017f, -0.309017f}, {0.850651f, 0.525731f, 0.000000f},
|
||||
{0.716567f, 0.681718f, 0.147621f}, {0.716567f, 0.681718f, -0.147621f}, {0.525731f, 0.850651f, 0.000000f},
|
||||
{0.425325f, 0.688191f, 0.587785f}, {0.864188f, 0.442863f, 0.238856f}, {0.688191f, 0.587785f, 0.425325f},
|
||||
{0.809017f, 0.309017f, 0.500000f}, {0.681718f, 0.147621f, 0.716567f}, {0.587785f, 0.425325f, 0.688191f},
|
||||
{0.955423f, 0.295242f, 0.000000f}, {1.000000f, 0.000000f, 0.000000f}, {0.951056f, 0.162460f, 0.262866f},
|
||||
{0.850651f, -0.525731f, 0.000000f}, {0.955423f, -0.295242f, 0.000000f}, {0.864188f, -0.442863f, 0.238856f},
|
||||
{0.951056f, -0.162460f, 0.262866f}, {0.809017f, -0.309017f, 0.500000f}, {0.681718f, -0.147621f, 0.716567f},
|
||||
{0.850651f, 0.000000f, 0.525731f}, {0.864188f, 0.442863f, -0.238856f}, {0.809017f, 0.309017f, -0.500000f},
|
||||
{0.951056f, 0.162460f, -0.262866f}, {0.525731f, 0.000000f, -0.850651f}, {0.681718f, 0.147621f, -0.716567f},
|
||||
{0.681718f, -0.147621f, -0.716567f}, {0.850651f, 0.000000f, -0.525731f}, {0.809017f, -0.309017f, -0.500000f},
|
||||
{0.864188f, -0.442863f, -0.238856f}, {0.951056f, -0.162460f, -0.262866f}, {0.147621f, 0.716567f, -0.681718f},
|
||||
{0.309017f, 0.500000f, -0.809017f}, {0.425325f, 0.688191f, -0.587785f}, {0.442863f, 0.238856f, -0.864188f},
|
||||
{0.587785f, 0.425325f, -0.688191f}, {0.688191f, 0.587785f, -0.425325f}, {-0.147621f, 0.716567f, -0.681718f},
|
||||
{-0.309017f, 0.500000f, -0.809017f}, {0.000000f, 0.525731f, -0.850651f}, {-0.525731f, 0.000000f, -0.850651f},
|
||||
{-0.442863f, 0.238856f, -0.864188f}, {-0.295242f, 0.000000f, -0.955423f}, {-0.162460f, 0.262866f, -0.951056f},
|
||||
{0.000000f, 0.000000f, -1.000000f}, {0.295242f, 0.000000f, -0.955423f}, {0.162460f, 0.262866f, -0.951056f},
|
||||
{-0.442863f, -0.238856f, -0.864188f}, {-0.309017f, -0.500000f, -0.809017f}, {-0.162460f, -0.262866f, -0.951056f},
|
||||
{0.000000f, -0.850651f, -0.525731f}, {-0.147621f, -0.716567f, -0.681718f}, {0.147621f, -0.716567f, -0.681718f},
|
||||
{0.000000f, -0.525731f, -0.850651f}, {0.309017f, -0.500000f, -0.809017f}, {0.442863f, -0.238856f, -0.864188f},
|
||||
{0.162460f, -0.262866f, -0.951056f}, {0.238856f, -0.864188f, -0.442863f}, {0.500000f, -0.809017f, -0.309017f},
|
||||
{0.425325f, -0.688191f, -0.587785f}, {0.716567f, -0.681718f, -0.147621f}, {0.688191f, -0.587785f, -0.425325f},
|
||||
{0.587785f, -0.425325f, -0.688191f}, {0.000000f, -0.955423f, -0.295242f}, {0.000000f, -1.000000f, 0.000000f},
|
||||
{0.262866f, -0.951056f, -0.162460f}, {0.000000f, -0.850651f, 0.525731f}, {0.000000f, -0.955423f, 0.295242f},
|
||||
{0.238856f, -0.864188f, 0.442863f}, {0.262866f, -0.951056f, 0.162460f}, {0.500000f, -0.809017f, 0.309017f},
|
||||
{0.716567f, -0.681718f, 0.147621f}, {0.525731f, -0.850651f, 0.000000f}, {-0.238856f, -0.864188f, -0.442863f},
|
||||
{-0.500000f, -0.809017f, -0.309017f}, {-0.262866f, -0.951056f, -0.162460f}, {-0.850651f, -0.525731f, 0.000000f},
|
||||
{-0.716567f, -0.681718f, -0.147621f}, {-0.716567f, -0.681718f, 0.147621f}, {-0.525731f, -0.850651f, 0.000000f},
|
||||
{-0.500000f, -0.809017f, 0.309017f}, {-0.238856f, -0.864188f, 0.442863f}, {-0.262866f, -0.951056f, 0.162460f},
|
||||
{-0.864188f, -0.442863f, 0.238856f}, {-0.809017f, -0.309017f, 0.500000f}, {-0.688191f, -0.587785f, 0.425325f},
|
||||
{-0.681718f, -0.147621f, 0.716567f}, {-0.442863f, -0.238856f, 0.864188f}, {-0.587785f, -0.425325f, 0.688191f},
|
||||
{-0.309017f, -0.500000f, 0.809017f}, {-0.147621f, -0.716567f, 0.681718f}, {-0.425325f, -0.688191f, 0.587785f},
|
||||
{-0.162460f, -0.262866f, 0.951056f}, {0.442863f, -0.238856f, 0.864188f}, {0.162460f, -0.262866f, 0.951056f},
|
||||
{0.309017f, -0.500000f, 0.809017f}, {0.147621f, -0.716567f, 0.681718f}, {0.000000f, -0.525731f, 0.850651f},
|
||||
{0.425325f, -0.688191f, 0.587785f}, {0.587785f, -0.425325f, 0.688191f}, {0.688191f, -0.587785f, 0.425325f},
|
||||
{-0.955423f, 0.295242f, 0.000000f}, {-0.951056f, 0.162460f, 0.262866f}, {-1.000000f, 0.000000f, 0.000000f},
|
||||
{-0.850651f, 0.000000f, 0.525731f}, {-0.955423f, -0.295242f, 0.000000f}, {-0.951056f, -0.162460f, 0.262866f},
|
||||
{-0.864188f, 0.442863f, -0.238856f}, {-0.951056f, 0.162460f, -0.262866f}, {-0.809017f, 0.309017f, -0.500000f},
|
||||
{-0.864188f, -0.442863f, -0.238856f}, {-0.951056f, -0.162460f, -0.262866f}, {-0.809017f, -0.309017f, -0.500000f},
|
||||
{-0.681718f, 0.147621f, -0.716567f}, {-0.681718f, -0.147621f, -0.716567f}, {-0.850651f, 0.000000f, -0.525731f},
|
||||
{-0.688191f, 0.587785f, -0.425325f}, {-0.587785f, 0.425325f, -0.688191f}, {-0.425325f, 0.688191f, -0.587785f},
|
||||
{-0.425325f, -0.688191f, -0.587785f}, {-0.587785f, -0.425325f, -0.688191f}, {-0.688191f, -0.587785f, -0.425325f}};
|
||||
|
||||
+74
-66
@@ -1,15 +1,15 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "md2rep.hpp"
|
||||
#include "md2norms.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxRuntime* gx_runtime;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
static Vector *normals = 0;
|
||||
static float tex_coords[2][2] = { {0,0},{0,0} };
|
||||
static Vector* normals = 0;
|
||||
static float tex_coords[2][2] = {{0, 0}, {0, 0}};
|
||||
|
||||
#pragma pack( push,1 )
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct md2_header {
|
||||
int magic;
|
||||
@@ -43,11 +43,12 @@ struct md2_tri {
|
||||
unsigned short verts[3], uvs[3];
|
||||
};
|
||||
|
||||
#pragma pack( pop )
|
||||
#pragma pack(pop)
|
||||
|
||||
struct t_vert {
|
||||
unsigned short i, uv;
|
||||
bool operator<(const t_vert &t)const {
|
||||
bool operator<(const t_vert& t) const
|
||||
{
|
||||
return memcmp(&i, &t.i, 4) < 0;
|
||||
}
|
||||
};
|
||||
@@ -56,15 +57,17 @@ struct t_tri {
|
||||
unsigned short verts[3];
|
||||
};
|
||||
|
||||
MD2Rep::MD2Rep(const string &f) :
|
||||
mesh(0), n_verts(0), n_tris(0), n_frames(0) {
|
||||
|
||||
MD2Rep::MD2Rep(const string& f) : mesh(0), n_verts(0), n_tris(0), n_frames(0)
|
||||
{
|
||||
filebuf in;
|
||||
md2_header header;
|
||||
|
||||
if (!in.open(f.c_str(), ios_base::in | ios_base::binary)) return;
|
||||
if (in.sgetn((char*)&header, sizeof(header)) != sizeof(header)) return;
|
||||
if (header.magic != '2PDI' || header.version != 8) return;
|
||||
if (!in.open(f.c_str(), ios_base::in | ios_base::binary))
|
||||
return;
|
||||
if (in.sgetn((char*)&header, sizeof(header)) != sizeof(header))
|
||||
return;
|
||||
if (header.magic != '2PDI' || header.version != 8)
|
||||
return;
|
||||
|
||||
n_frames = header.numFrames;
|
||||
n_tris = header.numTriangles;
|
||||
@@ -120,7 +123,7 @@ MD2Rep::MD2Rep(const string &f) :
|
||||
//read in frames
|
||||
for (k = 0; k < n_frames; ++k) {
|
||||
char t_buff[16];
|
||||
Frame *fr = &frames[k];
|
||||
Frame* fr = &frames[k];
|
||||
in.sgetn((char*)&fr->scale, 12);
|
||||
in.sgetn((char*)&fr->trans, 12);
|
||||
in.sgetn(t_buff, 16);
|
||||
@@ -133,9 +136,9 @@ MD2Rep::MD2Rep(const string &f) :
|
||||
|
||||
fr->verts.resize(n_verts);
|
||||
for (int j = 0; j < n_verts; ++j) {
|
||||
Vertex *v = &fr->verts[j];
|
||||
const t_vert &tv = t_verts[j];
|
||||
const md2_vert &mv = md2_verts[tv.i];
|
||||
Vertex* v = &fr->verts[j];
|
||||
const t_vert& tv = t_verts[j];
|
||||
const md2_vert& mv = md2_verts[tv.i];
|
||||
v->x = mv.y;
|
||||
v->y = mv.z;
|
||||
v->z = mv.x;
|
||||
@@ -148,7 +151,7 @@ MD2Rep::MD2Rep(const string &f) :
|
||||
mesh = gx_graphics->createMesh(n_verts, n_tris, 0);
|
||||
mesh->lock(true);
|
||||
for (k = 0; k < n_tris; ++k) {
|
||||
const t_tri &t = t_tris[k];
|
||||
const t_tri& t = t_tris[k];
|
||||
mesh->setTriangle(k, t.verts[0], t.verts[2], t.verts[1]);
|
||||
}
|
||||
mesh->unlock();
|
||||
@@ -162,8 +165,10 @@ MD2Rep::MD2Rep(const string &f) :
|
||||
}
|
||||
}
|
||||
|
||||
MD2Rep::~MD2Rep() {
|
||||
if (mesh) gx_graphics->freeMesh(mesh);
|
||||
MD2Rep::~MD2Rep()
|
||||
{
|
||||
if (mesh)
|
||||
gx_graphics->freeMesh(mesh);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -180,41 +185,43 @@ void MD2Rep::render( Vert *v,int frame ){
|
||||
}
|
||||
*/
|
||||
|
||||
void MD2Rep::render(Vert *v, int frame, float time) {
|
||||
|
||||
const Frame &frame_b = frames[frame];
|
||||
const Vertex *v_b = (Vertex*)(&frame_b.verts.begin()[0]);
|
||||
void MD2Rep::render(Vert* v, int frame, float time)
|
||||
{
|
||||
const Frame& frame_b = frames[frame];
|
||||
const Vertex* v_b = (Vertex*)(&frame_b.verts.begin()[0]);
|
||||
const Vector scale_b = frame_b.scale, trans_b = frame_b.trans;
|
||||
|
||||
for (int k = 0; k < n_verts; ++v, ++v_b, ++k) {
|
||||
const Vector t_b(v_b->x * scale_b.x + trans_b.x, v_b->y * scale_b.y + trans_b.y,
|
||||
v_b->z * scale_b.z + trans_b.z);
|
||||
const Vector& n_b = normals[v_b->n];
|
||||
|
||||
const Vector t_b(v_b->x*scale_b.x + trans_b.x, v_b->y*scale_b.y + trans_b.y, v_b->z*scale_b.z + trans_b.z);
|
||||
const Vector &n_b = normals[v_b->n];
|
||||
|
||||
v->coords += (t_b - v->coords)*time;
|
||||
v->normal += (n_b - v->normal)*time;
|
||||
v->coords += (t_b - v->coords) * time;
|
||||
v->normal += (n_b - v->normal) * time;
|
||||
}
|
||||
}
|
||||
|
||||
void MD2Rep::render(Vert *v, int render_a, int render_b, float render_t) {
|
||||
const Frame &frame_a = frames[render_a];
|
||||
void MD2Rep::render(Vert* v, int render_a, int render_b, float render_t)
|
||||
{
|
||||
const Frame& frame_a = frames[render_a];
|
||||
const Vector scale_a = frame_a.scale, trans_a = frame_a.trans;
|
||||
|
||||
const Frame &frame_b = frames[render_b];
|
||||
const Frame& frame_b = frames[render_b];
|
||||
const Vector scale_b = frame_b.scale, trans_b = frame_b.trans;
|
||||
|
||||
const Vertex *v_a = (Vertex*)(&frame_a.verts.begin()[0]);
|
||||
const Vertex *v_b = (Vertex*)(&frame_b.verts.begin()[0]);
|
||||
const Vertex* v_a = (Vertex*)(&frame_a.verts.begin()[0]);
|
||||
const Vertex* v_b = (Vertex*)(&frame_b.verts.begin()[0]);
|
||||
|
||||
for (int k = 0; k < n_verts; ++v, ++v_a, ++v_b, ++k) {
|
||||
const Vector t_a(v_a->x * scale_a.x + trans_a.x, v_a->y * scale_a.y + trans_a.y,
|
||||
v_a->z * scale_a.z + trans_a.z);
|
||||
const Vector t_b(v_b->x * scale_b.x + trans_b.x, v_b->y * scale_b.y + trans_b.y,
|
||||
v_b->z * scale_b.z + trans_b.z);
|
||||
v->coords = (t_b - t_a) * render_t + t_a;
|
||||
|
||||
const Vector t_a(v_a->x*scale_a.x + trans_a.x, v_a->y*scale_a.y + trans_a.y, v_a->z*scale_a.z + trans_a.z);
|
||||
const Vector t_b(v_b->x*scale_b.x + trans_b.x, v_b->y*scale_b.y + trans_b.y, v_b->z*scale_b.z + trans_b.z);
|
||||
v->coords = (t_b - t_a)*render_t + t_a;
|
||||
|
||||
const Vector &n_a = normals[v_a->n];
|
||||
const Vector &n_b = normals[v_b->n];
|
||||
v->normal = (n_b - n_a)*render_t + n_a;
|
||||
const Vector& n_a = normals[v_a->n];
|
||||
const Vector& n_b = normals[v_b->n];
|
||||
v->normal = (n_b - n_a) * render_t + n_a;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,27 +234,29 @@ void MD2Rep::render( Vert *v,const Vert *v_a,const Vert *v_b,float render_t ){
|
||||
}
|
||||
*/
|
||||
|
||||
void MD2Rep::render(Model *model, int render_a, int render_b, float render_t) {
|
||||
const Frame &frame_a = frames[render_a];
|
||||
void MD2Rep::render(Model* model, int render_a, int render_b, float render_t)
|
||||
{
|
||||
const Frame& frame_a = frames[render_a];
|
||||
const Vector scale_a = frame_a.scale, trans_a = frame_a.trans;
|
||||
|
||||
const Frame &frame_b = frames[render_b];
|
||||
const Frame& frame_b = frames[render_b];
|
||||
const Vector scale_b = frame_b.scale, trans_b = frame_b.trans;
|
||||
|
||||
const VertexUV *uv = (VertexUV*)&uvs.begin()[0];
|
||||
const Vertex *v_a = (Vertex*)(&frame_a.verts.begin()[0]);
|
||||
const Vertex *v_b = (Vertex*)(&frame_b.verts.begin()[0]);
|
||||
const VertexUV* uv = (VertexUV*)&uvs.begin()[0];
|
||||
const Vertex* v_a = (Vertex*)(&frame_a.verts.begin()[0]);
|
||||
const Vertex* v_b = (Vertex*)(&frame_b.verts.begin()[0]);
|
||||
|
||||
mesh->lock(true);
|
||||
for (int k = 0; k < n_verts; ++uv, ++v_a, ++v_b, ++k) {
|
||||
const Vector t_a(v_a->x * scale_a.x + trans_a.x, v_a->y * scale_a.y + trans_a.y,
|
||||
v_a->z * scale_a.z + trans_a.z);
|
||||
const Vector t_b(v_b->x * scale_b.x + trans_b.x, v_b->y * scale_b.y + trans_b.y,
|
||||
v_b->z * scale_b.z + trans_b.z);
|
||||
const Vector t((t_b - t_a) * render_t + t_a);
|
||||
|
||||
const Vector t_a(v_a->x*scale_a.x + trans_a.x, v_a->y*scale_a.y + trans_a.y, v_a->z*scale_a.z + trans_a.z);
|
||||
const Vector t_b(v_b->x*scale_b.x + trans_b.x, v_b->y*scale_b.y + trans_b.y, v_b->z*scale_b.z + trans_b.z);
|
||||
const Vector t((t_b - t_a)*render_t + t_a);
|
||||
|
||||
const Vector &n_a = normals[v_a->n];
|
||||
const Vector &n_b = normals[v_b->n];
|
||||
const Vector n((n_b - n_a)*render_t + n_a);
|
||||
const Vector& n_a = normals[v_a->n];
|
||||
const Vector& n_b = normals[v_b->n];
|
||||
const Vector n((n_b - n_a) * render_t + n_a);
|
||||
|
||||
tex_coords[0][0] = uv->u;
|
||||
tex_coords[0][1] = uv->v;
|
||||
@@ -280,22 +289,22 @@ void MD2Rep::render( Model *model,const Vert *v_a,const Vert *v_b,float render_t
|
||||
}
|
||||
*/
|
||||
|
||||
void MD2Rep::render(Model *model, const Vert *v_a, int render_b, float render_t) {
|
||||
|
||||
const Frame &frame_b = frames[render_b];
|
||||
void MD2Rep::render(Model* model, const Vert* v_a, int render_b, float render_t)
|
||||
{
|
||||
const Frame& frame_b = frames[render_b];
|
||||
const Vector scale_b = frame_b.scale, trans_b = frame_b.trans;
|
||||
|
||||
const VertexUV *uv = (VertexUV*)&uvs.begin()[0];
|
||||
const Vertex *v_b = (Vertex*)&frame_b.verts.begin()[0];
|
||||
const VertexUV* uv = (VertexUV*)&uvs.begin()[0];
|
||||
const Vertex* v_b = (Vertex*)&frame_b.verts.begin()[0];
|
||||
|
||||
mesh->lock(true);
|
||||
for (int k = 0; k < n_verts; ++uv, ++v_a, ++v_b, ++k) {
|
||||
const Vector t_b(v_b->x * scale_b.x + trans_b.x, v_b->y * scale_b.y + trans_b.y,
|
||||
v_b->z * scale_b.z + trans_b.z);
|
||||
const Vector t((t_b - v_a->coords) * render_t + v_a->coords);
|
||||
|
||||
const Vector t_b(v_b->x*scale_b.x + trans_b.x, v_b->y*scale_b.y + trans_b.y, v_b->z*scale_b.z + trans_b.z);
|
||||
const Vector t((t_b - v_a->coords)*render_t + v_a->coords);
|
||||
|
||||
const Vector &n_b = normals[v_b->n];
|
||||
const Vector n((n_b - v_a->normal)*render_t + v_a->normal);
|
||||
const Vector& n_b = normals[v_b->n];
|
||||
const Vector n((n_b - v_a->normal) * render_t + v_a->normal);
|
||||
|
||||
tex_coords[0][0] = uv->u;
|
||||
tex_coords[0][1] = uv->v;
|
||||
@@ -306,4 +315,3 @@ void MD2Rep::render(Model *model, const Vert *v_a, int render_b, float render_t)
|
||||
|
||||
model->enqueue(mesh, 0, n_verts, 0, n_tris);
|
||||
}
|
||||
|
||||
|
||||
+33
-24
@@ -4,46 +4,55 @@
|
||||
|
||||
#include "model.hpp"
|
||||
|
||||
class MD2Rep{
|
||||
public:
|
||||
struct Vert{
|
||||
Vector coords,normal;
|
||||
class MD2Rep {
|
||||
public:
|
||||
struct Vert {
|
||||
Vector coords, normal;
|
||||
};
|
||||
|
||||
MD2Rep( const string &f );
|
||||
MD2Rep(const string& f);
|
||||
virtual ~MD2Rep();
|
||||
|
||||
void render( Vert *verts,int frame );
|
||||
void render( Vert *verts,int frame,float time );
|
||||
void render( Vert *verts,int frame_a,int frame_b,float time );
|
||||
void render( Vert *verts,const Vert *verts_a,const Vert *verts_b,float time );
|
||||
void render(Vert* verts, int frame);
|
||||
void render(Vert* verts, int frame, float time);
|
||||
void render(Vert* verts, int frame_a, int frame_b, float time);
|
||||
void render(Vert* verts, const Vert* verts_a, const Vert* verts_b, float time);
|
||||
|
||||
void render( Model *model,int frame_a,int frame_b,float time );
|
||||
void render( Model *model,const Vert *verts_a,const Vert *verts_b,float time );
|
||||
void render( Model *model,const Vert *verts_a,int frame_b,float time );
|
||||
void render(Model* model, int frame_a, int frame_b, float time);
|
||||
void render(Model* model, const Vert* verts_a, const Vert* verts_b, float time);
|
||||
void render(Model* model, const Vert* verts_a, int frame_b, float time);
|
||||
|
||||
const Box &getBox()const{ return box; }
|
||||
const int numFrames()const{ return n_frames; }
|
||||
const int numVertices()const{ return n_verts; }
|
||||
const Box& getBox() const
|
||||
{
|
||||
return box;
|
||||
}
|
||||
const int numFrames() const
|
||||
{
|
||||
return n_frames;
|
||||
}
|
||||
const int numVertices() const
|
||||
{
|
||||
return n_verts;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Vertex{
|
||||
unsigned char x,y,z,n;
|
||||
private:
|
||||
struct Vertex {
|
||||
unsigned char x, y, z, n;
|
||||
};
|
||||
|
||||
struct VertexUV{
|
||||
float u,v;
|
||||
struct VertexUV {
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct Frame{
|
||||
Vector scale,trans;
|
||||
struct Frame {
|
||||
Vector scale, trans;
|
||||
vector<Vertex> verts;
|
||||
};
|
||||
|
||||
Box box;
|
||||
gxMesh *mesh;
|
||||
gxMesh* mesh;
|
||||
int n_frames;
|
||||
int n_verts,n_tris;
|
||||
int n_verts, n_tris;
|
||||
vector<Frame> frames;
|
||||
vector<VertexUV> uvs;
|
||||
};
|
||||
|
||||
+147
-115
@@ -1,196 +1,228 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "meshcollider.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
static const int MAX_COLL_TRIS=16;
|
||||
static const int MAX_COLL_TRIS = 16;
|
||||
static vector<Vector> tri_centres;
|
||||
|
||||
extern float stats3d[10];
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxRuntime* gx_runtime;
|
||||
|
||||
static bool triTest( const Vector a[3],const Vector b[3] ){
|
||||
bool pb0=false,pb1=false,pb2=false;
|
||||
Plane p( a[0],a[1],a[2] ),p0,p1,p2;
|
||||
for( int k=0;k<3;++k ){
|
||||
Line l( b[k],b[(k+1)%3]-b[k] );
|
||||
float t=p.t_intersect( l );
|
||||
if( t<0 || t>1 ) continue;
|
||||
Vector i=l*t;
|
||||
if( !pb0 ){ p0=Plane( a[0]+p.n,a[1],a[0] );pb0=true; }
|
||||
if( p0.distance( i )<0 ) continue;
|
||||
if( !pb1 ){ p1=Plane( a[1]+p.n,a[2],a[1] );pb1=true; }
|
||||
if( p1.distance( i )<0 ) continue;
|
||||
if( !pb2 ){ p2=Plane( a[2]+p.n,a[0],a[2] );pb2=true; }
|
||||
if( p2.distance( i )<0 ) continue;
|
||||
static bool triTest(const Vector a[3], const Vector b[3])
|
||||
{
|
||||
bool pb0 = false, pb1 = false, pb2 = false;
|
||||
Plane p(a[0], a[1], a[2]), p0, p1, p2;
|
||||
for (int k = 0; k < 3; ++k) {
|
||||
Line l(b[k], b[(k + 1) % 3] - b[k]);
|
||||
float t = p.t_intersect(l);
|
||||
if (t < 0 || t > 1)
|
||||
continue;
|
||||
Vector i = l * t;
|
||||
if (!pb0) {
|
||||
p0 = Plane(a[0] + p.n, a[1], a[0]);
|
||||
pb0 = true;
|
||||
}
|
||||
if (p0.distance(i) < 0)
|
||||
continue;
|
||||
if (!pb1) {
|
||||
p1 = Plane(a[1] + p.n, a[2], a[1]);
|
||||
pb1 = true;
|
||||
}
|
||||
if (p1.distance(i) < 0)
|
||||
continue;
|
||||
if (!pb2) {
|
||||
p2 = Plane(a[2] + p.n, a[0], a[2]);
|
||||
pb2 = true;
|
||||
}
|
||||
if (p2.distance(i) < 0)
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool trisIntersect( const Vector a[3],const Vector b[3] ){
|
||||
return triTest( a,b ) || triTest( b,a );
|
||||
static bool trisIntersect(const Vector a[3], const Vector b[3])
|
||||
{
|
||||
return triTest(a, b) || triTest(b, a);
|
||||
}
|
||||
|
||||
MeshCollider::MeshCollider( const vector<Vertex> &verts,const vector<Triangle> &tris ):
|
||||
vertices(verts),triangles(tris){
|
||||
MeshCollider::MeshCollider(const vector<Vertex>& verts, const vector<Triangle>& tris) : vertices(verts), triangles(tris)
|
||||
{
|
||||
vector<int> ts;
|
||||
tri_centres.clear();
|
||||
for( int k=0;k<triangles.size();++k ){
|
||||
const MeshCollider::Triangle &t=triangles[k];
|
||||
const Vector &v0=vertices[t.verts[0]].coords;
|
||||
const Vector &v1=vertices[t.verts[1]].coords;
|
||||
const Vector &v2=vertices[t.verts[2]].coords;
|
||||
tri_centres.push_back( (v0+v1+v2)/3 );
|
||||
ts.push_back( k );
|
||||
for (int k = 0; k < triangles.size(); ++k) {
|
||||
const MeshCollider::Triangle& t = triangles[k];
|
||||
const Vector& v0 = vertices[t.verts[0]].coords;
|
||||
const Vector& v1 = vertices[t.verts[1]].coords;
|
||||
const Vector& v2 = vertices[t.verts[2]].coords;
|
||||
tri_centres.push_back((v0 + v1 + v2) / 3);
|
||||
ts.push_back(k);
|
||||
}
|
||||
tree=createNode( ts );
|
||||
tree = createNode(ts);
|
||||
}
|
||||
|
||||
MeshCollider::~MeshCollider(){
|
||||
MeshCollider::~MeshCollider()
|
||||
{
|
||||
delete tree;
|
||||
}
|
||||
|
||||
bool MeshCollider::collide( const Line &line,float radius,Collision *curr_coll,const Transform &t ){
|
||||
|
||||
if( !tree ) return false;
|
||||
bool MeshCollider::collide(const Line& line, float radius, Collision* curr_coll, const Transform& t)
|
||||
{
|
||||
if (!tree)
|
||||
return false;
|
||||
|
||||
//create local box
|
||||
Box box( line );
|
||||
box.expand( radius );
|
||||
Box local_box=-t * box;
|
||||
Box box(line);
|
||||
box.expand(radius);
|
||||
Box local_box = -t * box;
|
||||
|
||||
return collide( local_box,line,radius,t,curr_coll,tree );
|
||||
return collide(local_box, line, radius, t, curr_coll, tree);
|
||||
}
|
||||
|
||||
bool MeshCollider::collide( const Box &line_box,const Line &line,float radius,const Transform &tform,Collision *curr_coll,MeshCollider::Node *node ){
|
||||
if( !line_box.overlaps( node->box ) ){
|
||||
bool MeshCollider::collide(const Box& line_box, const Line& line, float radius, const Transform& tform,
|
||||
Collision* curr_coll, MeshCollider::Node* node)
|
||||
{
|
||||
if (!line_box.overlaps(node->box)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hit=false;
|
||||
if( !node->triangles.size() ){
|
||||
if( node->left ) hit|=collide( line_box,line,radius,tform,curr_coll,node->left );
|
||||
if( node->right ) hit|=collide( line_box,line,radius,tform,curr_coll,node->right );
|
||||
bool hit = false;
|
||||
if (!node->triangles.size()) {
|
||||
if (node->left)
|
||||
hit |= collide(line_box, line, radius, tform, curr_coll, node->left);
|
||||
if (node->right)
|
||||
hit |= collide(line_box, line, radius, tform, curr_coll, node->right);
|
||||
return hit;
|
||||
}
|
||||
|
||||
stats3d[0]+=node->triangles.size();
|
||||
stats3d[0] += node->triangles.size();
|
||||
|
||||
for( int k=0;k<node->triangles.size();++k ){
|
||||
|
||||
const Triangle &tri=triangles[node->triangles[k]];
|
||||
const Vector &t_v0=vertices[ tri.verts[0] ].coords;
|
||||
const Vector &t_v1=vertices[ tri.verts[1] ].coords;
|
||||
const Vector &t_v2=vertices[ tri.verts[2] ].coords;
|
||||
for (int k = 0; k < node->triangles.size(); ++k) {
|
||||
const Triangle& tri = triangles[node->triangles[k]];
|
||||
const Vector& t_v0 = vertices[tri.verts[0]].coords;
|
||||
const Vector& t_v1 = vertices[tri.verts[1]].coords;
|
||||
const Vector& t_v2 = vertices[tri.verts[2]].coords;
|
||||
|
||||
//tri box
|
||||
Box tri_box( t_v0 );
|
||||
tri_box.update( t_v1 );
|
||||
tri_box.update( t_v2 );
|
||||
if( !tri_box.overlaps( line_box ) ) continue;
|
||||
Box tri_box(t_v0);
|
||||
tri_box.update(t_v1);
|
||||
tri_box.update(t_v2);
|
||||
if (!tri_box.overlaps(line_box))
|
||||
continue;
|
||||
|
||||
if( !curr_coll->triangleCollide( line,radius,tform*t_v0,tform*t_v1,tform*t_v2 ) ) continue;
|
||||
if (!curr_coll->triangleCollide(line, radius, tform * t_v0, tform * t_v1, tform * t_v2))
|
||||
continue;
|
||||
|
||||
curr_coll->surface=tri.surface;
|
||||
curr_coll->index=tri.index;
|
||||
curr_coll->surface = tri.surface;
|
||||
curr_coll->index = tri.index;
|
||||
|
||||
hit=true;
|
||||
hit = true;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
Box MeshCollider::nodeBox( const vector<int> &tris ){
|
||||
Box MeshCollider::nodeBox(const vector<int>& tris)
|
||||
{
|
||||
Box box;
|
||||
for( int k=0;k<tris.size();++k ){
|
||||
const Triangle &t=triangles[ tris[k] ];
|
||||
for( int j=0;j<3;++j ) box.update( vertices[t.verts[j]].coords );
|
||||
for (int k = 0; k < tris.size(); ++k) {
|
||||
const Triangle& t = triangles[tris[k]];
|
||||
for (int j = 0; j < 3; ++j)
|
||||
box.update(vertices[t.verts[j]].coords);
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
MeshCollider::Node *MeshCollider::createLeaf( const vector<int> &tris ){
|
||||
|
||||
Node *c=new Node;
|
||||
c->box=nodeBox( tris );
|
||||
c->triangles=tris;
|
||||
leaves.push_back( c );
|
||||
MeshCollider::Node* MeshCollider::createLeaf(const vector<int>& tris)
|
||||
{
|
||||
Node* c = new Node;
|
||||
c->box = nodeBox(tris);
|
||||
c->triangles = tris;
|
||||
leaves.push_back(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
MeshCollider::Node *MeshCollider::createNode( const vector<int> &tris ){
|
||||
MeshCollider::Node* MeshCollider::createNode(const vector<int>& tris)
|
||||
{
|
||||
if (tris.size() <= MAX_COLL_TRIS)
|
||||
return createLeaf(tris);
|
||||
|
||||
if( tris.size()<=MAX_COLL_TRIS ) return createLeaf( tris );
|
||||
|
||||
Node *c=new Node;
|
||||
c->box=nodeBox( tris );
|
||||
Node* c = new Node;
|
||||
c->box = nodeBox(tris);
|
||||
|
||||
//find longest axis
|
||||
//
|
||||
float max=c->box.width();
|
||||
if( c->box.height()>max ) max=c->box.height();
|
||||
if( c->box.depth()>max ) max=c->box.depth();
|
||||
int axis=0;
|
||||
if( max==c->box.height() ) axis=1;
|
||||
else if( max==c->box.depth() ) axis=2;
|
||||
float max = c->box.width();
|
||||
if (c->box.height() > max)
|
||||
max = c->box.height();
|
||||
if (c->box.depth() > max)
|
||||
max = c->box.depth();
|
||||
int axis = 0;
|
||||
if (max == c->box.height())
|
||||
axis = 1;
|
||||
else if (max == c->box.depth())
|
||||
axis = 2;
|
||||
|
||||
//sort by axis
|
||||
//
|
||||
int k;
|
||||
multimap<float,int> axis_map;
|
||||
for( k=0;k<tris.size();++k ){
|
||||
pair<float,int> p( tri_centres[tris[k]][axis],tris[k] );
|
||||
axis_map.insert( p );
|
||||
multimap<float, int> axis_map;
|
||||
for (k = 0; k < tris.size(); ++k) {
|
||||
pair<float, int> p(tri_centres[tris[k]][axis], tris[k]);
|
||||
axis_map.insert(p);
|
||||
}
|
||||
|
||||
//generate left node
|
||||
//
|
||||
vector<int> new_tris;
|
||||
multimap<float,int>::iterator it=axis_map.begin();
|
||||
for( k=axis_map.size()/2;k--;++it ){
|
||||
new_tris.push_back( it->second );
|
||||
multimap<float, int>::iterator it = axis_map.begin();
|
||||
for (k = axis_map.size() / 2; k--; ++it) {
|
||||
new_tris.push_back(it->second);
|
||||
}
|
||||
c->left=createNode( new_tris );
|
||||
c->left = createNode(new_tris);
|
||||
|
||||
//generate right node
|
||||
//
|
||||
new_tris.clear();
|
||||
for( ;it!=axis_map.end();++it ){
|
||||
new_tris.push_back( it->second );
|
||||
for (; it != axis_map.end(); ++it) {
|
||||
new_tris.push_back(it->second);
|
||||
}
|
||||
c->right=createNode( new_tris );
|
||||
c->right = createNode(new_tris);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
bool MeshCollider::intersects( const MeshCollider &c,const Transform &t )const{
|
||||
bool MeshCollider::intersects(const MeshCollider& c, const Transform& t) const
|
||||
{
|
||||
static Vector a[MAX_COLL_TRIS][3], b[3];
|
||||
|
||||
static Vector a[MAX_COLL_TRIS][3],b[3];
|
||||
|
||||
if( !(t * tree->box).overlaps( c.tree->box ) ) return false;
|
||||
for( int k=0;k<leaves.size();++k ){
|
||||
Node *p=leaves[k];
|
||||
Box box=t*p->box;
|
||||
bool tformed=false;
|
||||
for( int j=0;j<c.leaves.size();++j ){
|
||||
Node *q=c.leaves[j];
|
||||
if( !box.overlaps( q->box ) ) continue;
|
||||
if( !tformed ){
|
||||
for( int n=0;n<p->triangles.size();++n ){
|
||||
const Triangle &tri=triangles[p->triangles[n]];
|
||||
a[n][0]=t * vertices[tri.verts[0]].coords;
|
||||
a[n][1]=t * vertices[tri.verts[1]].coords;
|
||||
a[n][2]=t * vertices[tri.verts[2]].coords;
|
||||
if (!(t * tree->box).overlaps(c.tree->box))
|
||||
return false;
|
||||
for (int k = 0; k < leaves.size(); ++k) {
|
||||
Node* p = leaves[k];
|
||||
Box box = t * p->box;
|
||||
bool tformed = false;
|
||||
for (int j = 0; j < c.leaves.size(); ++j) {
|
||||
Node* q = c.leaves[j];
|
||||
if (!box.overlaps(q->box))
|
||||
continue;
|
||||
if (!tformed) {
|
||||
for (int n = 0; n < p->triangles.size(); ++n) {
|
||||
const Triangle& tri = triangles[p->triangles[n]];
|
||||
a[n][0] = t * vertices[tri.verts[0]].coords;
|
||||
a[n][1] = t * vertices[tri.verts[1]].coords;
|
||||
a[n][2] = t * vertices[tri.verts[2]].coords;
|
||||
}
|
||||
tformed=true;
|
||||
tformed = true;
|
||||
}
|
||||
for( int n=0;n<q->triangles.size();++n ){
|
||||
const Triangle &tri=c.triangles[q->triangles[n]];
|
||||
b[0]=c.vertices[tri.verts[0]].coords;
|
||||
b[1]=c.vertices[tri.verts[1]].coords;
|
||||
b[2]=c.vertices[tri.verts[2]].coords;
|
||||
for( int t=0;t<p->triangles.size();++t ){
|
||||
if( trisIntersect( a[t],b ) ) return true;
|
||||
for (int n = 0; n < q->triangles.size(); ++n) {
|
||||
const Triangle& tri = c.triangles[q->triangles[n]];
|
||||
b[0] = c.vertices[tri.verts[0]].coords;
|
||||
b[1] = c.vertices[tri.verts[1]].coords;
|
||||
b[2] = c.vertices[tri.verts[2]].coords;
|
||||
for (int t = 0; t < p->triangles.size(); ++t) {
|
||||
if (trisIntersect(a[t], b))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,42 +4,47 @@
|
||||
|
||||
#include "collision.hpp"
|
||||
|
||||
class MeshCollider{
|
||||
public:
|
||||
struct Vertex{
|
||||
class MeshCollider {
|
||||
public:
|
||||
struct Vertex {
|
||||
Vector coords;
|
||||
};
|
||||
struct Triangle{
|
||||
void *surface;
|
||||
int verts[3],index;
|
||||
struct Triangle {
|
||||
void* surface;
|
||||
int verts[3], index;
|
||||
};
|
||||
MeshCollider( const vector<Vertex> &verts,const vector<Triangle> &tris );
|
||||
MeshCollider(const vector<Vertex>& verts, const vector<Triangle>& tris);
|
||||
~MeshCollider();
|
||||
|
||||
//sphere collision
|
||||
bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &tform );
|
||||
bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& tform);
|
||||
|
||||
bool intersects( const MeshCollider &c,const Transform &t )const;
|
||||
bool intersects(const MeshCollider& c, const Transform& t) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
vector<Vertex> vertices;
|
||||
vector<Triangle> triangles;
|
||||
|
||||
struct Node{
|
||||
struct Node {
|
||||
Box box;
|
||||
Node *left,*right;
|
||||
Node * left, *right;
|
||||
vector<int> triangles;
|
||||
Node():left(0),right(0){}
|
||||
~Node(){ delete left;delete right; }
|
||||
Node() : left(0), right(0) {}
|
||||
~Node()
|
||||
{
|
||||
delete left;
|
||||
delete right;
|
||||
}
|
||||
};
|
||||
|
||||
Node *tree;
|
||||
Node* tree;
|
||||
vector<Node*> leaves;
|
||||
|
||||
Box nodeBox( const vector<int> &tris );
|
||||
Node *createLeaf( const vector<int> &tris );
|
||||
Node *createNode( const vector<int> &tris );
|
||||
bool collide( const Box &box,const Line &line,float radius,const Transform &tform,Collision *curr_coll,Node *node );
|
||||
Box nodeBox(const vector<int>& tris);
|
||||
Node* createLeaf(const vector<int>& tris);
|
||||
Node* createNode(const vector<int>& tris);
|
||||
bool collide(const Box& box, const Line& line, float radius, const Transform& tform, Collision* curr_coll,
|
||||
Node* node);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,130 +1,148 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "meshloader.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
struct Tri{
|
||||
struct Tri {
|
||||
int verts[3];
|
||||
};
|
||||
|
||||
struct Surf{
|
||||
struct Surf {
|
||||
vector<Tri> tris;
|
||||
};
|
||||
|
||||
struct MLMesh{
|
||||
map<Brush,Surf*> brush_map;
|
||||
struct MLMesh {
|
||||
map<Brush, Surf*> brush_map;
|
||||
vector<Surface::Vertex> verts;
|
||||
|
||||
MLMesh(){
|
||||
}
|
||||
MLMesh() {}
|
||||
|
||||
~MLMesh(){
|
||||
map<Brush,Surf*>::const_iterator it;
|
||||
for( it=brush_map.begin();it!=brush_map.end();++it ){
|
||||
~MLMesh()
|
||||
{
|
||||
map<Brush, Surf*>::const_iterator it;
|
||||
for (it = brush_map.begin(); it != brush_map.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static MLMesh *ml_mesh;
|
||||
static MLMesh* ml_mesh;
|
||||
static vector<MLMesh*> mesh_stack;
|
||||
|
||||
void MeshLoader::beginMesh(){
|
||||
mesh_stack.push_back( ml_mesh );
|
||||
ml_mesh=new MLMesh();
|
||||
void MeshLoader::beginMesh()
|
||||
{
|
||||
mesh_stack.push_back(ml_mesh);
|
||||
ml_mesh = new MLMesh();
|
||||
}
|
||||
|
||||
int MeshLoader::numVertices(){
|
||||
int MeshLoader::numVertices()
|
||||
{
|
||||
return ml_mesh->verts.size();
|
||||
}
|
||||
|
||||
void MeshLoader::addVertex( const Surface::Vertex &v ){
|
||||
ml_mesh->verts.push_back( v );
|
||||
void MeshLoader::addVertex(const Surface::Vertex& v)
|
||||
{
|
||||
ml_mesh->verts.push_back(v);
|
||||
}
|
||||
|
||||
void MeshLoader::addTriangle( const int verts[3],const Brush &b ){
|
||||
addTriangle( verts[0],verts[1],verts[2],b );
|
||||
void MeshLoader::addTriangle(const int verts[3], const Brush& b)
|
||||
{
|
||||
addTriangle(verts[0], verts[1], verts[2], b);
|
||||
}
|
||||
|
||||
void MeshLoader::addBone( int n,float w,int b ){
|
||||
Surface::Vertex &v=ml_mesh->verts[n];
|
||||
void MeshLoader::addBone(int n, float w, int b)
|
||||
{
|
||||
Surface::Vertex& v = ml_mesh->verts[n];
|
||||
int i;
|
||||
for( i=0;i<MAX_SURFACE_BONES;++i ){
|
||||
if( v.bone_bones[i]==255 || w>v.bone_weights[i] ) break;
|
||||
for (i = 0; i < MAX_SURFACE_BONES; ++i) {
|
||||
if (v.bone_bones[i] == 255 || w > v.bone_weights[i])
|
||||
break;
|
||||
}
|
||||
if( i==MAX_SURFACE_BONES ) return;
|
||||
for( int k=MAX_SURFACE_BONES-1;k>i;--k ){
|
||||
v.bone_bones[k]=v.bone_bones[k-1];
|
||||
v.bone_weights[k]=v.bone_weights[k-1];
|
||||
if (i == MAX_SURFACE_BONES)
|
||||
return;
|
||||
for (int k = MAX_SURFACE_BONES - 1; k > i; --k) {
|
||||
v.bone_bones[k] = v.bone_bones[k - 1];
|
||||
v.bone_weights[k] = v.bone_weights[k - 1];
|
||||
}
|
||||
v.bone_bones[i]=b;
|
||||
v.bone_weights[i]=w;
|
||||
v.bone_bones[i] = b;
|
||||
v.bone_weights[i] = w;
|
||||
}
|
||||
|
||||
Surface::Vertex &MeshLoader::refVertex( int n ){
|
||||
Surface::Vertex& MeshLoader::refVertex(int n)
|
||||
{
|
||||
return ml_mesh->verts[n];
|
||||
}
|
||||
|
||||
void MeshLoader::addTriangle( int v0,int v1,int v2,const Brush &b ){
|
||||
void MeshLoader::addTriangle(int v0, int v1, int v2, const Brush& b)
|
||||
{
|
||||
//find surface
|
||||
Surf *surf;
|
||||
map<Brush,Surf*>::const_iterator it=ml_mesh->brush_map.find( b );
|
||||
if( it!=ml_mesh->brush_map.end() ) surf=it->second;
|
||||
else{
|
||||
surf=new Surf;
|
||||
ml_mesh->brush_map.insert( make_pair( b,surf ) );
|
||||
Surf* surf;
|
||||
map<Brush, Surf*>::const_iterator it = ml_mesh->brush_map.find(b);
|
||||
if (it != ml_mesh->brush_map.end())
|
||||
surf = it->second;
|
||||
else {
|
||||
surf = new Surf;
|
||||
ml_mesh->brush_map.insert(make_pair(b, surf));
|
||||
}
|
||||
|
||||
Tri tri;
|
||||
tri.verts[0]=v0;tri.verts[1]=v1;tri.verts[2]=v2;
|
||||
surf->tris.push_back( tri );
|
||||
tri.verts[0] = v0;
|
||||
tri.verts[1] = v1;
|
||||
tri.verts[2] = v2;
|
||||
surf->tris.push_back(tri);
|
||||
}
|
||||
|
||||
void MeshLoader::endMesh( MeshModel *mesh ){
|
||||
if( mesh ){
|
||||
void MeshLoader::endMesh(MeshModel* mesh)
|
||||
{
|
||||
if (mesh) {
|
||||
//fix bone weights
|
||||
int k,max_bones=0;
|
||||
for( k=0;k<ml_mesh->verts.size();++k ){
|
||||
Surface::Vertex &v=ml_mesh->verts[k];
|
||||
if( v.bone_bones[0]==255 ) continue;
|
||||
int k, max_bones = 0;
|
||||
for (k = 0; k < ml_mesh->verts.size(); ++k) {
|
||||
Surface::Vertex& v = ml_mesh->verts[k];
|
||||
if (v.bone_bones[0] == 255)
|
||||
continue;
|
||||
int j;
|
||||
float t=0;
|
||||
for( j=0;j<MAX_SURFACE_BONES;++j ){
|
||||
if( v.bone_bones[j]==255 ) break;
|
||||
t+=v.bone_weights[j];
|
||||
float t = 0;
|
||||
for (j = 0; j < MAX_SURFACE_BONES; ++j) {
|
||||
if (v.bone_bones[j] == 255)
|
||||
break;
|
||||
t += v.bone_weights[j];
|
||||
}
|
||||
if( j>max_bones ) max_bones=j;
|
||||
t=1.0f/t;
|
||||
for( j=0;j<MAX_SURFACE_BONES;++j ){
|
||||
v.bone_weights[j]*=t;
|
||||
if (j > max_bones)
|
||||
max_bones = j;
|
||||
t = 1.0f / t;
|
||||
for (j = 0; j < MAX_SURFACE_BONES; ++j) {
|
||||
v.bone_weights[j] *= t;
|
||||
}
|
||||
}
|
||||
map<int,int> vert_map;
|
||||
map<Brush,Surf*>::iterator it;
|
||||
for( it=ml_mesh->brush_map.begin();it!=ml_mesh->brush_map.end();++it ){
|
||||
map<int, int> vert_map;
|
||||
map<Brush, Surf*>::iterator it;
|
||||
for (it = ml_mesh->brush_map.begin(); it != ml_mesh->brush_map.end(); ++it) {
|
||||
vert_map.clear();
|
||||
Brush b=it->first;
|
||||
Surf *t=it->second;
|
||||
Surface *surf=mesh->findSurface( b );
|
||||
if( !surf ) surf=mesh->createSurface( b );
|
||||
for( int k=0;k<t->tris.size();++k ){
|
||||
Brush b = it->first;
|
||||
Surf* t = it->second;
|
||||
Surface* surf = mesh->findSurface(b);
|
||||
if (!surf)
|
||||
surf = mesh->createSurface(b);
|
||||
for (int k = 0; k < t->tris.size(); ++k) {
|
||||
Surface::Triangle tri;
|
||||
for( int j=0;j<3;++j ){
|
||||
int n=t->tris[k].verts[j],id;
|
||||
map<int,int>::const_iterator it=vert_map.find( n );
|
||||
if( it!=vert_map.end() ) id=it->second;
|
||||
else{
|
||||
id=surf->numVertices();
|
||||
surf->addVertex( ml_mesh->verts[n] );
|
||||
vert_map.insert( make_pair( n,id ) );
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
int n = t->tris[k].verts[j], id;
|
||||
map<int, int>::const_iterator it = vert_map.find(n);
|
||||
if (it != vert_map.end())
|
||||
id = it->second;
|
||||
else {
|
||||
id = surf->numVertices();
|
||||
surf->addVertex(ml_mesh->verts[n]);
|
||||
vert_map.insert(make_pair(n, id));
|
||||
}
|
||||
tri.verts[j]=id;
|
||||
tri.verts[j] = id;
|
||||
}
|
||||
surf->addTriangle( tri );
|
||||
surf->addTriangle(tri);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete ml_mesh;
|
||||
ml_mesh=mesh_stack.back();
|
||||
ml_mesh = mesh_stack.back();
|
||||
mesh_stack.pop_back();
|
||||
}
|
||||
|
||||
@@ -5,38 +5,35 @@
|
||||
#include "model.hpp"
|
||||
#include "surface.hpp"
|
||||
|
||||
class MeshLoader{
|
||||
public:
|
||||
enum{
|
||||
HINT_COLLAPSE=1,
|
||||
HINT_ANIMONLY=2
|
||||
};
|
||||
class MeshLoader {
|
||||
public:
|
||||
enum { HINT_COLLAPSE = 1, HINT_ANIMONLY = 2 };
|
||||
|
||||
virtual MeshModel *load( const string &f,const Transform &conv,int hint )=0;
|
||||
virtual MeshModel* load(const string& f, const Transform& conv, int hint) = 0;
|
||||
|
||||
//clear
|
||||
static void beginMesh();
|
||||
|
||||
//add a vertex
|
||||
static void addVertex( const Surface::Vertex &v );
|
||||
static void addVertex(const Surface::Vertex& v);
|
||||
|
||||
//add a triangle
|
||||
static void addTriangle( const int verts[3],const Brush &b );
|
||||
static void addTriangle(const int verts[3], const Brush& b);
|
||||
|
||||
//also add a triangle
|
||||
static void addTriangle( int v0,int v1,int v2,const Brush &b );
|
||||
static void addTriangle(int v0, int v1, int v2, const Brush& b);
|
||||
|
||||
//add a bone
|
||||
static void addBone( int vert,float weight,int bone );
|
||||
static void addBone(int vert, float weight, int bone);
|
||||
|
||||
//reference a vertex
|
||||
static Surface::Vertex &refVertex( int vert );
|
||||
static Surface::Vertex& refVertex(int vert);
|
||||
|
||||
//number of verts
|
||||
static int numVertices();
|
||||
|
||||
//finally, update the mesh...
|
||||
static void endMesh( MeshModel *mesh );
|
||||
static void endMesh(MeshModel* mesh);
|
||||
};
|
||||
|
||||
#endif
|
||||
+107
-75
@@ -1,61 +1,68 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "meshmodel.hpp"
|
||||
#include "meshcollider.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
struct MeshModel::Rep : public Surface::Monitor {
|
||||
|
||||
int ref_cnt;
|
||||
mutable Box box, cullBox;
|
||||
mutable MeshCollider *collider;
|
||||
mutable MeshCollider* collider;
|
||||
mutable int box_valid, coll_valid, norms_valid;
|
||||
|
||||
SurfaceList surfaces;
|
||||
vector<Transform> bone_tforms;
|
||||
|
||||
Rep() :
|
||||
ref_cnt(1), collider(0), box_valid(-1), coll_valid(-1), norms_valid(-1) {
|
||||
Rep() : ref_cnt(1), collider(0), box_valid(-1), coll_valid(-1), norms_valid(-1)
|
||||
{
|
||||
geom_changes = brush_changes = 0;
|
||||
}
|
||||
|
||||
~Rep() {
|
||||
~Rep()
|
||||
{
|
||||
delete collider;
|
||||
for (int k = 0; k < surfaces.size(); ++k) delete surfaces[k];
|
||||
for (int k = 0; k < surfaces.size(); ++k)
|
||||
delete surfaces[k];
|
||||
}
|
||||
|
||||
Surface *createSurface(const Brush &b) {
|
||||
Surface *t = new Surface(this);
|
||||
Surface* createSurface(const Brush& b)
|
||||
{
|
||||
Surface* t = new Surface(this);
|
||||
surfaces.push_back(t);
|
||||
t->setBrush(b);
|
||||
return t;
|
||||
}
|
||||
|
||||
Surface *findSurface(const Brush &b) {
|
||||
Surface* findSurface(const Brush& b)
|
||||
{
|
||||
for (int k = 0; k < surfaces.size(); ++k) {
|
||||
Surface *s = surfaces[k];
|
||||
if (s->getBrush() < b || b < s->getBrush()) continue;
|
||||
Surface* s = surfaces[k];
|
||||
if (s->getBrush() < b || b < s->getBrush())
|
||||
continue;
|
||||
return s;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void paint(const Brush &b) {
|
||||
void paint(const Brush& b)
|
||||
{
|
||||
for (int k = 0; k < surfaces.size(); ++k) {
|
||||
Surface *s = surfaces[k];
|
||||
Surface* s = surfaces[k];
|
||||
s->setBrush(b);
|
||||
}
|
||||
}
|
||||
|
||||
void add(Rep *t) {
|
||||
void add(Rep* t)
|
||||
{
|
||||
if (cullBox.empty() && !t->cullBox.empty()) {
|
||||
setCullBox(t->cullBox);
|
||||
}
|
||||
for (int k = 0; k < t->surfaces.size(); ++k) {
|
||||
Surface *src = t->surfaces[k];
|
||||
Surface *dest = findSurface(src->getBrush());
|
||||
if (!dest) dest = createSurface(src->getBrush());
|
||||
Surface* src = t->surfaces[k];
|
||||
Surface* dest = findSurface(src->getBrush());
|
||||
if (!dest)
|
||||
dest = createSurface(src->getBrush());
|
||||
int j;
|
||||
for (j = 0; j < src->numTriangles(); ++j) {
|
||||
Surface::Triangle t = src->getTriangle(j);
|
||||
@@ -70,22 +77,24 @@ struct MeshModel::Rep : public Surface::Monitor {
|
||||
}
|
||||
}
|
||||
|
||||
void transform(const Transform &t) {
|
||||
void transform(const Transform& t)
|
||||
{
|
||||
Matrix co = t.m.cofactor();
|
||||
for (int k = 0; k < surfaces.size(); ++k) {
|
||||
Surface *s = surfaces[k];
|
||||
Surface* s = surfaces[k];
|
||||
for (int j = 0; j < s->numVertices(); ++j) {
|
||||
const Vector &v = s->getVertex(j).coords;
|
||||
const Vector &n = s->getVertex(j).normal;
|
||||
s->setCoords(j, t*v);
|
||||
s->setNormal(j, co*n);
|
||||
const Vector& v = s->getVertex(j).coords;
|
||||
const Vector& n = s->getVertex(j).normal;
|
||||
s->setCoords(j, t * v);
|
||||
s->setNormal(j, co * n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void flip() {
|
||||
void flip()
|
||||
{
|
||||
for (int k = 0; k < surfaces.size(); ++k) {
|
||||
Surface *s = surfaces[k];
|
||||
Surface* s = surfaces[k];
|
||||
int j;
|
||||
for (j = 0; j < s->numVertices(); ++j) {
|
||||
s->setNormal(j, -s->getVertex(j).normal);
|
||||
@@ -98,25 +107,28 @@ struct MeshModel::Rep : public Surface::Monitor {
|
||||
}
|
||||
}
|
||||
|
||||
void setCullBox(const Box &t) {
|
||||
void setCullBox(const Box& t)
|
||||
{
|
||||
cullBox = t;
|
||||
}
|
||||
|
||||
void updateNormals() {
|
||||
void updateNormals()
|
||||
{
|
||||
if (norms_valid != geom_changes) {
|
||||
for (int k = 0; k < surfaces.size(); ++k) {
|
||||
Surface *s = surfaces[k];
|
||||
Surface* s = surfaces[k];
|
||||
s->updateNormals();
|
||||
}
|
||||
norms_valid = geom_changes;
|
||||
}
|
||||
}
|
||||
|
||||
const Box &getBox()const {
|
||||
const Box& getBox() const
|
||||
{
|
||||
if (box_valid != geom_changes) {
|
||||
box.clear();
|
||||
for (int k = 0; k < surfaces.size(); ++k) {
|
||||
Surface *s = surfaces[k];
|
||||
Surface* s = surfaces[k];
|
||||
for (int j = 0; j < s->numVertices(); ++j) {
|
||||
box.update(s->getVertex(j).coords);
|
||||
}
|
||||
@@ -126,17 +138,19 @@ struct MeshModel::Rep : public Surface::Monitor {
|
||||
return box;
|
||||
}
|
||||
|
||||
const Box &getCullBox()const {
|
||||
const Box& getCullBox() const
|
||||
{
|
||||
return cullBox.empty() ? getBox() : cullBox;
|
||||
}
|
||||
|
||||
MeshCollider *getCollider()const {
|
||||
MeshCollider* getCollider() const
|
||||
{
|
||||
if (coll_valid != geom_changes) {
|
||||
delete collider;
|
||||
vector<MeshCollider::Vertex> verts;
|
||||
vector<MeshCollider::Triangle> tris;
|
||||
for (int k = 0; k < surfaces.size(); ++k) {
|
||||
Surface *s = surfaces[k];
|
||||
Surface* s = surfaces[k];
|
||||
int j;
|
||||
for (j = 0; j < s->numTriangles(); ++j) {
|
||||
MeshCollider::Triangle q;
|
||||
@@ -160,11 +174,10 @@ struct MeshModel::Rep : public Surface::Monitor {
|
||||
}
|
||||
};
|
||||
|
||||
MeshModel::MeshModel() :
|
||||
rep(new Rep()), brush_changes(0) {}
|
||||
MeshModel::MeshModel() : rep(new Rep()), brush_changes(0) {}
|
||||
|
||||
MeshModel::MeshModel(const MeshModel &t) : Model(t),
|
||||
rep(t.rep), brush_changes(rep->brush_changes - 1) {
|
||||
MeshModel::MeshModel(const MeshModel& t) : Model(t), rep(t.rep), brush_changes(rep->brush_changes - 1)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
surf_bones.resize(t.surf_bones.size());
|
||||
/*
|
||||
@@ -177,26 +190,32 @@ rep(t.rep), brush_changes(rep->brush_changes - 1) {
|
||||
*/
|
||||
}
|
||||
|
||||
MeshModel::~MeshModel() {
|
||||
if (!--rep->ref_cnt) delete rep;
|
||||
MeshModel::~MeshModel()
|
||||
{
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
}
|
||||
|
||||
void MeshModel::updateNormals() {
|
||||
void MeshModel::updateNormals()
|
||||
{
|
||||
rep->updateNormals();
|
||||
}
|
||||
|
||||
void MeshModel::setCullBox(const Box &box) {
|
||||
void MeshModel::setCullBox(const Box& box)
|
||||
{
|
||||
rep->setCullBox(box);
|
||||
}
|
||||
|
||||
void MeshModel::setRenderBrush(const Brush &b) {
|
||||
void MeshModel::setRenderBrush(const Brush& b)
|
||||
{
|
||||
--brush_changes;
|
||||
render_brush = b;
|
||||
}
|
||||
|
||||
void MeshModel::createBones() {
|
||||
void MeshModel::createBones()
|
||||
{
|
||||
setRenderSpace(RENDER_SPACE_WORLD);
|
||||
const vector<Object*> &bones = getAnimator()->getObjects();
|
||||
const vector<Object*>& bones = getAnimator()->getObjects();
|
||||
|
||||
surf_bones.resize(bones.size());
|
||||
|
||||
@@ -207,19 +226,21 @@ void MeshModel::createBones() {
|
||||
}
|
||||
}
|
||||
|
||||
bool MeshModel::render(const RenderContext &rc) {
|
||||
|
||||
const Box &b = rep->getCullBox();
|
||||
if (b.empty()) return false;
|
||||
bool MeshModel::render(const RenderContext& rc)
|
||||
{
|
||||
const Box& b = rep->getCullBox();
|
||||
if (b.empty())
|
||||
return false;
|
||||
|
||||
static Frustum model_frustum;
|
||||
new(&model_frustum) Frustum(rc.getWorldFrustum(), -getRenderTform());
|
||||
if (!model_frustum.cull(b)) return false;
|
||||
new (&model_frustum) Frustum(rc.getWorldFrustum(), -getRenderTform());
|
||||
if (!model_frustum.cull(b))
|
||||
return false;
|
||||
|
||||
if (brush_changes != rep->brush_changes) {
|
||||
brushes.clear();
|
||||
for (int k = 0; k < rep->surfaces.size(); ++k) {
|
||||
Surface *s = rep->surfaces[k];
|
||||
Surface* s = rep->surfaces[k];
|
||||
brushes.push_back(Brush(s->getBrush(), render_brush));
|
||||
}
|
||||
brush_changes = rep->brush_changes;
|
||||
@@ -227,8 +248,8 @@ bool MeshModel::render(const RenderContext &rc) {
|
||||
|
||||
if (!surf_bones.size()) {
|
||||
for (int k = 0; k < rep->surfaces.size(); ++k) {
|
||||
Surface *s = rep->surfaces[k];
|
||||
if (gxMesh *mesh = s->getMesh()) {
|
||||
Surface* s = rep->surfaces[k];
|
||||
if (gxMesh* mesh = s->getMesh()) {
|
||||
enqueue(mesh, 0, s->numVertices(), 0, s->numTriangles(), brushes[k]);
|
||||
}
|
||||
}
|
||||
@@ -236,21 +257,20 @@ bool MeshModel::render(const RenderContext &rc) {
|
||||
}
|
||||
|
||||
//OK, its boned!
|
||||
const vector<Object*> &bones = getAnimator()->getObjects();
|
||||
const vector<Object*>& bones = getAnimator()->getObjects();
|
||||
|
||||
int k;
|
||||
for (k = 0; k < bones.size(); ++k) {
|
||||
Transform t =
|
||||
bones[k]->getRenderTform() * rep->bone_tforms[k];
|
||||
Transform t = bones[k]->getRenderTform() * rep->bone_tforms[k];
|
||||
surf_bones[k].coord_tform = t;
|
||||
surf_bones[k].normal_tform = t.m.cofactor();
|
||||
}
|
||||
|
||||
bool trans = false;
|
||||
for (k = 0; k < rep->surfaces.size(); ++k) {
|
||||
Surface *s = rep->surfaces[k];
|
||||
Surface* s = rep->surfaces[k];
|
||||
if (brushes[k].getBlend() == gxScene::BLEND_REPLACE) {
|
||||
if (gxMesh *mesh = s->getMesh(surf_bones)) {
|
||||
if (gxMesh* mesh = s->getMesh(surf_bones)) {
|
||||
enqueue(mesh, 0, s->numVertices(), 0, s->numTriangles(), brushes[k]);
|
||||
}
|
||||
} else {
|
||||
@@ -260,12 +280,13 @@ bool MeshModel::render(const RenderContext &rc) {
|
||||
return trans;
|
||||
}
|
||||
|
||||
void MeshModel::renderQueue(int type) {
|
||||
void MeshModel::renderQueue(int type)
|
||||
{
|
||||
if (type == QUEUE_TRANSPARENT && surf_bones.size()) {
|
||||
for (int k = 0; k < rep->surfaces.size(); ++k) {
|
||||
Surface *s = rep->surfaces[k];
|
||||
Surface* s = rep->surfaces[k];
|
||||
if (brushes[k].getBlend() != gxScene::BLEND_REPLACE) {
|
||||
if (gxMesh *mesh = s->getMesh(surf_bones)) {
|
||||
if (gxMesh* mesh = s->getMesh(surf_bones)) {
|
||||
enqueue(mesh, 0, s->numVertices(), 0, s->numTriangles(), brushes[k]);
|
||||
}
|
||||
}
|
||||
@@ -274,47 +295,58 @@ void MeshModel::renderQueue(int type) {
|
||||
Model::renderQueue(type);
|
||||
}
|
||||
|
||||
Surface *MeshModel::createSurface(const Brush &b) {
|
||||
Surface* MeshModel::createSurface(const Brush& b)
|
||||
{
|
||||
return rep->createSurface(b);
|
||||
--brush_changes;
|
||||
}
|
||||
|
||||
void MeshModel::flipTriangles() {
|
||||
void MeshModel::flipTriangles()
|
||||
{
|
||||
rep->flip();
|
||||
}
|
||||
|
||||
void MeshModel::transform(const Transform &t) {
|
||||
void MeshModel::transform(const Transform& t)
|
||||
{
|
||||
rep->transform(t);
|
||||
}
|
||||
|
||||
void MeshModel::add(const MeshModel &t) {
|
||||
void MeshModel::add(const MeshModel& t)
|
||||
{
|
||||
rep->add(t.rep);
|
||||
}
|
||||
|
||||
const MeshModel::SurfaceList &MeshModel::getSurfaces()const {
|
||||
const MeshModel::SurfaceList& MeshModel::getSurfaces() const
|
||||
{
|
||||
return rep->surfaces;
|
||||
}
|
||||
|
||||
void MeshModel::paint(const Brush &b) {
|
||||
void MeshModel::paint(const Brush& b)
|
||||
{
|
||||
rep->paint(b);
|
||||
}
|
||||
|
||||
const Box &MeshModel::getBox()const {
|
||||
const Box& MeshModel::getBox() const
|
||||
{
|
||||
return rep->getBox();
|
||||
}
|
||||
|
||||
MeshCollider *MeshModel::getCollider()const {
|
||||
MeshCollider* MeshModel::getCollider() const
|
||||
{
|
||||
return rep->getCollider();
|
||||
}
|
||||
|
||||
Surface *MeshModel::findSurface(const Brush &b)const {
|
||||
Surface* MeshModel::findSurface(const Brush& b) const
|
||||
{
|
||||
return rep->findSurface(b);
|
||||
}
|
||||
|
||||
bool MeshModel::collide(const Line &line, float radius, Collision *curr_coll, const Transform &t) {
|
||||
bool MeshModel::collide(const Line& line, float radius, Collision* curr_coll, const Transform& t)
|
||||
{
|
||||
return getCollider()->collide(line, radius, curr_coll, t);
|
||||
}
|
||||
|
||||
bool MeshModel::intersects(const MeshModel &m)const {
|
||||
return getCollider()->intersects(*m.getCollider(), -m.GetWorldTransform()*GetWorldTransform());
|
||||
bool MeshModel::intersects(const MeshModel& m) const
|
||||
{
|
||||
return getCollider()->intersects(*m.getCollider(), -m.GetWorldTransform() * GetWorldTransform());
|
||||
}
|
||||
|
||||
@@ -7,57 +7,63 @@
|
||||
|
||||
class MeshCollider;
|
||||
|
||||
class MeshModel : public Model{
|
||||
public:
|
||||
class MeshModel : public Model {
|
||||
public:
|
||||
typedef vector<Surface*> SurfaceList;
|
||||
|
||||
MeshModel();
|
||||
MeshModel( const MeshModel &t );
|
||||
MeshModel(const MeshModel& t);
|
||||
~MeshModel();
|
||||
|
||||
//Entity interface
|
||||
virtual MeshModel *getMeshModel(){ return this; }
|
||||
virtual Entity *clone(){ return new MeshModel( *this ); }
|
||||
virtual MeshModel* getMeshModel()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
virtual Entity* clone()
|
||||
{
|
||||
return new MeshModel(*this);
|
||||
}
|
||||
|
||||
//Object interface
|
||||
virtual bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &t );
|
||||
virtual bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& t);
|
||||
|
||||
//Model interface
|
||||
virtual void setRenderBrush( const Brush &b );
|
||||
virtual bool render( const RenderContext &rc );
|
||||
virtual void renderQueue( int type );
|
||||
virtual void setRenderBrush(const Brush& b);
|
||||
virtual bool render(const RenderContext& rc);
|
||||
virtual void renderQueue(int type);
|
||||
|
||||
//boned mesh!
|
||||
void createBones();
|
||||
|
||||
//MeshModel interface
|
||||
Surface *createSurface( const Brush &b );
|
||||
void setCullBox( const Box &box );
|
||||
Surface* createSurface(const Brush& b);
|
||||
void setCullBox(const Box& box);
|
||||
void updateNormals();
|
||||
void flipTriangles();
|
||||
void transform( const Transform &t );
|
||||
void paint( const Brush &b );
|
||||
void add( const MeshModel &t );
|
||||
void transform(const Transform& t);
|
||||
void paint(const Brush& b);
|
||||
void add(const MeshModel& t);
|
||||
void optimize();
|
||||
|
||||
//accessors
|
||||
const SurfaceList &getSurfaces()const;
|
||||
Surface *findSurface( const Brush &b )const;
|
||||
bool intersects( const MeshModel &m )const;
|
||||
MeshCollider *getCollider()const;
|
||||
const Box &getBox()const;
|
||||
const SurfaceList& getSurfaces() const;
|
||||
Surface* findSurface(const Brush& b) const;
|
||||
bool intersects(const MeshModel& m) const;
|
||||
MeshCollider* getCollider() const;
|
||||
const Box& getBox() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Rep;
|
||||
|
||||
Rep *rep;
|
||||
Rep* rep;
|
||||
int brush_changes;
|
||||
Brush render_brush;
|
||||
vector<Brush> brushes;
|
||||
|
||||
vector<Surface::Bone> surf_bones;
|
||||
|
||||
MeshModel &operator=(const MeshModel &);
|
||||
MeshModel& operator=(const MeshModel&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
#include "mesh.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
class MeshRenderer{
|
||||
public:
|
||||
MeshRenderer( const Mesh &t );
|
||||
class MeshRenderer {
|
||||
public:
|
||||
MeshRenderer(const Mesh& t);
|
||||
~MeshRenderer();
|
||||
|
||||
void render( Camera *c,Model *m )const;
|
||||
void render(Camera* c, Model* m) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
Box box;
|
||||
struct Surface;
|
||||
vector<Surface*> surfs;
|
||||
|
||||
MeshRenderer( const MeshRenderer &t );
|
||||
MeshRenderer &operator=(const MeshRenderer&);
|
||||
MeshRenderer(const MeshRenderer& t);
|
||||
MeshRenderer& operator=(const MeshRenderer&);
|
||||
};
|
||||
|
||||
#endif
|
||||
+208
-199
@@ -1,228 +1,237 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "meshutil.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
MeshModel *MeshUtil::createCube( const Brush &b ){
|
||||
static Vector norms[]={
|
||||
Vector(0,0,-1),Vector(1,0,0),Vector(0,0,1),
|
||||
Vector(-1,0,0),Vector(0,1,0),Vector(0,-1,0)
|
||||
};
|
||||
static Vector tex_coords[]={
|
||||
Vector(0,0,1),Vector(1,0,1),Vector(1,1,1),Vector(0,1,1)
|
||||
};
|
||||
static int verts[]={
|
||||
2,3,1,0,3,7,5,1,7,6,4,5,6,2,0,4,6,7,3,2,0,1,5,4
|
||||
};
|
||||
static Box box( Vector(-1,-1,-1),Vector(1,1,1) );
|
||||
MeshModel* MeshUtil::createCube(const Brush& b)
|
||||
{
|
||||
static Vector norms[] = {Vector(0, 0, -1), Vector(1, 0, 0), Vector(0, 0, 1),
|
||||
Vector(-1, 0, 0), Vector(0, 1, 0), Vector(0, -1, 0)};
|
||||
static Vector tex_coords[] = {Vector(0, 0, 1), Vector(1, 0, 1), Vector(1, 1, 1), Vector(0, 1, 1)};
|
||||
static int verts[] = {2, 3, 1, 0, 3, 7, 5, 1, 7, 6, 4, 5, 6, 2, 0, 4, 6, 7, 3, 2, 0, 1, 5, 4};
|
||||
static Box box(Vector(-1, -1, -1), Vector(1, 1, 1));
|
||||
|
||||
MeshModel *m=new MeshModel();
|
||||
Surface *s=m->createSurface( b );
|
||||
MeshModel* m = new MeshModel();
|
||||
Surface* s = m->createSurface(b);
|
||||
Surface::Vertex v;
|
||||
Surface::Triangle t;
|
||||
for( int k=0;k<24;k+=4 ){
|
||||
const Vector &normal=norms[k/4];
|
||||
for( int j=0;j<4;++j ){
|
||||
v.coords=box.corner( verts[k+j] );
|
||||
v.normal=normal;
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=tex_coords[j].x;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=tex_coords[j].y;
|
||||
s->addVertex( v );
|
||||
}
|
||||
t.verts[0]=k;t.verts[1]=k+1;t.verts[2]=k+2;s->addTriangle(t);
|
||||
t.verts[1]=k+2;t.verts[2]=k+3;s->addTriangle(t);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
MeshModel *MeshUtil::createSphere( const Brush &b,int segs ){
|
||||
|
||||
int h_segs=segs*2,v_segs=segs;
|
||||
|
||||
MeshModel *m=new MeshModel();
|
||||
Surface *s=m->createSurface( b );
|
||||
|
||||
Surface::Vertex v;
|
||||
Surface::Triangle t;
|
||||
|
||||
v.coords=v.normal=Vector(0,1,0);
|
||||
int k;
|
||||
for( k=0;k<h_segs;++k ){
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=(k+.5f)/h_segs;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=0;
|
||||
s->addVertex( v );
|
||||
}
|
||||
for( k=1;k<v_segs;++k ){
|
||||
float pitch=k*PI/v_segs-HALFPI;
|
||||
for( int j=0;j<=h_segs;++j ){
|
||||
float yaw=(j%h_segs)*TWOPI/h_segs;
|
||||
v.coords=v.normal=rotationMatrix( pitch,yaw,0 ).k;
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=float(j)/float(h_segs);
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=float(k)/float(v_segs);
|
||||
s->addVertex( v );
|
||||
}
|
||||
}
|
||||
v.coords=v.normal=Vector(0,-1,0);
|
||||
for( k=0;k<h_segs;++k ){
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=(k+.5f)/h_segs;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=1;
|
||||
s->addVertex( v );
|
||||
}
|
||||
for( k=0;k<h_segs;++k ){
|
||||
t.verts[0]=k;
|
||||
t.verts[1]=t.verts[0]+h_segs+1;
|
||||
t.verts[2]=t.verts[1]-1;
|
||||
s->addTriangle( t );
|
||||
}
|
||||
for( k=1;k<v_segs-1;++k ){
|
||||
for( int j=0;j<h_segs;++j ){
|
||||
t.verts[0]=k*(h_segs+1)+j-1;
|
||||
t.verts[1]=t.verts[0]+1;
|
||||
t.verts[2]=t.verts[1]+h_segs+1;
|
||||
s->addTriangle( t );
|
||||
t.verts[1]=t.verts[2];
|
||||
t.verts[2]=t.verts[1]-1;
|
||||
s->addTriangle( t );
|
||||
}
|
||||
}
|
||||
for( k=0;k<h_segs;++k ){
|
||||
t.verts[0]=(h_segs+1)*(v_segs-1)+k-1;
|
||||
t.verts[1]=t.verts[0]+1;
|
||||
t.verts[2]=t.verts[1]+h_segs;
|
||||
s->addTriangle( t );
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
MeshModel *MeshUtil::createCylinder( const Brush &b,int segs,bool solid ){
|
||||
|
||||
MeshModel *m=new MeshModel();
|
||||
Surface::Vertex v;
|
||||
Surface::Triangle t;
|
||||
|
||||
Surface *s=m->createSurface( b );
|
||||
int k;
|
||||
for( k=0;k<=segs;++k ){
|
||||
float yaw=(k%segs)*TWOPI/segs;
|
||||
v.coords=rotationMatrix( 0,yaw,0 ).k;
|
||||
v.coords.y=1;
|
||||
v.normal=Vector(v.coords.x,0,v.coords.z);
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=float(k)/segs;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=0;
|
||||
s->addVertex( v );
|
||||
v.coords.y=-1;
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=float(k)/segs;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=1;
|
||||
s->addVertex( v );
|
||||
}
|
||||
for( k=0;k<segs;++k ){
|
||||
t.verts[0]=k*2;
|
||||
t.verts[1]=t.verts[0]+2;
|
||||
t.verts[2]=t.verts[1]+1;
|
||||
s->addTriangle( t );
|
||||
t.verts[1]=t.verts[2];
|
||||
t.verts[2]=t.verts[1]-2;
|
||||
s->addTriangle( t );
|
||||
}
|
||||
|
||||
if( !solid ) return m;
|
||||
|
||||
s=m->createSurface( b );
|
||||
|
||||
for( k=0;k<segs;++k ){
|
||||
float yaw=k*TWOPI/segs;
|
||||
v.coords=rotationMatrix( 0,yaw,0 ).k;
|
||||
v.coords.y=1;v.normal=Vector(0,1,0);
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=v.coords.x*.5f+.5f;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=v.coords.z*.5f+.5f;
|
||||
s->addVertex(v);
|
||||
v.coords.y=-1;v.normal=Vector( 0,-1,0 );
|
||||
for (int k = 0; k < 24; k += 4) {
|
||||
const Vector& normal = norms[k / 4];
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
v.coords = box.corner(verts[k + j]);
|
||||
v.normal = normal;
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = tex_coords[j].x;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = tex_coords[j].y;
|
||||
s->addVertex(v);
|
||||
}
|
||||
for( k=2;k<segs;++k ){
|
||||
t.verts[0]=0;
|
||||
t.verts[1]=k*2;
|
||||
t.verts[2]=(k-1)*2;
|
||||
s->addTriangle( t );
|
||||
t.verts[0]=1;
|
||||
t.verts[1]=(k-1)*2+1;
|
||||
t.verts[2]=k*2+1;
|
||||
s->addTriangle( t );
|
||||
t.verts[0] = k;
|
||||
t.verts[1] = k + 1;
|
||||
t.verts[2] = k + 2;
|
||||
s->addTriangle(t);
|
||||
t.verts[1] = k + 2;
|
||||
t.verts[2] = k + 3;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
MeshModel *MeshUtil::createCone( const Brush &b,int segs,bool solid ){
|
||||
MeshModel *m=new MeshModel();
|
||||
MeshModel* MeshUtil::createSphere(const Brush& b, int segs)
|
||||
{
|
||||
int h_segs = segs * 2, v_segs = segs;
|
||||
|
||||
MeshModel* m = new MeshModel();
|
||||
Surface* s = m->createSurface(b);
|
||||
|
||||
Surface::Vertex v;
|
||||
Surface::Triangle t;
|
||||
|
||||
Surface *s;
|
||||
s=m->createSurface( b );
|
||||
v.coords = v.normal = Vector(0, 1, 0);
|
||||
int k;
|
||||
v.coords=v.normal=Vector(0,1,0);
|
||||
for( k=0;k<segs;++k ){
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=(k+.5f)/segs;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=0;
|
||||
s->addVertex( v );
|
||||
for (k = 0; k < h_segs; ++k) {
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = (k + .5f) / h_segs;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = 0;
|
||||
s->addVertex(v);
|
||||
}
|
||||
for( k=0;k<=segs;++k ){
|
||||
float yaw=(k%segs)*TWOPI/segs;
|
||||
v.coords=yawMatrix( yaw ).k;v.coords.y=-1;
|
||||
v.normal=Vector( v.coords.x,0,v.coords.z );
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=float(k)/segs;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=1;
|
||||
s->addVertex( v );
|
||||
for (k = 1; k < v_segs; ++k) {
|
||||
float pitch = k * PI / v_segs - HALFPI;
|
||||
for (int j = 0; j <= h_segs; ++j) {
|
||||
float yaw = (j % h_segs) * TWOPI / h_segs;
|
||||
v.coords = v.normal = rotationMatrix(pitch, yaw, 0).k;
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = float(j) / float(h_segs);
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = float(k) / float(v_segs);
|
||||
s->addVertex(v);
|
||||
}
|
||||
for( k=0;k<segs;++k ){
|
||||
t.verts[0]=k;
|
||||
t.verts[1]=k+segs+1;
|
||||
t.verts[2]=k+segs;
|
||||
s->addTriangle( t );
|
||||
}
|
||||
if( !solid ) return m;
|
||||
s=m->createSurface( b );
|
||||
for( k=0;k<segs;++k ){
|
||||
float yaw=k*TWOPI/segs;
|
||||
v.coords=yawMatrix( yaw ).k;v.coords.y=-1;
|
||||
v.normal=Vector( v.coords.x,0,v.coords.z );
|
||||
v.tex_coords[0][0]=v.tex_coords[1][0]=v.coords.x*.5f+.5f;
|
||||
v.tex_coords[0][1]=v.tex_coords[1][1]=v.coords.z*.5f+.5f;
|
||||
s->addVertex( v );
|
||||
v.coords = v.normal = Vector(0, -1, 0);
|
||||
for (k = 0; k < h_segs; ++k) {
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = (k + .5f) / h_segs;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = 1;
|
||||
s->addVertex(v);
|
||||
}
|
||||
t.verts[0]=0;
|
||||
for( k=2;k<segs;++k ){
|
||||
t.verts[1]=k-1;
|
||||
t.verts[2]=k;
|
||||
s->addTriangle( t );
|
||||
for (k = 0; k < h_segs; ++k) {
|
||||
t.verts[0] = k;
|
||||
t.verts[1] = t.verts[0] + h_segs + 1;
|
||||
t.verts[2] = t.verts[1] - 1;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
for (k = 1; k < v_segs - 1; ++k) {
|
||||
for (int j = 0; j < h_segs; ++j) {
|
||||
t.verts[0] = k * (h_segs + 1) + j - 1;
|
||||
t.verts[1] = t.verts[0] + 1;
|
||||
t.verts[2] = t.verts[1] + h_segs + 1;
|
||||
s->addTriangle(t);
|
||||
t.verts[1] = t.verts[2];
|
||||
t.verts[2] = t.verts[1] - 1;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
}
|
||||
for (k = 0; k < h_segs; ++k) {
|
||||
t.verts[0] = (h_segs + 1) * (v_segs - 1) + k - 1;
|
||||
t.verts[1] = t.verts[0] + 1;
|
||||
t.verts[2] = t.verts[1] + h_segs;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
MeshModel* MeshUtil::createCylinder(const Brush& b, int segs, bool solid)
|
||||
{
|
||||
MeshModel* m = new MeshModel();
|
||||
Surface::Vertex v;
|
||||
Surface::Triangle t;
|
||||
|
||||
Surface* s = m->createSurface(b);
|
||||
int k;
|
||||
for (k = 0; k <= segs; ++k) {
|
||||
float yaw = (k % segs) * TWOPI / segs;
|
||||
v.coords = rotationMatrix(0, yaw, 0).k;
|
||||
v.coords.y = 1;
|
||||
v.normal = Vector(v.coords.x, 0, v.coords.z);
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = float(k) / segs;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = 0;
|
||||
s->addVertex(v);
|
||||
v.coords.y = -1;
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = float(k) / segs;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = 1;
|
||||
s->addVertex(v);
|
||||
}
|
||||
for (k = 0; k < segs; ++k) {
|
||||
t.verts[0] = k * 2;
|
||||
t.verts[1] = t.verts[0] + 2;
|
||||
t.verts[2] = t.verts[1] + 1;
|
||||
s->addTriangle(t);
|
||||
t.verts[1] = t.verts[2];
|
||||
t.verts[2] = t.verts[1] - 2;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
|
||||
if (!solid)
|
||||
return m;
|
||||
|
||||
s = m->createSurface(b);
|
||||
|
||||
for (k = 0; k < segs; ++k) {
|
||||
float yaw = k * TWOPI / segs;
|
||||
v.coords = rotationMatrix(0, yaw, 0).k;
|
||||
v.coords.y = 1;
|
||||
v.normal = Vector(0, 1, 0);
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = v.coords.x * .5f + .5f;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = v.coords.z * .5f + .5f;
|
||||
s->addVertex(v);
|
||||
v.coords.y = -1;
|
||||
v.normal = Vector(0, -1, 0);
|
||||
s->addVertex(v);
|
||||
}
|
||||
for (k = 2; k < segs; ++k) {
|
||||
t.verts[0] = 0;
|
||||
t.verts[1] = k * 2;
|
||||
t.verts[2] = (k - 1) * 2;
|
||||
s->addTriangle(t);
|
||||
t.verts[0] = 1;
|
||||
t.verts[1] = (k - 1) * 2 + 1;
|
||||
t.verts[2] = k * 2 + 1;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
MeshModel* MeshUtil::createCone(const Brush& b, int segs, bool solid)
|
||||
{
|
||||
MeshModel* m = new MeshModel();
|
||||
Surface::Vertex v;
|
||||
Surface::Triangle t;
|
||||
|
||||
Surface* s;
|
||||
s = m->createSurface(b);
|
||||
int k;
|
||||
v.coords = v.normal = Vector(0, 1, 0);
|
||||
for (k = 0; k < segs; ++k) {
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = (k + .5f) / segs;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = 0;
|
||||
s->addVertex(v);
|
||||
}
|
||||
for (k = 0; k <= segs; ++k) {
|
||||
float yaw = (k % segs) * TWOPI / segs;
|
||||
v.coords = yawMatrix(yaw).k;
|
||||
v.coords.y = -1;
|
||||
v.normal = Vector(v.coords.x, 0, v.coords.z);
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = float(k) / segs;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = 1;
|
||||
s->addVertex(v);
|
||||
}
|
||||
for (k = 0; k < segs; ++k) {
|
||||
t.verts[0] = k;
|
||||
t.verts[1] = k + segs + 1;
|
||||
t.verts[2] = k + segs;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
if (!solid)
|
||||
return m;
|
||||
s = m->createSurface(b);
|
||||
for (k = 0; k < segs; ++k) {
|
||||
float yaw = k * TWOPI / segs;
|
||||
v.coords = yawMatrix(yaw).k;
|
||||
v.coords.y = -1;
|
||||
v.normal = Vector(v.coords.x, 0, v.coords.z);
|
||||
v.tex_coords[0][0] = v.tex_coords[1][0] = v.coords.x * .5f + .5f;
|
||||
v.tex_coords[0][1] = v.tex_coords[1][1] = v.coords.z * .5f + .5f;
|
||||
s->addVertex(v);
|
||||
}
|
||||
t.verts[0] = 0;
|
||||
for (k = 2; k < segs; ++k) {
|
||||
t.verts[1] = k - 1;
|
||||
t.verts[2] = k;
|
||||
s->addTriangle(t);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void MeshUtil::lightMesh( MeshModel *m,const Vector &pos,const Vector &rgb,float range ){
|
||||
if( range ){
|
||||
float att=1.0f/range;
|
||||
const MeshModel::SurfaceList &surfs=m->getSurfaces();
|
||||
for( int k=0;k<surfs.size();++k ){
|
||||
Surface *s=surfs[k];
|
||||
for( int j=0;j<s->numVertices();++j ){
|
||||
const Surface::Vertex &v=s->getVertex( j );
|
||||
Vector lv=pos-v.coords;
|
||||
float dp=v.normal.normalized().dot( lv );
|
||||
if( dp<=0 ) continue;
|
||||
float d=lv.length();
|
||||
float i=1/(d*att)*(dp/d);
|
||||
s->setColor( j,s->getColor(j)+rgb*i );
|
||||
void MeshUtil::lightMesh(MeshModel* m, const Vector& pos, const Vector& rgb, float range)
|
||||
{
|
||||
if (range) {
|
||||
float att = 1.0f / range;
|
||||
const MeshModel::SurfaceList& surfs = m->getSurfaces();
|
||||
for (int k = 0; k < surfs.size(); ++k) {
|
||||
Surface* s = surfs[k];
|
||||
for (int j = 0; j < s->numVertices(); ++j) {
|
||||
const Surface::Vertex& v = s->getVertex(j);
|
||||
Vector lv = pos - v.coords;
|
||||
float dp = v.normal.normalized().dot(lv);
|
||||
if (dp <= 0)
|
||||
continue;
|
||||
float d = lv.length();
|
||||
float i = 1 / (d * att) * (dp / d);
|
||||
s->setColor(j, s->getColor(j) + rgb * i);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
const MeshModel::SurfaceList &surfs=m->getSurfaces();
|
||||
for( int k=0;k<surfs.size();++k ){
|
||||
Surface *s=surfs[k];
|
||||
for( int j=0;j<s->numVertices();++j ){
|
||||
const Surface::Vertex &v=s->getVertex( j );
|
||||
s->setColor( j,s->getColor(j)+rgb );
|
||||
} else {
|
||||
const MeshModel::SurfaceList& surfs = m->getSurfaces();
|
||||
for (int k = 0; k < surfs.size(); ++k) {
|
||||
Surface* s = surfs[k];
|
||||
for (int j = 0; j < s->numVertices(); ++j) {
|
||||
const Surface::Vertex& v = s->getVertex(j);
|
||||
s->setColor(j, s->getColor(j) + rgb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
|
||||
#include "meshmodel.hpp"
|
||||
|
||||
struct MeshUtil{
|
||||
struct MeshUtil {
|
||||
static MeshModel* createCube(const Brush& b);
|
||||
static MeshModel* createSphere(const Brush& b, int segs);
|
||||
static MeshModel* createCylinder(const Brush& b, int segs, bool solid);
|
||||
static MeshModel* createCone(const Brush& b, int segs, bool solid);
|
||||
|
||||
static MeshModel *createCube( const Brush &b );
|
||||
static MeshModel *createSphere( const Brush &b,int segs );
|
||||
static MeshModel *createCylinder( const Brush &b,int segs,bool solid );
|
||||
static MeshModel *createCone( const Brush &b,int segs,bool solid );
|
||||
|
||||
static void lightMesh( MeshModel *m,const Vector &pos,const Vector &rgb,float range );
|
||||
static void lightMesh(MeshModel* m, const Vector& pos, const Vector& rgb, float range);
|
||||
|
||||
/*
|
||||
static void flipMesh( Mesh *m );
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "mirror.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
Mirror::Mirror(){
|
||||
}
|
||||
Mirror::Mirror() {}
|
||||
|
||||
Mirror::Mirror( const Mirror &t ):
|
||||
Object(t){
|
||||
}
|
||||
Mirror::Mirror(const Mirror& t) : Object(t) {}
|
||||
|
||||
Mirror::~Mirror(){
|
||||
}
|
||||
Mirror::~Mirror() {}
|
||||
@@ -4,15 +4,21 @@
|
||||
|
||||
#include "object.hpp"
|
||||
|
||||
class Mirror : public Object{
|
||||
public:
|
||||
class Mirror : public Object {
|
||||
public:
|
||||
Mirror();
|
||||
Mirror( const Mirror &t );
|
||||
Mirror(const Mirror& t);
|
||||
~Mirror();
|
||||
|
||||
//Entity interface
|
||||
Entity *clone(){ return new Mirror( *this ); }
|
||||
Mirror *getMirror(){ return this; }
|
||||
Entity* clone()
|
||||
{
|
||||
return new Mirror(*this);
|
||||
}
|
||||
Mirror* getMirror()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
+86
-74
@@ -1,128 +1,140 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "model.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxScene *gx_scene;
|
||||
extern gxScene* gx_scene;
|
||||
|
||||
class Model::MeshQueue{
|
||||
union{
|
||||
gxMesh *mesh;
|
||||
MeshQueue *next;
|
||||
class Model::MeshQueue {
|
||||
union {
|
||||
gxMesh* mesh;
|
||||
MeshQueue* next;
|
||||
};
|
||||
int fv,vc,ft,tc;
|
||||
int fv, vc, ft, tc;
|
||||
Brush brush;
|
||||
int q_type;
|
||||
// bool opaque;
|
||||
// bool opaque;
|
||||
|
||||
static MeshQueue *pool;
|
||||
static MeshQueue* pool;
|
||||
|
||||
public:
|
||||
MeshQueue(){}
|
||||
public:
|
||||
MeshQueue() {}
|
||||
|
||||
MeshQueue( gxMesh *m,int fv,int vc,int ft,int tc,const Brush &b ):
|
||||
mesh(m),fv(fv),vc(vc),ft(ft),tc(tc),brush(b){
|
||||
int n=brush.getBlend();
|
||||
q_type=(n==gxScene::BLEND_REPLACE) ? QUEUE_OPAQUE : QUEUE_TRANSPARENT;
|
||||
MeshQueue(gxMesh* m, int fv, int vc, int ft, int tc, const Brush& b)
|
||||
: mesh(m), fv(fv), vc(vc), ft(ft), tc(tc), brush(b)
|
||||
{
|
||||
int n = brush.getBlend();
|
||||
q_type = (n == gxScene::BLEND_REPLACE) ? QUEUE_OPAQUE : QUEUE_TRANSPARENT;
|
||||
}
|
||||
|
||||
int getQueueType()const{
|
||||
int getQueueType() const
|
||||
{
|
||||
return q_type;
|
||||
}
|
||||
void render(){
|
||||
gx_scene->setRenderState( brush.getRenderState() );
|
||||
gx_scene->render( mesh,fv,vc,ft,tc );
|
||||
void render()
|
||||
{
|
||||
gx_scene->setRenderState(brush.getRenderState());
|
||||
gx_scene->render(mesh, fv, vc, ft, tc);
|
||||
}
|
||||
void *operator new( size_t sz ){
|
||||
static const int GROW=256;
|
||||
if( !pool ){
|
||||
pool=new MeshQueue[GROW];
|
||||
for( int k=0;k<GROW-1;++k ) pool[k].next=&pool[k+1];
|
||||
pool[GROW-1].next=0;
|
||||
void* operator new(size_t sz)
|
||||
{
|
||||
static const int GROW = 256;
|
||||
if (!pool) {
|
||||
pool = new MeshQueue[GROW];
|
||||
for (int k = 0; k < GROW - 1; ++k)
|
||||
pool[k].next = &pool[k + 1];
|
||||
pool[GROW - 1].next = 0;
|
||||
}
|
||||
MeshQueue *t=pool;
|
||||
pool=t->next;
|
||||
MeshQueue* t = pool;
|
||||
pool = t->next;
|
||||
return t;
|
||||
}
|
||||
void operator delete( void *q ){
|
||||
MeshQueue *t=(MeshQueue*)q;
|
||||
t->next=pool;
|
||||
pool=t;
|
||||
void operator delete(void* q)
|
||||
{
|
||||
MeshQueue* t = (MeshQueue*)q;
|
||||
t->next = pool;
|
||||
pool = t;
|
||||
}
|
||||
};
|
||||
|
||||
Model::MeshQueue *Model::MeshQueue::pool;
|
||||
Model::MeshQueue* Model::MeshQueue::pool;
|
||||
|
||||
Model::Model():
|
||||
space( RENDER_SPACE_LOCAL ),
|
||||
auto_fade(false),
|
||||
captured_alpha(1),w_brush(true){
|
||||
}
|
||||
Model::Model() : space(RENDER_SPACE_LOCAL), auto_fade(false), captured_alpha(1), w_brush(true) {}
|
||||
|
||||
Model::Model( const Model &t ):Object(t),
|
||||
space(t.space),brush(t.brush),
|
||||
auto_fade(t.auto_fade),auto_fade_nr(t.auto_fade_nr),auto_fade_fr(t.auto_fade_fr),
|
||||
captured_alpha(t.captured_alpha),w_brush(true){
|
||||
}
|
||||
Model::Model(const Model& t)
|
||||
: Object(t), space(t.space), brush(t.brush), auto_fade(t.auto_fade), auto_fade_nr(t.auto_fade_nr),
|
||||
auto_fade_fr(t.auto_fade_fr), captured_alpha(t.captured_alpha), w_brush(true)
|
||||
{}
|
||||
|
||||
void Model::capture(){
|
||||
void Model::capture()
|
||||
{
|
||||
Object::capture();
|
||||
captured_alpha=brush.getAlpha();
|
||||
captured_alpha = brush.getAlpha();
|
||||
}
|
||||
|
||||
bool Model::beginRender( float t ){
|
||||
Object::beginRender( t );
|
||||
tweened_alpha=brush.getAlpha();
|
||||
if( t!=1 && tweened_alpha!=captured_alpha ){
|
||||
bool Model::beginRender(float t)
|
||||
{
|
||||
Object::beginRender(t);
|
||||
tweened_alpha = brush.getAlpha();
|
||||
if (t != 1 && tweened_alpha != captured_alpha) {
|
||||
//
|
||||
//render tweening of alpha
|
||||
//
|
||||
tweened_alpha=(tweened_alpha-captured_alpha)*t+captured_alpha;
|
||||
tweened_alpha = (tweened_alpha - captured_alpha) * t + captured_alpha;
|
||||
}
|
||||
return tweened_alpha>0;
|
||||
return tweened_alpha > 0;
|
||||
}
|
||||
|
||||
bool Model::doAutoFade( const Vector &eye ){
|
||||
float alpha=tweened_alpha;
|
||||
if( auto_fade ){
|
||||
bool Model::doAutoFade(const Vector& eye)
|
||||
{
|
||||
float alpha = tweened_alpha;
|
||||
if (auto_fade) {
|
||||
//
|
||||
//autofading of alpha
|
||||
//
|
||||
float d=eye.distance( getRenderTform().v );
|
||||
if( d>=auto_fade_fr ) return false;
|
||||
if( d>=auto_fade_nr ){
|
||||
float t=1-(d-auto_fade_nr)/(auto_fade_fr-auto_fade_nr );
|
||||
alpha*=t;if( alpha<=0 ) return false;
|
||||
float d = eye.distance(getRenderTform().v);
|
||||
if (d >= auto_fade_fr)
|
||||
return false;
|
||||
if (d >= auto_fade_nr) {
|
||||
float t = 1 - (d - auto_fade_nr) / (auto_fade_fr - auto_fade_nr);
|
||||
alpha *= t;
|
||||
if (alpha <= 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if( w_brush ) render_brush=brush;
|
||||
if (w_brush)
|
||||
render_brush = brush;
|
||||
|
||||
if( alpha!=render_brush.getAlpha() ){
|
||||
render_brush.setAlpha( alpha );
|
||||
}else if( !w_brush ){
|
||||
if (alpha != render_brush.getAlpha()) {
|
||||
render_brush.setAlpha(alpha);
|
||||
} else if (!w_brush) {
|
||||
return true;
|
||||
}
|
||||
|
||||
setRenderBrush( render_brush );
|
||||
w_brush=false;
|
||||
setRenderBrush(render_brush);
|
||||
w_brush = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Model::enqueue( MeshQueue *q ){
|
||||
queues[q->getQueueType()].push_back( q );
|
||||
void Model::enqueue(MeshQueue* q)
|
||||
{
|
||||
queues[q->getQueueType()].push_back(q);
|
||||
}
|
||||
|
||||
void Model::enqueue( gxMesh *mesh,int fv,int vc,int ft,int tc ){
|
||||
enqueue( new MeshQueue( mesh,fv,vc,ft,tc,render_brush ) );
|
||||
void Model::enqueue(gxMesh* mesh, int fv, int vc, int ft, int tc)
|
||||
{
|
||||
enqueue(new MeshQueue(mesh, fv, vc, ft, tc, render_brush));
|
||||
}
|
||||
|
||||
void Model::enqueue( gxMesh *mesh,int fv,int vc,int ft,int tc,const Brush &brush ){
|
||||
enqueue( new MeshQueue( mesh,fv,vc,ft,tc,brush ) );
|
||||
void Model::enqueue(gxMesh* mesh, int fv, int vc, int ft, int tc, const Brush& brush)
|
||||
{
|
||||
enqueue(new MeshQueue(mesh, fv, vc, ft, tc, brush));
|
||||
}
|
||||
|
||||
void Model::renderQueue( int type ){
|
||||
vector<MeshQueue*> *que=&queues[type];
|
||||
for( ;que->size();que->pop_back() ){
|
||||
MeshQueue *q=que->back();
|
||||
void Model::renderQueue(int type)
|
||||
{
|
||||
vector<MeshQueue*>* que = &queues[type];
|
||||
for (; que->size(); que->pop_back()) {
|
||||
MeshQueue* q = que->back();
|
||||
q->render();
|
||||
delete q;
|
||||
}
|
||||
|
||||
+110
-47
@@ -11,82 +11,145 @@ class Terrain;
|
||||
class PlaneModel;
|
||||
class Q3BSPModel;
|
||||
|
||||
class Model : public Object{
|
||||
public:
|
||||
enum{
|
||||
RENDER_SPACE_LOCAL=0,
|
||||
RENDER_SPACE_WORLD=1
|
||||
};
|
||||
enum{
|
||||
COLLISION_GEOMETRY_DEFAULT=0,
|
||||
COLLISION_GEOMETRY_TRIS=1,
|
||||
COLLISION_GEOMETRY_BOX=2,
|
||||
COLLISION_GEOMETRY_SPHERE=3
|
||||
};
|
||||
enum{
|
||||
QUEUE_OPAQUE=0,
|
||||
QUEUE_TRANSPARENT=1
|
||||
class Model : public Object {
|
||||
public:
|
||||
enum { RENDER_SPACE_LOCAL = 0, RENDER_SPACE_WORLD = 1 };
|
||||
enum {
|
||||
COLLISION_GEOMETRY_DEFAULT = 0,
|
||||
COLLISION_GEOMETRY_TRIS = 1,
|
||||
COLLISION_GEOMETRY_BOX = 2,
|
||||
COLLISION_GEOMETRY_SPHERE = 3
|
||||
};
|
||||
enum { QUEUE_OPAQUE = 0, QUEUE_TRANSPARENT = 1 };
|
||||
|
||||
Model();
|
||||
Model( const Model &m );
|
||||
Model(const Model& m);
|
||||
|
||||
//Entity interface
|
||||
Model *getModel(){ return this; }
|
||||
Model* getModel()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
//Object interface
|
||||
void capture();
|
||||
bool beginRender( float tween );
|
||||
bool beginRender(float tween);
|
||||
|
||||
//Model interface
|
||||
virtual void setRenderBrush( const Brush &b ){}
|
||||
virtual bool render( const RenderContext &rc ){ return false; }
|
||||
virtual void renderQueue( int type );
|
||||
virtual void setRenderBrush(const Brush& b) {}
|
||||
virtual bool render(const RenderContext& rc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void renderQueue(int type);
|
||||
|
||||
virtual Sprite *getSprite(){ return 0; }
|
||||
virtual Terrain *getTerrain(){ return 0; }
|
||||
virtual PlaneModel *getPlaneModel(){ return 0; }
|
||||
virtual MeshModel *getMeshModel(){ return 0; }
|
||||
virtual MD2Model *getMD2Model(){ return 0; }
|
||||
virtual Q3BSPModel *getBSPModel(){ return 0; }
|
||||
virtual Sprite* getSprite()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual Terrain* getTerrain()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual PlaneModel* getPlaneModel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual MeshModel* getMeshModel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual MD2Model* getMD2Model()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual Q3BSPModel* getBSPModel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void setBrush( const Brush &b ){ brush=b;w_brush=true; }
|
||||
virtual void setColor( const Vector &c ){ brush.setColor(c);w_brush=true; }
|
||||
virtual void setAlpha( float a ){ brush.setAlpha(a);w_brush=true; }
|
||||
virtual void setShininess( float t ){ brush.setShininess(t);w_brush=true; }
|
||||
virtual void setTexture( int i,const Texture &t,int f ){ brush.setTexture(i,t,f);w_brush=true; }
|
||||
virtual void setBlend( int n ){ brush.setBlend(n);w_brush=true; }
|
||||
virtual void setFX( int n ){ brush.setFX(n);w_brush=true; }
|
||||
virtual void setBrush(const Brush& b)
|
||||
{
|
||||
brush = b;
|
||||
w_brush = true;
|
||||
}
|
||||
virtual void setColor(const Vector& c)
|
||||
{
|
||||
brush.setColor(c);
|
||||
w_brush = true;
|
||||
}
|
||||
virtual void setAlpha(float a)
|
||||
{
|
||||
brush.setAlpha(a);
|
||||
w_brush = true;
|
||||
}
|
||||
virtual void setShininess(float t)
|
||||
{
|
||||
brush.setShininess(t);
|
||||
w_brush = true;
|
||||
}
|
||||
virtual void setTexture(int i, const Texture& t, int f)
|
||||
{
|
||||
brush.setTexture(i, t, f);
|
||||
w_brush = true;
|
||||
}
|
||||
virtual void setBlend(int n)
|
||||
{
|
||||
brush.setBlend(n);
|
||||
w_brush = true;
|
||||
}
|
||||
virtual void setFX(int n)
|
||||
{
|
||||
brush.setFX(n);
|
||||
w_brush = true;
|
||||
}
|
||||
|
||||
const Brush &getBrush()const{ return brush; }
|
||||
const Brush& getBrush() const
|
||||
{
|
||||
return brush;
|
||||
}
|
||||
|
||||
void setRenderSpace( int n ){ space=n; }
|
||||
int getRenderSpace()const{ return space; }
|
||||
void setRenderSpace(int n)
|
||||
{
|
||||
space = n;
|
||||
}
|
||||
int getRenderSpace() const
|
||||
{
|
||||
return space;
|
||||
}
|
||||
|
||||
void setAutoFade( float nr,float fr ){ auto_fade_nr=nr;auto_fade_fr=fr;auto_fade=true; }
|
||||
void setAutoFade(float nr, float fr)
|
||||
{
|
||||
auto_fade_nr = nr;
|
||||
auto_fade_fr = fr;
|
||||
auto_fade = true;
|
||||
}
|
||||
|
||||
bool doAutoFade( const Vector &eye );
|
||||
bool doAutoFade(const Vector& eye);
|
||||
|
||||
void enqueue( gxMesh *mesh,int first_vert,int vert_cnt,int first_tri,int tri_cnt );
|
||||
void enqueue( gxMesh *mesh,int first_vert,int vert_cnt,int first_tri,int tri_cnt,const Brush &b );
|
||||
void enqueue(gxMesh* mesh, int first_vert, int vert_cnt, int first_tri, int tri_cnt);
|
||||
void enqueue(gxMesh* mesh, int first_vert, int vert_cnt, int first_tri, int tri_cnt, const Brush& b);
|
||||
|
||||
int queueSize( int type )const{ return queues[type].size(); }
|
||||
int queueSize(int type) const
|
||||
{
|
||||
return queues[type].size();
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
class MeshQueue;
|
||||
|
||||
int space;
|
||||
Brush brush,render_brush;
|
||||
Brush brush, render_brush;
|
||||
|
||||
mutable bool w_brush;
|
||||
float captured_alpha,tweened_alpha;
|
||||
float captured_alpha, tweened_alpha;
|
||||
|
||||
bool auto_fade;
|
||||
float auto_fade_nr,auto_fade_fr;
|
||||
float auto_fade_nr, auto_fade_fr;
|
||||
|
||||
vector<MeshQueue*> queues[2];
|
||||
|
||||
void enqueue( MeshQueue *q );
|
||||
void enqueue(MeshQueue* q);
|
||||
};
|
||||
|
||||
#endif
|
||||
+114
-85
@@ -1,162 +1,191 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "object.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxRuntime* gx_runtime;
|
||||
|
||||
Object::Object():
|
||||
order(0),animator(0),last_copy(0),
|
||||
coll_type(0),coll_radii(Vector(1,1,1)),coll_box(Box(Vector(-1,-1,-1),Vector(1,1,1))),
|
||||
pick_geom(0),obscurer(false),captured(false){
|
||||
Object::Object()
|
||||
: order(0), animator(0), last_copy(0), coll_type(0), coll_radii(Vector(1, 1, 1)),
|
||||
coll_box(Box(Vector(-1, -1, -1), Vector(1, 1, 1))), pick_geom(0), obscurer(false), captured(false)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
Object::Object( const Object &o ):
|
||||
Entity(o),
|
||||
order(o.order),animator(0),last_copy(0),
|
||||
coll_type(o.coll_type),coll_radii(o.coll_radii),coll_box(o.coll_box),
|
||||
pick_geom(o.pick_geom),obscurer(o.obscurer),captured(false){
|
||||
Object::Object(const Object& o)
|
||||
: Entity(o), order(o.order), animator(0), last_copy(0), coll_type(o.coll_type), coll_radii(o.coll_radii),
|
||||
coll_box(o.coll_box), pick_geom(o.pick_geom), obscurer(o.obscurer), captured(false)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
Object::~Object(){
|
||||
Object::~Object()
|
||||
{
|
||||
delete animator;
|
||||
velocity=Vector();
|
||||
velocity = Vector();
|
||||
updateSounds();
|
||||
}
|
||||
|
||||
Object *Object::copy(){
|
||||
last_copy=clone()->getObject();
|
||||
for( Entity *e=GetChildren();e;e=e->GetSuccessor() ){
|
||||
Object *cpy=e->getObject()->copy();
|
||||
cpy->SetParent( last_copy );
|
||||
Object* Object::copy()
|
||||
{
|
||||
last_copy = clone()->getObject();
|
||||
for (Entity* e = GetChildren(); e; e = e->GetSuccessor()) {
|
||||
Object* cpy = e->getObject()->copy();
|
||||
cpy->SetParent(last_copy);
|
||||
}
|
||||
if( animator ) last_copy->setAnimator( new Animator( animator ) );
|
||||
if (animator)
|
||||
last_copy->setAnimator(new Animator(animator));
|
||||
return last_copy;
|
||||
}
|
||||
|
||||
void Object::reset(){
|
||||
void Object::reset()
|
||||
{
|
||||
colls.clear();
|
||||
velocity=Vector();
|
||||
prev_tform=GetWorldTransform();
|
||||
velocity = Vector();
|
||||
prev_tform = GetWorldTransform();
|
||||
}
|
||||
|
||||
void Object::setCollisionType( int type ){
|
||||
coll_type=type;
|
||||
void Object::setCollisionType(int type)
|
||||
{
|
||||
coll_type = type;
|
||||
}
|
||||
|
||||
void Object::setCollisionRadii( const Vector &radii ){
|
||||
coll_radii=radii;
|
||||
void Object::setCollisionRadii(const Vector& radii)
|
||||
{
|
||||
coll_radii = radii;
|
||||
}
|
||||
|
||||
void Object::setCollisionBox( const Box &box ){
|
||||
coll_box=box;
|
||||
void Object::setCollisionBox(const Box& box)
|
||||
{
|
||||
coll_box = box;
|
||||
}
|
||||
|
||||
void Object::setAnimator( Animator *t ){
|
||||
if( animator ) delete animator;
|
||||
animator=t;
|
||||
void Object::setAnimator(Animator* t)
|
||||
{
|
||||
if (animator)
|
||||
delete animator;
|
||||
animator = t;
|
||||
}
|
||||
|
||||
void Object::beginUpdate( float e ){
|
||||
elapsed=e;
|
||||
void Object::beginUpdate(float e)
|
||||
{
|
||||
elapsed = e;
|
||||
colls.clear();
|
||||
animate( e );
|
||||
animate(e);
|
||||
}
|
||||
|
||||
void Object::animate( float e ){
|
||||
if( animator ) animator->update( e );
|
||||
void Object::animate(float e)
|
||||
{
|
||||
if (animator)
|
||||
animator->update(e);
|
||||
}
|
||||
|
||||
void Object::addCollision( const ObjCollision *c ){
|
||||
colls.push_back( c );
|
||||
void Object::addCollision(const ObjCollision* c)
|
||||
{
|
||||
colls.push_back(c);
|
||||
}
|
||||
|
||||
void Object::endUpdate(){
|
||||
velocity=(GetWorldTransform().v-prev_tform.v)/elapsed;
|
||||
prev_tform=GetWorldTransform();
|
||||
void Object::endUpdate()
|
||||
{
|
||||
velocity = (GetWorldTransform().v - prev_tform.v) / elapsed;
|
||||
prev_tform = GetWorldTransform();
|
||||
}
|
||||
|
||||
void Object::capture(){
|
||||
capt_pos=GetLocalPosition();
|
||||
capt_scl=GetLocalScale();
|
||||
capt_rot=GetLocalRotation();
|
||||
captured=true;
|
||||
void Object::capture()
|
||||
{
|
||||
capt_pos = GetLocalPosition();
|
||||
capt_scl = GetLocalScale();
|
||||
capt_rot = GetLocalRotation();
|
||||
captured = true;
|
||||
}
|
||||
|
||||
bool Object::beginRender( float tween ){
|
||||
bool Object::beginRender(float tween)
|
||||
{
|
||||
updateSounds();
|
||||
if( tween==1 || !captured ){
|
||||
render_tform=GetWorldTransform();
|
||||
render_tform_valid=true;
|
||||
}else{
|
||||
Vector pos=(GetLocalPosition()-capt_pos)*tween+capt_pos;
|
||||
Vector scl=(GetLocalScale()-capt_scl)*tween+capt_scl;
|
||||
Quat rot=capt_rot.slerpTo( GetLocalRotation(),tween );
|
||||
tween_tform.m=Matrix( rot );
|
||||
tween_tform.m.i*=scl.x;
|
||||
tween_tform.m.j*=scl.y;
|
||||
tween_tform.m.k*=scl.z;
|
||||
tween_tform.v=pos;
|
||||
render_tform_valid=false;
|
||||
if (tween == 1 || !captured) {
|
||||
render_tform = GetWorldTransform();
|
||||
render_tform_valid = true;
|
||||
} else {
|
||||
Vector pos = (GetLocalPosition() - capt_pos) * tween + capt_pos;
|
||||
Vector scl = (GetLocalScale() - capt_scl) * tween + capt_scl;
|
||||
Quat rot = capt_rot.slerpTo(GetLocalRotation(), tween);
|
||||
tween_tform.m = Matrix(rot);
|
||||
tween_tform.m.i *= scl.x;
|
||||
tween_tform.m.j *= scl.y;
|
||||
tween_tform.m.k *= scl.z;
|
||||
tween_tform.v = pos;
|
||||
render_tform_valid = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Object::endRender(){
|
||||
}
|
||||
void Object::endRender() {}
|
||||
|
||||
int Object::getCollisionType()const{
|
||||
int Object::getCollisionType() const
|
||||
{
|
||||
return coll_type;
|
||||
}
|
||||
|
||||
const Vector &Object::getCollisionRadii()const{
|
||||
const Vector& Object::getCollisionRadii() const
|
||||
{
|
||||
return coll_radii;
|
||||
}
|
||||
|
||||
const Box &Object::getCollisionBox()const{
|
||||
const Box& Object::getCollisionBox() const
|
||||
{
|
||||
return coll_box;
|
||||
}
|
||||
|
||||
const Vector &Object::getVelocity()const{
|
||||
const Vector& Object::getVelocity() const
|
||||
{
|
||||
return velocity;
|
||||
}
|
||||
|
||||
const Object::Collisions &Object::getCollisions()const{
|
||||
const Object::Collisions& Object::getCollisions() const
|
||||
{
|
||||
return colls;
|
||||
}
|
||||
|
||||
const Transform &Object::getRenderTform()const{
|
||||
if( render_tform_valid ) return render_tform;
|
||||
const Transform& Object::getRenderTform() const
|
||||
{
|
||||
if (render_tform_valid)
|
||||
return render_tform;
|
||||
|
||||
Object *parent=(Object*)getParent();
|
||||
render_tform=parent ? parent->getRenderTform() * tween_tform : tween_tform;
|
||||
render_tform_valid=true;
|
||||
Object* parent = (Object*)getParent();
|
||||
render_tform = parent ? parent->getRenderTform() * tween_tform : tween_tform;
|
||||
render_tform_valid = true;
|
||||
|
||||
return render_tform;
|
||||
}
|
||||
|
||||
const Transform &Object::getPrevWorldTform()const{
|
||||
const Transform& Object::getPrevWorldTform() const
|
||||
{
|
||||
return prev_tform;
|
||||
}
|
||||
|
||||
gxChannel *Object::emitSound( gxSound *sound ){
|
||||
if( !sound ) return 0;
|
||||
gxChannel* Object::emitSound(gxSound* sound)
|
||||
{
|
||||
if (!sound)
|
||||
return 0;
|
||||
|
||||
gxChannel *chan=sound->play3d( &GetWorldTransform().v.x,&velocity.x );
|
||||
for( int k=0;k<channels.size();++k ){
|
||||
if( chan==channels[k] ) return chan;
|
||||
if( !channels[k] ) return channels[k]=chan;
|
||||
gxChannel* chan = sound->play3d(&GetWorldTransform().v.x, &velocity.x);
|
||||
for (int k = 0; k < channels.size(); ++k) {
|
||||
if (chan == channels[k])
|
||||
return chan;
|
||||
if (!channels[k])
|
||||
return channels[k] = chan;
|
||||
}
|
||||
channels.push_back( chan );
|
||||
channels.push_back(chan);
|
||||
return chan;
|
||||
}
|
||||
|
||||
void Object::updateSounds(){
|
||||
for( int k=0;k<channels.size();++k ){
|
||||
if( gxChannel *chan=channels[k] ){
|
||||
if( chan->isPlaying() ) chan->set3d( &GetWorldTransform().v.x,&velocity.x );
|
||||
else channels[k]=0;
|
||||
void Object::updateSounds()
|
||||
{
|
||||
for (int k = 0; k < channels.size(); ++k) {
|
||||
if (gxChannel* chan = channels[k]) {
|
||||
if (chan->isPlaying())
|
||||
chan->set3d(&GetWorldTransform().v.x, &velocity.x);
|
||||
else
|
||||
channels[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+80
-41
@@ -4,74 +4,113 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "entity.hpp"
|
||||
#include "animator.hpp"
|
||||
#include "collision.hpp"
|
||||
#include "entity.hpp"
|
||||
|
||||
class gxSound;
|
||||
|
||||
struct ObjCollision{
|
||||
Object *with;
|
||||
struct ObjCollision {
|
||||
Object* with;
|
||||
Vector coords;
|
||||
Collision collision;
|
||||
};
|
||||
|
||||
class Object : public Entity{
|
||||
public:
|
||||
class Object : public Entity {
|
||||
public:
|
||||
typedef std::vector<const ObjCollision*> Collisions;
|
||||
|
||||
Object();
|
||||
Object( const Object &object );
|
||||
Object(const Object& object);
|
||||
~Object();
|
||||
|
||||
//Entity interface
|
||||
Object *getObject(){ return this; }
|
||||
Entity *clone(){ return new Object( *this ); }
|
||||
Object* getObject()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
Entity* clone()
|
||||
{
|
||||
return new Object(*this);
|
||||
}
|
||||
|
||||
//deep object copy!
|
||||
Object *copy();
|
||||
Object* copy();
|
||||
|
||||
//called by user
|
||||
void reset();
|
||||
void setCollisionType( int type );
|
||||
void setCollisionRadii( const Vector &radii );
|
||||
void setCollisionBox( const Box &box );
|
||||
void setOrder( int n ){ order=n; }
|
||||
void setPickGeometry( int n ){ pick_geom=n; }
|
||||
void setObscurer( bool t ){ obscurer=t; }
|
||||
void setAnimation( const Animation &t ){ anim=t; }
|
||||
void setAnimator( Animator *t );
|
||||
void setCollisionType(int type);
|
||||
void setCollisionRadii(const Vector& radii);
|
||||
void setCollisionBox(const Box& box);
|
||||
void setOrder(int n)
|
||||
{
|
||||
order = n;
|
||||
}
|
||||
void setPickGeometry(int n)
|
||||
{
|
||||
pick_geom = n;
|
||||
}
|
||||
void setObscurer(bool t)
|
||||
{
|
||||
obscurer = t;
|
||||
}
|
||||
void setAnimation(const Animation& t)
|
||||
{
|
||||
anim = t;
|
||||
}
|
||||
void setAnimator(Animator* t);
|
||||
|
||||
gxChannel *emitSound( gxSound *sound );
|
||||
gxChannel* emitSound(gxSound* sound);
|
||||
|
||||
//overridables!
|
||||
virtual bool collide( const Line &line,float radius,::Collision *curr_coll,const Transform &t ){ return false; }
|
||||
virtual bool collide(const Line& line, float radius, ::Collision* curr_coll, const Transform& t)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void capture();
|
||||
virtual void animate( float e );
|
||||
virtual bool beginRender( float tween );
|
||||
virtual void animate(float e);
|
||||
virtual bool beginRender(float tween);
|
||||
virtual void endRender();
|
||||
|
||||
//for use by world
|
||||
void beginUpdate( float elapsed );
|
||||
void addCollision( const ObjCollision *c );
|
||||
void beginUpdate(float elapsed);
|
||||
void addCollision(const ObjCollision* c);
|
||||
void endUpdate();
|
||||
|
||||
//accessors
|
||||
int getCollisionType()const;
|
||||
const Vector &getCollisionRadii()const;
|
||||
const Box &getCollisionBox()const;
|
||||
int getOrder()const{ return order; }
|
||||
const Vector &getVelocity()const;
|
||||
const Collisions &getCollisions()const;
|
||||
const Transform &getRenderTform()const;
|
||||
const Transform &getPrevWorldTform()const;
|
||||
int getPickGeometry()const{ return pick_geom; }
|
||||
int getObscurer()const{ return obscurer; }
|
||||
Animation getAnimation()const{ return anim; }
|
||||
Animator *getAnimator()const{ return animator; }
|
||||
Object *getLastCopy()const{ return last_copy; }
|
||||
int getCollisionType() const;
|
||||
const Vector& getCollisionRadii() const;
|
||||
const Box& getCollisionBox() const;
|
||||
int getOrder() const
|
||||
{
|
||||
return order;
|
||||
}
|
||||
const Vector& getVelocity() const;
|
||||
const Collisions& getCollisions() const;
|
||||
const Transform& getRenderTform() const;
|
||||
const Transform& getPrevWorldTform() const;
|
||||
int getPickGeometry() const
|
||||
{
|
||||
return pick_geom;
|
||||
}
|
||||
int getObscurer() const
|
||||
{
|
||||
return obscurer;
|
||||
}
|
||||
Animation getAnimation() const
|
||||
{
|
||||
return anim;
|
||||
}
|
||||
Animator* getAnimator() const
|
||||
{
|
||||
return animator;
|
||||
}
|
||||
Object* getLastCopy() const
|
||||
{
|
||||
return last_copy;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
int coll_type;
|
||||
int order;
|
||||
Vector coll_radii;
|
||||
@@ -83,17 +122,17 @@ private:
|
||||
float elapsed;
|
||||
Vector velocity;
|
||||
vector<gxChannel*> channels;
|
||||
Vector capt_pos,capt_scl;
|
||||
Vector capt_pos, capt_scl;
|
||||
Quat capt_rot;
|
||||
mutable Object *last_copy;
|
||||
mutable Object* last_copy;
|
||||
|
||||
Transform prev_tform;
|
||||
Transform captured_tform,tween_tform;
|
||||
Transform captured_tform, tween_tform;
|
||||
mutable Transform render_tform;
|
||||
mutable bool render_tform_valid;
|
||||
|
||||
Animation anim;
|
||||
Animator *animator;
|
||||
Animator* animator;
|
||||
|
||||
void updateSounds();
|
||||
};
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "pivot.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
Pivot::Pivot(){
|
||||
}
|
||||
Pivot::Pivot() {}
|
||||
|
||||
Pivot::Pivot( const Object &t ):
|
||||
Object(t){
|
||||
}
|
||||
Pivot::Pivot(const Object& t) : Object(t) {}
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
|
||||
#include "object.hpp"
|
||||
|
||||
class Pivot : public Object{
|
||||
public:
|
||||
class Pivot : public Object {
|
||||
public:
|
||||
Pivot();
|
||||
Pivot( const Object &t );
|
||||
Pivot(const Object& t);
|
||||
|
||||
//Entity interface
|
||||
Entity *clone(){ return new Pivot( *this ); }
|
||||
Entity* clone()
|
||||
{
|
||||
return new Pivot(*this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,136 +1,140 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "planemodel.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
static Vector vts[17][17];
|
||||
|
||||
extern gxGraphics *gx_graphics;
|
||||
|
||||
struct PlaneModel::Rep{
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
struct PlaneModel::Rep {
|
||||
int ref_cnt;
|
||||
gxMesh *mesh;
|
||||
gxMesh* mesh;
|
||||
int sub_divs;
|
||||
|
||||
Rep( int n ):
|
||||
ref_cnt(1),sub_divs(n){
|
||||
mesh=gx_graphics->createMesh( 5*sub_divs*sub_divs,3*sub_divs*sub_divs,0 );
|
||||
Rep(int n) : ref_cnt(1), sub_divs(n)
|
||||
{
|
||||
mesh = gx_graphics->createMesh(5 * sub_divs * sub_divs, 3 * sub_divs * sub_divs, 0);
|
||||
}
|
||||
~Rep(){
|
||||
gx_graphics->freeMesh( mesh );
|
||||
~Rep()
|
||||
{
|
||||
gx_graphics->freeMesh(mesh);
|
||||
}
|
||||
void render( PlaneModel *model,const RenderContext &rc ){
|
||||
|
||||
void render(PlaneModel* model, const RenderContext& rc)
|
||||
{
|
||||
static Frustum f;
|
||||
new( &f ) Frustum( rc.getWorldFrustum(),-model->getRenderTform() );
|
||||
const Vector &eye=f.getVertex( Frustum::VERT_EYE );
|
||||
new (&f) Frustum(rc.getWorldFrustum(), -model->getRenderTform());
|
||||
const Vector& eye = f.getVertex(Frustum::VERT_EYE);
|
||||
|
||||
if( eye.y<=0 ) return;
|
||||
if (eye.y <= 0)
|
||||
return;
|
||||
|
||||
const Vector &tl=f.getVertex( Frustum::VERT_TLFAR );
|
||||
const Vector &tr=f.getVertex( Frustum::VERT_TRFAR );
|
||||
const Vector &br=f.getVertex( Frustum::VERT_BRFAR );
|
||||
const Vector &bl=f.getVertex( Frustum::VERT_BLFAR );
|
||||
const Vector& tl = f.getVertex(Frustum::VERT_TLFAR);
|
||||
const Vector& tr = f.getVertex(Frustum::VERT_TRFAR);
|
||||
const Vector& br = f.getVertex(Frustum::VERT_BRFAR);
|
||||
const Vector& bl = f.getVertex(Frustum::VERT_BLFAR);
|
||||
|
||||
Transform tex_t( model->getRenderTform().m );
|
||||
Transform tex_t(model->getRenderTform().m);
|
||||
|
||||
int x;
|
||||
for( x=0;x<=sub_divs;++x ){
|
||||
float t=float(x)/float(sub_divs);
|
||||
Vector tx=(tr-tl)*t+tl;
|
||||
Vector bx=(br-bl)*t+bl;
|
||||
for( int y=0;y<=sub_divs;++y ){
|
||||
float t=float(y)/float(sub_divs);
|
||||
vts[x][y]=(bx-tx)*t+tx;
|
||||
for (x = 0; x <= sub_divs; ++x) {
|
||||
float t = float(x) / float(sub_divs);
|
||||
Vector tx = (tr - tl) * t + tl;
|
||||
Vector bx = (br - bl) * t + bl;
|
||||
for (int y = 0; y <= sub_divs; ++y) {
|
||||
float t = float(y) / float(sub_divs);
|
||||
vts[x][y] = (bx - tx) * t + tx;
|
||||
}
|
||||
}
|
||||
|
||||
Plane plane( Vector( 0,1,0 ),0 );
|
||||
Plane plane(Vector(0, 1, 0), 0);
|
||||
|
||||
mesh->lock( true );
|
||||
int v_cnt=0,t_cnt=0;
|
||||
for( x=0;x<sub_divs;++x ){
|
||||
for( int y=0;y<sub_divs;++y ){
|
||||
mesh->lock(true);
|
||||
int v_cnt = 0, t_cnt = 0;
|
||||
for (x = 0; x < sub_divs; ++x) {
|
||||
for (int y = 0; y < sub_divs; ++y) {
|
||||
Vector in_verts[4], out_verts[5];
|
||||
|
||||
Vector in_verts[4],out_verts[5];
|
||||
in_verts[0] = vts[x][y];
|
||||
in_verts[1] = vts[x + 1][y];
|
||||
in_verts[2] = vts[x + 1][y + 1];
|
||||
in_verts[3] = vts[x][y + 1];
|
||||
|
||||
in_verts[0]=vts[x][y];
|
||||
in_verts[1]=vts[x+1][y];
|
||||
in_verts[2]=vts[x+1][y+1];
|
||||
in_verts[3]=vts[x][y+1];
|
||||
int k, out_cnt = 0;
|
||||
for (k = 0; k < 4; ++k) {
|
||||
const Vector& vert = in_verts[k];
|
||||
const Vector& prev_vert = in_verts[(k - 1) & 3];
|
||||
|
||||
int k,out_cnt=0;
|
||||
for( k=0;k<4;++k ){
|
||||
|
||||
const Vector &vert=in_verts[k];
|
||||
const Vector &prev_vert=in_verts[(k-1)&3];
|
||||
|
||||
if( vert.y>0 ){
|
||||
if( prev_vert.y<=0 ){
|
||||
float t=prev_vert.y/(prev_vert.y-vert.y);
|
||||
out_verts[out_cnt++]=(vert-prev_vert)*t+prev_vert;
|
||||
if (vert.y > 0) {
|
||||
if (prev_vert.y <= 0) {
|
||||
float t = prev_vert.y / (prev_vert.y - vert.y);
|
||||
out_verts[out_cnt++] = (vert - prev_vert) * t + prev_vert;
|
||||
}
|
||||
}else{
|
||||
if( prev_vert.y>0 ){
|
||||
float t=prev_vert.y/(prev_vert.y-vert.y);
|
||||
out_verts[out_cnt++]=(vert-prev_vert)*t+prev_vert;
|
||||
} else {
|
||||
if (prev_vert.y > 0) {
|
||||
float t = prev_vert.y / (prev_vert.y - vert.y);
|
||||
out_verts[out_cnt++] = (vert - prev_vert) * t + prev_vert;
|
||||
}
|
||||
out_verts[out_cnt++]=plane.intersect( Line( eye,vert-eye ) );
|
||||
out_verts[out_cnt++] = plane.intersect(Line(eye, vert - eye));
|
||||
}
|
||||
}
|
||||
if( out_cnt<3 || out_cnt>5 ) continue;
|
||||
if (out_cnt < 3 || out_cnt > 5)
|
||||
continue;
|
||||
|
||||
for( k=0;k<out_cnt;++k ){
|
||||
const Vector &v=out_verts[k];
|
||||
float tex_coords[2][2]={ {v.x,v.z},{v.x,v.z} };
|
||||
mesh->setVertex( v_cnt+k,&v.x,&plane.n.x,tex_coords );
|
||||
for (k = 0; k < out_cnt; ++k) {
|
||||
const Vector& v = out_verts[k];
|
||||
float tex_coords[2][2] = {{v.x, v.z}, {v.x, v.z}};
|
||||
mesh->setVertex(v_cnt + k, &v.x, &plane.n.x, tex_coords);
|
||||
}
|
||||
for( k=2;k<out_cnt;++k ){
|
||||
mesh->setTriangle( t_cnt++,v_cnt,v_cnt+k-1,v_cnt+k );
|
||||
for (k = 2; k < out_cnt; ++k) {
|
||||
mesh->setTriangle(t_cnt++, v_cnt, v_cnt + k - 1, v_cnt + k);
|
||||
}
|
||||
v_cnt+=out_cnt;
|
||||
v_cnt += out_cnt;
|
||||
}
|
||||
}
|
||||
mesh->unlock();
|
||||
if( v_cnt<3 ) return;
|
||||
model->enqueue( mesh,0,v_cnt,0,t_cnt );
|
||||
if (v_cnt < 3)
|
||||
return;
|
||||
model->enqueue(mesh, 0, v_cnt, 0, t_cnt);
|
||||
}
|
||||
};
|
||||
|
||||
PlaneModel::PlaneModel( int sub_divs ):
|
||||
rep( new Rep(sub_divs) ){
|
||||
}
|
||||
PlaneModel::PlaneModel(int sub_divs) : rep(new Rep(sub_divs)) {}
|
||||
|
||||
PlaneModel::PlaneModel( const PlaneModel &t ):
|
||||
Model( t ),rep( t.rep ){
|
||||
PlaneModel::PlaneModel(const PlaneModel& t) : Model(t), rep(t.rep)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
|
||||
PlaneModel::~PlaneModel(){
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
PlaneModel::~PlaneModel()
|
||||
{
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
}
|
||||
|
||||
Plane PlaneModel::getRenderPlane()const{
|
||||
return Plane( getRenderTform().v,getRenderTform().m.j.normalized() );
|
||||
Plane PlaneModel::getRenderPlane() const
|
||||
{
|
||||
return Plane(getRenderTform().v, getRenderTform().m.j.normalized());
|
||||
}
|
||||
|
||||
bool PlaneModel::render( const RenderContext &rc ){
|
||||
rep->render( this,rc );
|
||||
bool PlaneModel::render(const RenderContext& rc)
|
||||
{
|
||||
rep->render(this, rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlaneModel::collide( const Line &l,float radius,Collision *curr_coll,const Transform &tf ){
|
||||
bool PlaneModel::collide(const Line& l, float radius, Collision* curr_coll, const Transform& tf)
|
||||
{
|
||||
Line line(-tf * l);
|
||||
|
||||
Line line( -tf * l );
|
||||
Plane p(Vector(0, 1, 0), 0);
|
||||
p.d -= radius;
|
||||
float t = p.t_intersect(line);
|
||||
if (t >= curr_coll->time)
|
||||
return false;
|
||||
|
||||
Plane p( Vector( 0,1,0 ),0 );
|
||||
p.d-=radius;
|
||||
float t=p.t_intersect( line );
|
||||
if( t>=curr_coll->time ) return false;
|
||||
Vector n = (tf.m.cofactor() * p.n).normalized();
|
||||
|
||||
Vector n=(tf.m.cofactor() * p.n).normalized();
|
||||
|
||||
return curr_coll->update( l,t,n );
|
||||
return curr_coll->update(l, t, n);
|
||||
}
|
||||
|
||||
@@ -2,30 +2,36 @@
|
||||
#ifndef PLANEMODEL_H
|
||||
#define PLANEMODEL_H
|
||||
|
||||
#include "model.hpp"
|
||||
#include "brush.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
class PlaneModel : public Model{
|
||||
public:
|
||||
PlaneModel( int sub_divs );
|
||||
PlaneModel( const PlaneModel &t );
|
||||
class PlaneModel : public Model {
|
||||
public:
|
||||
PlaneModel(int sub_divs);
|
||||
PlaneModel(const PlaneModel& t);
|
||||
~PlaneModel();
|
||||
Entity *clone(){ return new PlaneModel( *this ); }
|
||||
Entity* clone()
|
||||
{
|
||||
return new PlaneModel(*this);
|
||||
}
|
||||
|
||||
//model interface
|
||||
bool render( const RenderContext &rc );
|
||||
bool render(const RenderContext& rc);
|
||||
|
||||
//object interface
|
||||
bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &tf );
|
||||
bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& tf);
|
||||
|
||||
Plane getRenderPlane()const;
|
||||
Plane getRenderPlane() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Rep;
|
||||
|
||||
Rep *rep;
|
||||
Rep* rep;
|
||||
|
||||
virtual PlaneModel *getPlaneModel(){ return this; }
|
||||
virtual PlaneModel* getPlaneModel()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,46 +1,49 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "q3bspmodel.hpp"
|
||||
#include "q3bsprep.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
struct Q3BSPModel::Rep : public Q3BSPRep{
|
||||
struct Q3BSPModel::Rep : public Q3BSPRep {
|
||||
int ref_cnt;
|
||||
|
||||
Rep( const string &f,float gam ):Q3BSPRep( f,gam ),
|
||||
ref_cnt(1){
|
||||
}
|
||||
Rep(const string& f, float gam) : Q3BSPRep(f, gam), ref_cnt(1) {}
|
||||
};
|
||||
|
||||
Q3BSPModel::Q3BSPModel( const string &f,float gam ):
|
||||
rep( new Rep( f,gam ) ){
|
||||
}
|
||||
Q3BSPModel::Q3BSPModel(const string& f, float gam) : rep(new Rep(f, gam)) {}
|
||||
|
||||
Q3BSPModel::Q3BSPModel( const Q3BSPModel &t ):Model(t),
|
||||
rep( t.rep ){
|
||||
Q3BSPModel::Q3BSPModel(const Q3BSPModel& t) : Model(t), rep(t.rep)
|
||||
{
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
|
||||
Q3BSPModel::~Q3BSPModel(){
|
||||
if( !--rep->ref_cnt ) delete rep;
|
||||
Q3BSPModel::~Q3BSPModel()
|
||||
{
|
||||
if (!--rep->ref_cnt)
|
||||
delete rep;
|
||||
}
|
||||
|
||||
bool Q3BSPModel::collide( const Line &line,float radius,Collision *curr_coll,const Transform &t ){
|
||||
return rep->collide( line,radius,curr_coll,t );
|
||||
bool Q3BSPModel::collide(const Line& line, float radius, Collision* curr_coll, const Transform& t)
|
||||
{
|
||||
return rep->collide(line, radius, curr_coll, t);
|
||||
}
|
||||
|
||||
bool Q3BSPModel::render( const RenderContext &rc ){
|
||||
rep->render( this,rc );
|
||||
bool Q3BSPModel::render(const RenderContext& rc)
|
||||
{
|
||||
rep->render(this, rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Q3BSPModel::setAmbient( const Vector &t ){
|
||||
rep->setAmbient( t );
|
||||
void Q3BSPModel::setAmbient(const Vector& t)
|
||||
{
|
||||
rep->setAmbient(t);
|
||||
}
|
||||
|
||||
void Q3BSPModel::setLighting( bool l ){
|
||||
rep->setLighting( l );
|
||||
void Q3BSPModel::setLighting(bool l)
|
||||
{
|
||||
rep->setLighting(l);
|
||||
}
|
||||
|
||||
bool Q3BSPModel::isValid()const{
|
||||
bool Q3BSPModel::isValid() const
|
||||
{
|
||||
return rep->isValid();
|
||||
}
|
||||
@@ -4,31 +4,37 @@
|
||||
|
||||
#include "model.hpp"
|
||||
|
||||
class Q3BSPModel : public Model{
|
||||
public:
|
||||
Q3BSPModel( const string &f,float gamma_adj );
|
||||
Q3BSPModel( const Q3BSPModel &m );
|
||||
class Q3BSPModel : public Model {
|
||||
public:
|
||||
Q3BSPModel(const string& f, float gamma_adj);
|
||||
Q3BSPModel(const Q3BSPModel& m);
|
||||
~Q3BSPModel();
|
||||
|
||||
//Entity interface
|
||||
Entity *clone(){ return new Q3BSPModel( *this ); }
|
||||
Entity* clone()
|
||||
{
|
||||
return new Q3BSPModel(*this);
|
||||
}
|
||||
|
||||
//Object interface
|
||||
virtual bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &t );
|
||||
virtual bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& t);
|
||||
|
||||
//Model interface
|
||||
Q3BSPModel *getBSPModel(){ return this; }
|
||||
Q3BSPModel* getBSPModel()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
bool render( const RenderContext &rc );
|
||||
bool render(const RenderContext& rc);
|
||||
|
||||
void setAmbient( const Vector &t );
|
||||
void setLighting( bool use_lmap );
|
||||
void setAmbient(const Vector& t);
|
||||
void setLighting(bool use_lmap);
|
||||
|
||||
bool isValid()const;
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Rep;
|
||||
Rep *rep;
|
||||
Rep* rep;
|
||||
};
|
||||
|
||||
#endif
|
||||
+207
-142
@@ -1,10 +1,10 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "q3bsprep.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
/* Quake3 File format types */
|
||||
|
||||
#pragma pack(push,1)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct q3_plane {
|
||||
Vector normal;
|
||||
@@ -72,7 +72,7 @@ struct q3_brushside {
|
||||
struct q3_direntry {
|
||||
union {
|
||||
int offset;
|
||||
void *lump;
|
||||
void* lump;
|
||||
};
|
||||
int length;
|
||||
};
|
||||
@@ -87,16 +87,20 @@ struct q3_header {
|
||||
|
||||
/* Loading reps */
|
||||
struct Surf {
|
||||
Q3BSPSurf *surf;
|
||||
Q3BSPSurf* surf;
|
||||
int texture, lm_index;
|
||||
vector<int> verts, tris;
|
||||
};
|
||||
|
||||
struct FaceCmp {
|
||||
bool operator()(const q3_face *a, const q3_face *b)const {
|
||||
if (a->texture < b->texture) return true;
|
||||
if (b->texture < a->texture) return false;
|
||||
if (a->lm_index < b->lm_index) return true;
|
||||
bool operator()(const q3_face* a, const q3_face* b) const
|
||||
{
|
||||
if (a->texture < b->texture)
|
||||
return true;
|
||||
if (b->texture < a->texture)
|
||||
return false;
|
||||
if (a->lm_index < b->lm_index)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -109,15 +113,15 @@ struct Q3BSPFace;
|
||||
|
||||
struct Q3BSPSurf {
|
||||
Brush brush;
|
||||
gxMesh *mesh;
|
||||
gxMesh* mesh;
|
||||
vector<Q3BSPFace*> r_faces;
|
||||
int texture, lm_index;
|
||||
};
|
||||
|
||||
struct Q3BSPFace {
|
||||
union {
|
||||
Surf *t_surf;
|
||||
Q3BSPSurf *surf;
|
||||
Surf* t_surf;
|
||||
Q3BSPSurf* surf;
|
||||
};
|
||||
int vert, n_verts, tri, n_tris;
|
||||
};
|
||||
@@ -135,10 +139,16 @@ struct Q3BSPLeaf {
|
||||
struct Q3BSPNode {
|
||||
Box box;
|
||||
Plane plane;
|
||||
Q3BSPNode *nodes[2];
|
||||
Q3BSPLeaf *leafs[2];
|
||||
Q3BSPNode* nodes[2];
|
||||
Q3BSPLeaf* leafs[2];
|
||||
|
||||
~Q3BSPNode() { delete nodes[0]; delete nodes[1]; delete leafs[0]; delete leafs[1]; }
|
||||
~Q3BSPNode()
|
||||
{
|
||||
delete nodes[0];
|
||||
delete nodes[1];
|
||||
delete leafs[0];
|
||||
delete leafs[1];
|
||||
}
|
||||
};
|
||||
|
||||
static q3_header header;
|
||||
@@ -156,27 +166,31 @@ static Frustum r_frustum;
|
||||
static Vector r_frustedges[12];
|
||||
static map<int, Q3BSPFace*> q3face_map;
|
||||
|
||||
extern gxScene *gx_scene;
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxScene* gx_scene;
|
||||
extern gxRuntime* gx_runtime;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
//#define SWAPTRIS
|
||||
Vector static tf(const Vector &v) {
|
||||
Vector static tf(const Vector& v)
|
||||
{
|
||||
return Vector(-v.y, v.z, v.x);
|
||||
}
|
||||
|
||||
#ifdef BETA
|
||||
static void debuglog(const string &t) {
|
||||
static void debuglog(const string& t)
|
||||
{
|
||||
gx_runtime->debugLog(t.c_str());
|
||||
}
|
||||
#else
|
||||
static void debuglog(const string &t) {}
|
||||
static void debuglog(const string& t) {}
|
||||
#endif
|
||||
|
||||
static Surf *findSurf(q3_face *f) {
|
||||
static Surf* findSurf(q3_face* f)
|
||||
{
|
||||
FaceMap::const_iterator it = face_map.find(f);
|
||||
if (it != face_map.end()) return it->second;
|
||||
Surf *s = new Surf;
|
||||
if (it != face_map.end())
|
||||
return it->second;
|
||||
Surf* s = new Surf;
|
||||
s->texture = f->texture;
|
||||
s->lm_index = f->lm_index;
|
||||
face_map.insert(make_pair(f, s));
|
||||
@@ -184,9 +198,10 @@ static Surf *findSurf(q3_face *f) {
|
||||
return s;
|
||||
}
|
||||
|
||||
void Q3BSPRep::createTextures() {
|
||||
void Q3BSPRep::createTextures()
|
||||
{
|
||||
int n_texs = header.dir[1].length / sizeof(q3_tex);
|
||||
q3_tex *q3tex = (q3_tex*)header.dir[1].lump;
|
||||
q3_tex* q3tex = (q3_tex*)header.dir[1].lump;
|
||||
for (int k = 0; k < n_texs; ++k) {
|
||||
string t = string(q3tex->name);
|
||||
char fl[32], co[32];
|
||||
@@ -200,7 +215,8 @@ void Q3BSPRep::createTextures() {
|
||||
tex = Texture(t + ".png", 1);
|
||||
if (!tex.getCanvas(0)) {
|
||||
tex = Texture(t + ".dds", 1);
|
||||
if (!tex.getCanvas(0)) debuglog("Failed!");
|
||||
if (!tex.getCanvas(0))
|
||||
debuglog("Failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,17 +226,19 @@ void Q3BSPRep::createTextures() {
|
||||
}
|
||||
}
|
||||
|
||||
void Q3BSPRep::createLightMaps() {
|
||||
void Q3BSPRep::createLightMaps()
|
||||
{
|
||||
int n_lmaps = header.dir[14].length / (128 * 128 * 3);
|
||||
unsigned char *rgb = (unsigned char*)header.dir[14].lump;
|
||||
unsigned char* rgb = (unsigned char*)header.dir[14].lump;
|
||||
unsigned char adj[256];
|
||||
int k;
|
||||
for (k = 0; k < 256; ++k) adj[k] = pow(k / 255.0f, gamma_adj)*255.0f;
|
||||
for (k = 0; k < 256; ++k)
|
||||
adj[k] = pow(k / 255.0f, gamma_adj) * 255.0f;
|
||||
|
||||
for (k = 0; k < n_lmaps; ++k) {
|
||||
Texture tex(128, 128, 1 + 8 + 16 + 32, 1);
|
||||
tex.setBlend(gxScene::BLEND_ADD);
|
||||
gxCanvas *c = tex.getCanvas(0);
|
||||
gxCanvas* c = tex.getCanvas(0);
|
||||
c->lock();
|
||||
for (int y = 0; y < 128; ++y) {
|
||||
for (int x = 0; x < 128; ++x) {
|
||||
@@ -234,19 +252,21 @@ void Q3BSPRep::createLightMaps() {
|
||||
}
|
||||
}
|
||||
|
||||
void Q3BSPRep::createVis() {
|
||||
int *vis = (int*)header.dir[16].lump;
|
||||
void Q3BSPRep::createVis()
|
||||
{
|
||||
int* vis = (int*)header.dir[16].lump;
|
||||
int n_vecs = *vis++;
|
||||
vis_sz = *vis++;
|
||||
debuglog("vis: " + itoa(n_vecs) + "," + itoa(vis_sz));
|
||||
vis_data = new char[n_vecs*vis_sz];
|
||||
memcpy(vis_data, vis, n_vecs*vis_sz);
|
||||
vis_data = new char[n_vecs * vis_sz];
|
||||
memcpy(vis_data, vis, n_vecs * vis_sz);
|
||||
}
|
||||
|
||||
void Q3BSPRep::createCollider() {
|
||||
void Q3BSPRep::createCollider()
|
||||
{
|
||||
vector<MeshCollider::Vertex> coll_verts;
|
||||
int n_verts = header.dir[10].length / sizeof(q3_vertex);
|
||||
q3_vertex *t = (q3_vertex*)header.dir[10].lump;
|
||||
q3_vertex* t = (q3_vertex*)header.dir[10].lump;
|
||||
MeshCollider::Vertex cv;
|
||||
int k;
|
||||
for (k = 0; k < n_verts; ++k) {
|
||||
@@ -269,23 +289,24 @@ void Q3BSPRep::createCollider() {
|
||||
coll_tris.clear();
|
||||
}
|
||||
|
||||
void Q3BSPRep::createSurfs() {
|
||||
void Q3BSPRep::createSurfs()
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < t_surfs.size(); ++k) {
|
||||
Surf *s = t_surfs[k];
|
||||
gxMesh *mesh = gx_graphics->createMesh(s->verts.size(), s->tris.size() / 3, 0);
|
||||
Surf* s = t_surfs[k];
|
||||
gxMesh* mesh = gx_graphics->createMesh(s->verts.size(), s->tris.size() / 3, 0);
|
||||
|
||||
mesh->lock(true);
|
||||
int j;
|
||||
for (j = 0; j < s->verts.size(); ++j) {
|
||||
q3_vertex *t;
|
||||
q3_vertex* t;
|
||||
int n = s->verts[j];
|
||||
if (n >= 0) {
|
||||
t = (q3_vertex*)header.dir[10].lump + n;
|
||||
} else {
|
||||
t = &p_verts[-n - 1];
|
||||
}
|
||||
float tex_coords[2][2] = { {t->tex_coords[2],t->tex_coords[3]},{t->tex_coords[0],t->tex_coords[1]} };
|
||||
float tex_coords[2][2] = {{t->tex_coords[2], t->tex_coords[3]}, {t->tex_coords[0], t->tex_coords[1]}};
|
||||
unsigned argb = 0xff000000 | (t->color[0] << 16) | (t->color[1] << 8) | t->color[2];
|
||||
mesh->setVertex(j, tf(t->coords), tf(t->normal), argb, tex_coords);
|
||||
}
|
||||
@@ -298,7 +319,7 @@ void Q3BSPRep::createSurfs() {
|
||||
}
|
||||
mesh->unlock();
|
||||
|
||||
Q3BSPSurf *surf = new Q3BSPSurf;
|
||||
Q3BSPSurf* surf = new Q3BSPSurf;
|
||||
surf->texture = s->texture;
|
||||
surf->lm_index = s->lm_index;
|
||||
surf->mesh = mesh;
|
||||
@@ -306,9 +327,10 @@ void Q3BSPRep::createSurfs() {
|
||||
s->surf = surf;
|
||||
}
|
||||
for (k = 0; k < faces.size(); ++k) {
|
||||
Q3BSPFace *f = faces[k];
|
||||
Q3BSPFace* f = faces[k];
|
||||
f->surf = f->t_surf->surf;
|
||||
f->tri /= 3; f->n_tris /= 3;
|
||||
f->tri /= 3;
|
||||
f->n_tris /= 3;
|
||||
}
|
||||
for (k = 0; k < t_surfs.size(); ++k) {
|
||||
delete t_surfs[k];
|
||||
@@ -318,16 +340,18 @@ void Q3BSPRep::createSurfs() {
|
||||
p_verts.clear();
|
||||
}
|
||||
|
||||
static void average(const q3_vertex &a, const q3_vertex &b, q3_vertex *c) {
|
||||
c->coords = (a.coords + b.coords)*.5f;
|
||||
c->normal = (a.normal + b.normal)*.5f;
|
||||
static void average(const q3_vertex& a, const q3_vertex& b, q3_vertex* c)
|
||||
{
|
||||
c->coords = (a.coords + b.coords) * .5f;
|
||||
c->normal = (a.normal + b.normal) * .5f;
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
c->color[k] = (a.color[k] + b.color[k] + 1) / 2;
|
||||
c->tex_coords[k] = (a.tex_coords[k] + b.tex_coords[k])*.5f;
|
||||
c->tex_coords[k] = (a.tex_coords[k] + b.tex_coords[k]) * .5f;
|
||||
}
|
||||
}
|
||||
|
||||
static void subdivide(vector<q3_vertex> &verts, int level, int index, int step) {
|
||||
static void subdivide(vector<q3_vertex>& verts, int level, int index, int step)
|
||||
{
|
||||
if (!level) {
|
||||
q3_vertex t1, t2;
|
||||
average(verts[index], verts[index + step], &t1);
|
||||
@@ -342,49 +366,49 @@ static void subdivide(vector<q3_vertex> &verts, int level, int index, int step)
|
||||
subdivide(verts, level - 1, index + step, step / 2);
|
||||
}
|
||||
|
||||
static void patchFace(Q3BSPFace *face, q3_face *q3face, bool draw, bool solid, int level) {
|
||||
|
||||
static void patchFace(Q3BSPFace* face, q3_face* q3face, bool draw, bool solid, int level)
|
||||
{
|
||||
int k, x, y;
|
||||
vector<q3_vertex> verts;
|
||||
|
||||
if (draw) {
|
||||
int step = 1 << level;
|
||||
int size_x = (q3face->patch_size[0] - 1)*step + 1;
|
||||
int size_y = (q3face->patch_size[1] - 1)*step + 1;
|
||||
verts.resize(size_x*size_y);
|
||||
int size_x = (q3face->patch_size[0] - 1) * step + 1;
|
||||
int size_y = (q3face->patch_size[1] - 1) * step + 1;
|
||||
verts.resize(size_x * size_y);
|
||||
|
||||
//seed initial verts
|
||||
q3_vertex *t = (q3_vertex*)header.dir[10].lump + q3face->vertex;
|
||||
q3_vertex* t = (q3_vertex*)header.dir[10].lump + q3face->vertex;
|
||||
for (y = 0; y < size_y; y += step) {
|
||||
for (x = 0; x < size_x; x += step) {
|
||||
verts[y*size_x + x] = *t++;
|
||||
verts[y * size_x + x] = *t++;
|
||||
}
|
||||
}
|
||||
//subdivide!
|
||||
for (y = 0; y < size_y; y += step) {
|
||||
for (x = 0; x < size_x - 1; x += step * 2) {
|
||||
subdivide(verts, level, y*size_x + x, step);
|
||||
subdivide(verts, level, y * size_x + x, step);
|
||||
}
|
||||
}
|
||||
for (x = 0; x < size_x; ++x) {
|
||||
for (y = 0; y < size_y - 1; y += step * 2) {
|
||||
subdivide(verts, level, y*size_x + x, size_x*step);
|
||||
subdivide(verts, level, y * size_x + x, size_x * step);
|
||||
}
|
||||
}
|
||||
|
||||
Surf *surf = face->t_surf;
|
||||
Surf* surf = face->t_surf;
|
||||
int vert = surf->verts.size() - face->vert;
|
||||
|
||||
//generate patch verts
|
||||
for (k = 0; k < size_x*size_y; ++k) {
|
||||
for (k = 0; k < size_x * size_y; ++k) {
|
||||
p_verts.push_back(verts[k]);
|
||||
surf->verts.push_back(p_verts.size()); // Why was there a - here
|
||||
}
|
||||
face->n_verts += size_x*size_y;
|
||||
face->n_verts += size_x * size_y;
|
||||
|
||||
//generate tris...
|
||||
for (y = 0; y < size_y - 1; ++y) {
|
||||
int n = y*size_x + vert;
|
||||
int n = y * size_x + vert;
|
||||
for (x = 0; x < size_x - 1; ++n, ++x) {
|
||||
surf->tris.push_back(n);
|
||||
surf->tris.push_back(n + size_x);
|
||||
@@ -394,7 +418,7 @@ static void patchFace(Q3BSPFace *face, q3_face *q3face, bool draw, bool solid, i
|
||||
surf->tris.push_back(n + size_x);
|
||||
}
|
||||
}
|
||||
face->n_tris += (size_x - 1)*(size_y - 1) * 6;
|
||||
face->n_tris += (size_x - 1) * (size_y - 1) * 6;
|
||||
}
|
||||
|
||||
if (solid) {
|
||||
@@ -402,33 +426,36 @@ static void patchFace(Q3BSPFace *face, q3_face *q3face, bool draw, bool solid, i
|
||||
int step = 1;
|
||||
int size_x = q3face->patch_size[0];
|
||||
int size_y = q3face->patch_size[1];
|
||||
verts.resize(size_x*size_y);
|
||||
verts.resize(size_x * size_y);
|
||||
|
||||
//seed initial verts
|
||||
q3_vertex *t = (q3_vertex*)header.dir[10].lump + q3face->vertex;
|
||||
for (k = 0; k < size_x*size_y; ++k) verts[k] = *t++;
|
||||
q3_vertex* t = (q3_vertex*)header.dir[10].lump + q3face->vertex;
|
||||
for (k = 0; k < size_x * size_y; ++k)
|
||||
verts[k] = *t++;
|
||||
//subdivide!
|
||||
for (y = 0; y < size_y; y += step) {
|
||||
for (x = 0; x < size_x - 1; x += step * 2) {
|
||||
subdivide(verts, 0, y*size_x + x, step);
|
||||
subdivide(verts, 0, y * size_x + x, step);
|
||||
}
|
||||
}
|
||||
for (x = 0; x < size_x; ++x) {
|
||||
for (y = 0; y < size_y - 1; y += step * 2) {
|
||||
subdivide(verts, 0, y*size_x + x, size_x*step);
|
||||
subdivide(verts, 0, y * size_x + x, size_x * step);
|
||||
}
|
||||
}
|
||||
|
||||
int vert = header.dir[10].length / sizeof(q3_vertex) + p_coll_verts.size();
|
||||
|
||||
//generate patch verts
|
||||
for (k = 0; k < size_x*size_y; ++k) p_coll_verts.push_back(tf(verts[k].coords));
|
||||
for (k = 0; k < size_x * size_y; ++k)
|
||||
p_coll_verts.push_back(tf(verts[k].coords));
|
||||
|
||||
MeshCollider::Triangle ct;
|
||||
ct.surface = 0; ct.index = 0;
|
||||
ct.surface = 0;
|
||||
ct.index = 0;
|
||||
//generate tris...
|
||||
for (y = 0; y < size_y - 1; ++y) {
|
||||
int n = y*size_x + vert;
|
||||
int n = y * size_x + vert;
|
||||
for (x = 0; x < size_x - 1; ++n, ++x) {
|
||||
ct.verts[0] = n;
|
||||
ct.verts[1] = n + size_x;
|
||||
@@ -443,12 +470,14 @@ static void patchFace(Q3BSPFace *face, q3_face *q3face, bool draw, bool solid, i
|
||||
}
|
||||
}
|
||||
|
||||
static void meshFace(Q3BSPFace *face, q3_face *q3face, bool draw, bool solid) {
|
||||
static void meshFace(Q3BSPFace* face, q3_face* q3face, bool draw, bool solid)
|
||||
{
|
||||
static map<int, int> vert_map;
|
||||
vert_map.clear();
|
||||
int *meshverts = (int*)header.dir[11].lump + q3face->meshvert;
|
||||
int* meshverts = (int*)header.dir[11].lump + q3face->meshvert;
|
||||
MeshCollider::Triangle ct;
|
||||
ct.surface = 0; ct.index = 0;
|
||||
ct.surface = 0;
|
||||
ct.index = 0;
|
||||
for (int j = 0; j < q3face->n_meshverts; j += 3) {
|
||||
for (int q = 0; q < 3; ++q) {
|
||||
int n = meshverts[j + q] + q3face->vertex;
|
||||
@@ -463,17 +492,19 @@ static void meshFace(Q3BSPFace *face, q3_face *q3face, bool draw, bool solid) {
|
||||
}
|
||||
ct.verts[q] = n;
|
||||
}
|
||||
if (solid) coll_tris.push_back(ct);
|
||||
if (solid)
|
||||
coll_tris.push_back(ct);
|
||||
}
|
||||
}
|
||||
|
||||
static Q3BSPBrush *createBrush(int n) {
|
||||
Q3BSPBrush *brush = new Q3BSPBrush;
|
||||
q3_brush *q3brush = (q3_brush*)header.dir[8].lump + n;
|
||||
q3_brushside *q3brushside = (q3_brushside*)header.dir[9].lump + q3brush->brushside;
|
||||
static Q3BSPBrush* createBrush(int n)
|
||||
{
|
||||
Q3BSPBrush* brush = new Q3BSPBrush;
|
||||
q3_brush* q3brush = (q3_brush*)header.dir[8].lump + n;
|
||||
q3_brushside* q3brushside = (q3_brushside*)header.dir[9].lump + q3brush->brushside;
|
||||
Plane p;
|
||||
for (int j = 0; j < q3brush->n_brushsides; ++j) {
|
||||
q3_plane *q3plane = (q3_plane*)header.dir[2].lump + q3brushside[j].plane;
|
||||
q3_plane* q3plane = (q3_plane*)header.dir[2].lump + q3brushside[j].plane;
|
||||
p.n = tf(q3plane->normal);
|
||||
p.d = -q3plane->distance;
|
||||
brush->planes.push_back(p);
|
||||
@@ -481,10 +512,11 @@ static Q3BSPBrush *createBrush(int n) {
|
||||
return brush;
|
||||
}
|
||||
|
||||
Q3BSPLeaf *Q3BSPRep::createLeaf(int n) {
|
||||
q3_leaf *q3leaf = (q3_leaf*)header.dir[4].lump + n;
|
||||
Q3BSPLeaf* Q3BSPRep::createLeaf(int n)
|
||||
{
|
||||
q3_leaf* q3leaf = (q3_leaf*)header.dir[4].lump + n;
|
||||
|
||||
Q3BSPLeaf *leaf = new Q3BSPLeaf;
|
||||
Q3BSPLeaf* leaf = new Q3BSPLeaf;
|
||||
|
||||
leaf->cluster = q3leaf->cluster;
|
||||
|
||||
@@ -492,37 +524,42 @@ Q3BSPLeaf *Q3BSPRep::createLeaf(int n) {
|
||||
Vector maxs(q3leaf->maxs[0], q3leaf->maxs[1], q3leaf->maxs[2]);
|
||||
leaf->box = Box(tf(mins));
|
||||
leaf->box.update(tf(maxs));
|
||||
int *leaffaces = (int*)header.dir[5].lump + q3leaf->leafface;
|
||||
int* leaffaces = (int*)header.dir[5].lump + q3leaf->leafface;
|
||||
|
||||
for (int k = 0; k < q3leaf->n_leaffaces; ++k) {
|
||||
|
||||
int face_n = leaffaces[k];
|
||||
|
||||
map<int, Q3BSPFace*>::const_iterator it = q3face_map.find(face_n);
|
||||
if (it != q3face_map.end()) {
|
||||
if (it->second) leaf->faces.push_back(it->second);
|
||||
if (it->second)
|
||||
leaf->faces.push_back(it->second);
|
||||
continue;
|
||||
}
|
||||
|
||||
q3_face *q3face = (q3_face*)header.dir[13].lump + leaffaces[k];
|
||||
q3_face* q3face = (q3_face*)header.dir[13].lump + leaffaces[k];
|
||||
|
||||
if (q3face->type == 1 || q3face->type == 3) {
|
||||
if (!q3face->n_meshverts || (q3face->n_meshverts % 3)) continue;
|
||||
} else if (q3face->type != 2) continue;
|
||||
if (!q3face->n_meshverts || (q3face->n_meshverts % 3))
|
||||
continue;
|
||||
} else if (q3face->type != 2)
|
||||
continue;
|
||||
|
||||
bool draw = true, solid = true;
|
||||
|
||||
if (q3face->texture >= 0) {
|
||||
q3_tex *q3tex = (q3_tex*)header.dir[1].lump + q3face->texture;
|
||||
if (!(q3tex->contents & 1)) continue;
|
||||
if (q3tex->flags & 0x84) draw = false;
|
||||
q3_tex* q3tex = (q3_tex*)header.dir[1].lump + q3face->texture;
|
||||
if (!(q3tex->contents & 1))
|
||||
continue;
|
||||
if (q3tex->flags & 0x84)
|
||||
draw = false;
|
||||
}
|
||||
|
||||
if (!draw && !solid) continue;
|
||||
if (!draw && !solid)
|
||||
continue;
|
||||
|
||||
Q3BSPFace *face = 0;
|
||||
Q3BSPFace* face = 0;
|
||||
if (draw) {
|
||||
Surf *surf = findSurf(q3face);
|
||||
Surf* surf = findSurf(q3face);
|
||||
face = new Q3BSPFace;
|
||||
face->t_surf = surf;
|
||||
face->vert = surf->verts.size();
|
||||
@@ -543,11 +580,12 @@ Q3BSPLeaf *Q3BSPRep::createLeaf(int n) {
|
||||
return leaf;
|
||||
}
|
||||
|
||||
Q3BSPNode *Q3BSPRep::createNode(int n) {
|
||||
q3_node *q3node = (q3_node*)header.dir[3].lump + n;
|
||||
q3_plane *q3plane = (q3_plane*)header.dir[2].lump + q3node->plane;
|
||||
Q3BSPNode* Q3BSPRep::createNode(int n)
|
||||
{
|
||||
q3_node* q3node = (q3_node*)header.dir[3].lump + n;
|
||||
q3_plane* q3plane = (q3_plane*)header.dir[2].lump + q3node->plane;
|
||||
|
||||
Q3BSPNode *node = new Q3BSPNode;
|
||||
Q3BSPNode* node = new Q3BSPNode;
|
||||
|
||||
Vector mins(q3node->mins[0], q3node->mins[1], q3node->mins[2]);
|
||||
Vector maxs(q3node->maxs[0], q3node->maxs[1], q3node->maxs[2]);
|
||||
@@ -570,15 +608,18 @@ Q3BSPNode *Q3BSPRep::createNode(int n) {
|
||||
return node;
|
||||
}
|
||||
|
||||
Q3BSPRep::Q3BSPRep(const string &f, float gam) :root_node(0), vis_sz(0), vis_data(0), use_lmap(true) {
|
||||
|
||||
Q3BSPRep::Q3BSPRep(const string& f, float gam) : root_node(0), vis_sz(0), vis_data(0), use_lmap(true)
|
||||
{
|
||||
gamma_adj = 1 - gam;
|
||||
|
||||
FILE *buf = fopen(f.c_str(), "rb"); if (!buf) return;
|
||||
FILE* buf = fopen(f.c_str(), "rb");
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
fread(&header, sizeof(header), 1, buf);
|
||||
if (header.magic != 'PSBI' || header.version != 0x2e) {
|
||||
fclose(buf); return;
|
||||
fclose(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
debuglog("Header OK");
|
||||
@@ -621,7 +662,8 @@ Q3BSPRep::Q3BSPRep(const string &f, float gam) :root_node(0), vis_sz(0), vis_dat
|
||||
q3face_map.clear();
|
||||
}
|
||||
|
||||
Q3BSPRep::~Q3BSPRep() {
|
||||
Q3BSPRep::~Q3BSPRep()
|
||||
{
|
||||
delete root_node;
|
||||
delete[] vis_data;
|
||||
int k;
|
||||
@@ -634,80 +676,99 @@ Q3BSPRep::~Q3BSPRep() {
|
||||
}
|
||||
}
|
||||
|
||||
void Q3BSPRep::vis(Q3BSPNode *n) {
|
||||
void Q3BSPRep::vis(Q3BSPNode* n)
|
||||
{
|
||||
int i = n->plane.distance(r_eye) < 0;
|
||||
if (n->nodes[i]) vis(n->nodes[i]);
|
||||
else r_cluster = n->leafs[i]->cluster;
|
||||
if (n->nodes[i])
|
||||
vis(n->nodes[i]);
|
||||
else
|
||||
r_cluster = n->leafs[i]->cluster;
|
||||
}
|
||||
|
||||
static bool cull(const Box &b, int *clip) {
|
||||
static bool cull(const Box& b, int* clip)
|
||||
{
|
||||
for (int n = 0; n < 6; ++n) {
|
||||
int mask = 1 << n;
|
||||
if (!(*clip & mask)) continue;
|
||||
const Plane &p = r_frustum.getPlane(n);
|
||||
int q =
|
||||
(p.distance(b.corner(0)) >= 0) + (p.distance(b.corner(1)) >= 0) +
|
||||
(p.distance(b.corner(2)) >= 0) + (p.distance(b.corner(3)) >= 0) +
|
||||
(p.distance(b.corner(4)) >= 0) + (p.distance(b.corner(5)) >= 0) +
|
||||
(p.distance(b.corner(6)) >= 0) + (p.distance(b.corner(7)) >= 0);
|
||||
if (!q) return false;
|
||||
if (q == 8) *clip &= ~mask;
|
||||
if (!(*clip & mask))
|
||||
continue;
|
||||
const Plane& p = r_frustum.getPlane(n);
|
||||
int q = (p.distance(b.corner(0)) >= 0) + (p.distance(b.corner(1)) >= 0) + (p.distance(b.corner(2)) >= 0)
|
||||
+ (p.distance(b.corner(3)) >= 0) + (p.distance(b.corner(4)) >= 0) + (p.distance(b.corner(5)) >= 0)
|
||||
+ (p.distance(b.corner(6)) >= 0) + (p.distance(b.corner(7)) >= 0);
|
||||
if (!q)
|
||||
return false;
|
||||
if (q == 8)
|
||||
*clip &= ~mask;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Q3BSPRep::render(Q3BSPLeaf *l, int clip) {
|
||||
void Q3BSPRep::render(Q3BSPLeaf* l, int clip)
|
||||
{
|
||||
int cluster = l->cluster;
|
||||
if (cluster < 0) return;
|
||||
if (cluster < 0)
|
||||
return;
|
||||
|
||||
if (r_cluster >= 0) {
|
||||
if (!(vis_data[cluster*vis_sz + r_cluster / 8] & (1 << (r_cluster & 7)))) return;
|
||||
if (!(vis_data[cluster * vis_sz + r_cluster / 8] & (1 << (r_cluster & 7))))
|
||||
return;
|
||||
}
|
||||
|
||||
if (clip && !cull(l->box, &clip)) return;
|
||||
if (clip && !cull(l->box, &clip))
|
||||
return;
|
||||
|
||||
for (int k = 0; k < l->faces.size(); ++k) {
|
||||
Q3BSPFace *f = l->faces[k];
|
||||
if (Q3BSPSurf *s = f->surf) {
|
||||
if (!s->r_faces.size()) r_surfs.push_back(s);
|
||||
Q3BSPFace* f = l->faces[k];
|
||||
if (Q3BSPSurf* s = f->surf) {
|
||||
if (!s->r_faces.size())
|
||||
r_surfs.push_back(s);
|
||||
s->r_faces.push_back(f);
|
||||
f->surf = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Q3BSPRep::render(Q3BSPNode *n, int clip) {
|
||||
if (clip && !cull(n->box, &clip)) return;
|
||||
void Q3BSPRep::render(Q3BSPNode* n, int clip)
|
||||
{
|
||||
if (clip && !cull(n->box, &clip))
|
||||
return;
|
||||
|
||||
//draw front to back...
|
||||
int i = n->plane.distance(r_eye) < 0;
|
||||
if (n->nodes[i]) render(n->nodes[i], clip);
|
||||
else render(n->leafs[i], clip);
|
||||
if (n->nodes[i])
|
||||
render(n->nodes[i], clip);
|
||||
else
|
||||
render(n->leafs[i], clip);
|
||||
i ^= 1;
|
||||
if (n->nodes[i]) render(n->nodes[i], clip);
|
||||
else render(n->leafs[i], clip);
|
||||
if (n->nodes[i])
|
||||
render(n->nodes[i], clip);
|
||||
else
|
||||
render(n->leafs[i], clip);
|
||||
}
|
||||
|
||||
void Q3BSPRep::render(Model *model, const RenderContext &rc) {
|
||||
void Q3BSPRep::render(Model* model, const RenderContext& rc)
|
||||
{
|
||||
r_eye = -model->getRenderTform() * rc.getCameraTform().v;
|
||||
new(&r_frustum) Frustum(rc.getWorldFrustum(), -model->getRenderTform());
|
||||
new (&r_frustum) Frustum(rc.getWorldFrustum(), -model->getRenderTform());
|
||||
|
||||
vis(root_node);
|
||||
if (r_cluster == -1) debuglog("No cluster!");
|
||||
if (r_cluster == -1)
|
||||
debuglog("No cluster!");
|
||||
render(root_node, 0x3f);
|
||||
|
||||
if (!r_surfs.size()) return;
|
||||
if (!r_surfs.size())
|
||||
return;
|
||||
|
||||
gx_scene->setAmbient2(&ambient.x);
|
||||
gx_scene->setWorldMatrix((gxScene::Matrix*)&model->getRenderTform());
|
||||
|
||||
int k;
|
||||
for (k = 0; k < r_surfs.size(); ++k) {
|
||||
Q3BSPSurf *s = r_surfs[k];
|
||||
Q3BSPSurf* s = r_surfs[k];
|
||||
gx_scene->setRenderState(s->brush.getRenderState());
|
||||
int j;
|
||||
for (j = 0; j < s->r_faces.size(); ++j) {
|
||||
Q3BSPFace *f = s->r_faces[j];
|
||||
Q3BSPFace* f = s->r_faces[j];
|
||||
gx_scene->render(s->mesh, f->vert, f->n_verts, f->tri, f->n_tris);
|
||||
f->surf = s;
|
||||
}
|
||||
@@ -716,21 +777,25 @@ void Q3BSPRep::render(Model *model, const RenderContext &rc) {
|
||||
r_surfs.clear();
|
||||
}
|
||||
|
||||
bool Q3BSPRep::collide(const Line &line, float radius, Collision *curr_coll, const Transform &t) {
|
||||
bool Q3BSPRep::collide(const Line& line, float radius, Collision* curr_coll, const Transform& t)
|
||||
{
|
||||
return collider->collide(line, radius, curr_coll, t);
|
||||
}
|
||||
|
||||
void Q3BSPRep::setAmbient(const Vector &t) {
|
||||
void Q3BSPRep::setAmbient(const Vector& t)
|
||||
{
|
||||
ambient = t;
|
||||
}
|
||||
|
||||
void Q3BSPRep::setLighting(bool lmap) {
|
||||
if (lmap == use_lmap) return;
|
||||
void Q3BSPRep::setLighting(bool lmap)
|
||||
{
|
||||
if (lmap == use_lmap)
|
||||
return;
|
||||
int fx = gxScene::FX_CONDLIGHT;
|
||||
if (use_lmap = lmap) {
|
||||
int k;
|
||||
for (k = 0; k < surfs.size(); ++k) {
|
||||
Q3BSPSurf *s = surfs[k];
|
||||
Q3BSPSurf* s = surfs[k];
|
||||
if (s->lm_index >= 0) {
|
||||
//has a lightmap...
|
||||
s->brush.setFX(fx);
|
||||
@@ -749,7 +814,7 @@ void Q3BSPRep::setLighting(bool lmap) {
|
||||
int k;
|
||||
Texture tex;
|
||||
for (k = 0; k < surfs.size(); ++k) {
|
||||
Q3BSPSurf *s = surfs[k];
|
||||
Q3BSPSurf* s = surfs[k];
|
||||
s->brush.setFX(fx | gxScene::FX_EMISSIVE);
|
||||
if (s->texture >= 0) {
|
||||
s->brush.setTexture(0, textures[s->texture], 0);
|
||||
|
||||
@@ -2,42 +2,45 @@
|
||||
#ifndef Q3BSPREP_H
|
||||
#define Q3BSPREP_H
|
||||
|
||||
#include "model.hpp"
|
||||
#include "meshcollider.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
struct Q3BSPSurf;
|
||||
struct Q3BSPFace;
|
||||
struct Q3BSPLeaf;
|
||||
struct Q3BSPNode;
|
||||
|
||||
class Q3BSPRep{
|
||||
public:
|
||||
class Q3BSPRep {
|
||||
public:
|
||||
//constructor
|
||||
Q3BSPRep( const string &f,float gamma_adj );
|
||||
Q3BSPRep(const string& f, float gamma_adj);
|
||||
~Q3BSPRep();
|
||||
|
||||
void render( Model *model,const RenderContext &rc );
|
||||
bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &t );
|
||||
void render(Model* model, const RenderContext& rc);
|
||||
bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& t);
|
||||
|
||||
void setAmbient( const Vector &t );
|
||||
void setLighting( bool use_lmap );
|
||||
void setAmbient(const Vector& t);
|
||||
void setLighting(bool use_lmap);
|
||||
|
||||
bool isValid()const{ return root_node!=0; }
|
||||
bool isValid() const
|
||||
{
|
||||
return root_node != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Q3BSPNode *root_node;
|
||||
private:
|
||||
Q3BSPNode* root_node;
|
||||
|
||||
Vector ambient;
|
||||
|
||||
vector<Q3BSPFace*> faces;
|
||||
vector<Q3BSPSurf*> surfs,r_surfs;
|
||||
vector<Texture> textures,light_maps;
|
||||
vector<Q3BSPSurf*> surfs, r_surfs;
|
||||
vector<Texture> textures, light_maps;
|
||||
|
||||
int vis_sz;
|
||||
char *vis_data;
|
||||
char* vis_data;
|
||||
bool use_lmap;
|
||||
|
||||
MeshCollider *collider;
|
||||
MeshCollider* collider;
|
||||
|
||||
void createVis();
|
||||
void createSurfs();
|
||||
@@ -45,12 +48,12 @@ private:
|
||||
|
||||
void createTextures();
|
||||
void createLightMaps();
|
||||
Q3BSPLeaf *createLeaf( int n );
|
||||
Q3BSPNode *createNode( int n );
|
||||
Q3BSPLeaf* createLeaf(int n);
|
||||
Q3BSPNode* createNode(int n);
|
||||
|
||||
void vis( Q3BSPNode *node );
|
||||
void render( Q3BSPLeaf *l,int clip );
|
||||
void render( Q3BSPNode *n,int clip );
|
||||
void vis(Q3BSPNode* node);
|
||||
void render(Q3BSPLeaf* l, int clip);
|
||||
void render(Q3BSPNode* n, int clip);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,21 +4,33 @@
|
||||
|
||||
#include "frustum.hpp"
|
||||
|
||||
class RenderContext{
|
||||
public:
|
||||
RenderContext( const Transform &t,const Frustum &f,bool r ):
|
||||
camera_tform( t ),camera_frustum(f),ref(r){
|
||||
new( &world_frustum ) Frustum( f,t );
|
||||
class RenderContext {
|
||||
public:
|
||||
RenderContext(const Transform& t, const Frustum& f, bool r) : camera_tform(t), camera_frustum(f), ref(r)
|
||||
{
|
||||
new (&world_frustum) Frustum(f, t);
|
||||
}
|
||||
|
||||
bool isReflected()const{ return ref; }
|
||||
const Transform &getCameraTform()const{ return camera_tform; }
|
||||
const Frustum &getWorldFrustum()const{ return world_frustum; }
|
||||
const Frustum &getCameraFrustum()const{ return camera_frustum; }
|
||||
bool isReflected() const
|
||||
{
|
||||
return ref;
|
||||
}
|
||||
const Transform& getCameraTform() const
|
||||
{
|
||||
return camera_tform;
|
||||
}
|
||||
const Frustum& getWorldFrustum() const
|
||||
{
|
||||
return world_frustum;
|
||||
}
|
||||
const Frustum& getCameraFrustum() const
|
||||
{
|
||||
return camera_frustum;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
Transform camera_tform;
|
||||
Frustum world_frustum,camera_frustum;
|
||||
Frustum world_frustum, camera_frustum;
|
||||
bool ref;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "skinmodel.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
SkinModel::SkinModel(){
|
||||
setRenderSpace( RENDER_SPACE_WORLD );
|
||||
SkinModel::SkinModel()
|
||||
{
|
||||
setRenderSpace(RENDER_SPACE_WORLD);
|
||||
}
|
||||
|
||||
void SkinModel::setBones( const vector<Object*> &bones ){
|
||||
_bones=bones;
|
||||
_surf_bones.resize( _bones.size() );
|
||||
void SkinModel::setBones(const vector<Object*>& bones)
|
||||
{
|
||||
_bones = bones;
|
||||
_surf_bones.resize(_bones.size());
|
||||
}
|
||||
|
||||
void SkinModel::render( const RenderContext &rc ){
|
||||
|
||||
void SkinModel::render(const RenderContext& rc)
|
||||
{
|
||||
int k;
|
||||
for( k=0;k<_bones.size();++k ){
|
||||
Object *obj=_bones[k];
|
||||
_surf_bones[k].coord_tform=obj->getRenderTform();
|
||||
_surf_bones[k].normal_tform=_surf_bones[k].coord_tform.m.cofactor();
|
||||
for (k = 0; k < _bones.size(); ++k) {
|
||||
Object* obj = _bones[k];
|
||||
_surf_bones[k].coord_tform = obj->getRenderTform();
|
||||
_surf_bones[k].normal_tform = _surf_bones[k].coord_tform.m.cofactor();
|
||||
}
|
||||
|
||||
const MeshModel::SurfaceList &_surfs=getSurfaces();
|
||||
const MeshModel::SurfaceList& _surfs = getSurfaces();
|
||||
|
||||
for( k=0;k<_surfs.size();++k ){
|
||||
Surface *surf=_surfs[k];
|
||||
if( gxMesh *mesh=surf->getMesh( _surf_bones ) ){
|
||||
enqueue( mesh,0,surf->numVertices(),0,surf->numTriangles(),surf->getBrush() );
|
||||
for (k = 0; k < _surfs.size(); ++k) {
|
||||
Surface* surf = _surfs[k];
|
||||
if (gxMesh* mesh = surf->getMesh(_surf_bones)) {
|
||||
enqueue(mesh, 0, surf->numVertices(), 0, surf->numTriangles(), surf->getBrush());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
|
||||
#include "meshmodel.hpp"
|
||||
|
||||
class SkinModel : public MeshModel{
|
||||
class SkinModel : public MeshModel {
|
||||
vector<Object*> _bones;
|
||||
vector<Surface::Bone> _surf_bones;
|
||||
public:
|
||||
|
||||
public:
|
||||
SkinModel();
|
||||
|
||||
void setBones( const vector<Object*> &bones );
|
||||
void setBones(const vector<Object*>& bones);
|
||||
|
||||
//Model interface
|
||||
virtual void render( const RenderContext &rc );
|
||||
virtual void render(const RenderContext& rc);
|
||||
};
|
||||
|
||||
#endif
|
||||
+98
-86
@@ -1,139 +1,151 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "sprite.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern float stats3d[];
|
||||
|
||||
static float null[]={0,0,0};
|
||||
static float null[] = {0, 0, 0};
|
||||
|
||||
static float tex_coords0[2][2]={ {0,0},{0,0} };
|
||||
static float tex_coords1[2][2]={ {1,0},{1,0} };
|
||||
static float tex_coords2[2][2]={ {1,1},{1,1} };
|
||||
static float tex_coords3[2][2]={ {0,1},{0,1} };
|
||||
static float tex_coords0[2][2] = {{0, 0}, {0, 0}};
|
||||
static float tex_coords1[2][2] = {{1, 0}, {1, 0}};
|
||||
static float tex_coords2[2][2] = {{1, 1}, {1, 1}};
|
||||
static float tex_coords3[2][2] = {{0, 1}, {0, 1}};
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxRuntime* gx_runtime;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
static gxMesh *mesh;
|
||||
static gxMesh* mesh;
|
||||
static int mesh_size;
|
||||
static vector<int> mesh_indices;
|
||||
|
||||
static int allocIndex(){
|
||||
if( !mesh_indices.size() ){
|
||||
if( mesh_size ) gx_graphics->freeMesh( mesh );
|
||||
for( int k=0;k<256;++k ){
|
||||
mesh_indices.push_back( mesh_size++ );
|
||||
static int allocIndex()
|
||||
{
|
||||
if (!mesh_indices.size()) {
|
||||
if (mesh_size)
|
||||
gx_graphics->freeMesh(mesh);
|
||||
for (int k = 0; k < 256; ++k) {
|
||||
mesh_indices.push_back(mesh_size++);
|
||||
}
|
||||
mesh=gx_graphics->createMesh( mesh_size*4,mesh_size*2,0 );
|
||||
mesh = gx_graphics->createMesh(mesh_size * 4, mesh_size * 2, 0);
|
||||
}
|
||||
int n=mesh_indices.back();
|
||||
int n = mesh_indices.back();
|
||||
mesh_indices.pop_back();
|
||||
return n;
|
||||
}
|
||||
|
||||
static void freeIndex( int n ){
|
||||
mesh_indices.push_back( n );
|
||||
if( mesh_indices.size()!=mesh_size ) return;
|
||||
gx_graphics->freeMesh( mesh );
|
||||
static void freeIndex(int n)
|
||||
{
|
||||
mesh_indices.push_back(n);
|
||||
if (mesh_indices.size() != mesh_size)
|
||||
return;
|
||||
gx_graphics->freeMesh(mesh);
|
||||
mesh_indices.clear();
|
||||
mesh_size=0;
|
||||
mesh_size = 0;
|
||||
}
|
||||
|
||||
Sprite::Sprite():
|
||||
view_mode(VIEW_MODE_FREE),
|
||||
xhandle(0),yhandle(0),
|
||||
rot(0),xscale(1),yscale(1),captured(false){
|
||||
setRenderSpace( RENDER_SPACE_WORLD );
|
||||
mesh_index=allocIndex();
|
||||
Sprite::Sprite() : view_mode(VIEW_MODE_FREE), xhandle(0), yhandle(0), rot(0), xscale(1), yscale(1), captured(false)
|
||||
{
|
||||
setRenderSpace(RENDER_SPACE_WORLD);
|
||||
mesh_index = allocIndex();
|
||||
}
|
||||
|
||||
Sprite::Sprite( const Sprite &t ):
|
||||
Model(t),
|
||||
view_mode(t.view_mode),
|
||||
xhandle(t.xhandle),yhandle(t.yhandle),
|
||||
rot(t.rot),xscale(t.xscale),yscale(t.yscale),captured(false){
|
||||
mesh_index=allocIndex();
|
||||
Sprite::Sprite(const Sprite& t)
|
||||
: Model(t), view_mode(t.view_mode), xhandle(t.xhandle), yhandle(t.yhandle), rot(t.rot), xscale(t.xscale),
|
||||
yscale(t.yscale), captured(false)
|
||||
{
|
||||
mesh_index = allocIndex();
|
||||
}
|
||||
|
||||
Sprite::~Sprite(){
|
||||
freeIndex( mesh_index );
|
||||
Sprite::~Sprite()
|
||||
{
|
||||
freeIndex(mesh_index);
|
||||
}
|
||||
|
||||
void Sprite::setRotation( float angle ){
|
||||
rot=angle;
|
||||
void Sprite::setRotation(float angle)
|
||||
{
|
||||
rot = angle;
|
||||
}
|
||||
|
||||
void Sprite::setScale( float x,float y ){
|
||||
xscale=x;yscale=y;
|
||||
void Sprite::setScale(float x, float y)
|
||||
{
|
||||
xscale = x;
|
||||
yscale = y;
|
||||
}
|
||||
|
||||
void Sprite::setHandle( float x,float y ){
|
||||
xhandle=x;yhandle=y;
|
||||
void Sprite::setHandle(float x, float y)
|
||||
{
|
||||
xhandle = x;
|
||||
yhandle = y;
|
||||
}
|
||||
|
||||
void Sprite::setViewmode( int mode ){
|
||||
view_mode=mode;
|
||||
void Sprite::setViewmode(int mode)
|
||||
{
|
||||
view_mode = mode;
|
||||
}
|
||||
|
||||
void Sprite::capture(){
|
||||
void Sprite::capture()
|
||||
{
|
||||
Model::capture();
|
||||
r_rot=rot;
|
||||
r_xscale=xscale;
|
||||
r_yscale=yscale;
|
||||
captured=true;
|
||||
r_rot = rot;
|
||||
r_xscale = xscale;
|
||||
r_yscale = yscale;
|
||||
captured = true;
|
||||
}
|
||||
|
||||
bool Sprite::beginRender( float tween ){
|
||||
Model::beginRender( tween );
|
||||
if( tween==1 || !captured ){
|
||||
r_rot=rot;
|
||||
r_xscale=xscale;
|
||||
r_yscale=yscale;
|
||||
}else{
|
||||
r_rot=(rot-r_rot)*tween+r_rot;
|
||||
r_xscale=(xscale-r_xscale)*tween+r_xscale;
|
||||
r_yscale=(yscale-r_yscale)*tween+r_yscale;
|
||||
bool Sprite::beginRender(float tween)
|
||||
{
|
||||
Model::beginRender(tween);
|
||||
if (tween == 1 || !captured) {
|
||||
r_rot = rot;
|
||||
r_xscale = xscale;
|
||||
r_yscale = yscale;
|
||||
} else {
|
||||
r_rot = (rot - r_rot) * tween + r_rot;
|
||||
r_xscale = (xscale - r_xscale) * tween + r_xscale;
|
||||
r_yscale = (yscale - r_yscale) * tween + r_yscale;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sprite::render( const RenderContext &rc ){
|
||||
bool Sprite::render(const RenderContext& rc)
|
||||
{
|
||||
Transform t = getRenderTform();
|
||||
|
||||
Transform t=getRenderTform();
|
||||
|
||||
if( view_mode==VIEW_MODE_FREE ){
|
||||
t.m=rc.getCameraTform().m;
|
||||
}else if( view_mode==VIEW_MODE_UPRIGHT ){
|
||||
t.m.k=rc.getCameraTform().m.k;t.m.orthogonalize();
|
||||
}else if( view_mode==VIEW_MODE_UPRIGHT2 ){
|
||||
t.m=yawMatrix( matrixYaw( rc.getCameraTform().m ) ) * t.m;
|
||||
if (view_mode == VIEW_MODE_FREE) {
|
||||
t.m = rc.getCameraTform().m;
|
||||
} else if (view_mode == VIEW_MODE_UPRIGHT) {
|
||||
t.m.k = rc.getCameraTform().m.k;
|
||||
t.m.orthogonalize();
|
||||
} else if (view_mode == VIEW_MODE_UPRIGHT2) {
|
||||
t.m = yawMatrix(matrixYaw(rc.getCameraTform().m)) * t.m;
|
||||
}
|
||||
|
||||
t.m=t.m * rollMatrix( r_rot ) * scaleMatrix( r_xscale,r_yscale,1 );
|
||||
t.m = t.m * rollMatrix(r_rot) * scaleMatrix(r_xscale, r_yscale, 1);
|
||||
|
||||
static Vector verts[4];
|
||||
verts[0]=t * Vector( -1-xhandle, 1-yhandle,0 );
|
||||
verts[1]=t * Vector( 1-xhandle, 1-yhandle,0 );
|
||||
verts[2]=t * Vector( 1-xhandle,-1-yhandle,0 );
|
||||
verts[3]=t * Vector( -1-xhandle,-1-yhandle,0 );
|
||||
verts[0] = t * Vector(-1 - xhandle, 1 - yhandle, 0);
|
||||
verts[1] = t * Vector(1 - xhandle, 1 - yhandle, 0);
|
||||
verts[2] = t * Vector(1 - xhandle, -1 - yhandle, 0);
|
||||
verts[3] = t * Vector(-1 - xhandle, -1 - yhandle, 0);
|
||||
|
||||
if( !rc.getWorldFrustum().cull( verts,4 ) ) return false;
|
||||
if (!rc.getWorldFrustum().cull(verts, 4))
|
||||
return false;
|
||||
|
||||
mesh->lock( false );
|
||||
int fv=mesh_index*4,ft=mesh_index*2;
|
||||
mesh->setVertex( fv+0,&verts[0].x,null,tex_coords0 );
|
||||
mesh->setVertex( fv+1,&verts[1].x,null,tex_coords1 );
|
||||
mesh->setVertex( fv+2,&verts[2].x,null,tex_coords2 );
|
||||
mesh->setVertex( fv+3,&verts[3].x,null,tex_coords3 );
|
||||
if( rc.isReflected() ){
|
||||
mesh->setTriangle( ft+0,0,2,1 );
|
||||
mesh->setTriangle( ft+1,0,3,2 );
|
||||
}else{
|
||||
mesh->setTriangle( ft+0,0,1,2 );
|
||||
mesh->setTriangle( ft+1,0,2,3 );
|
||||
mesh->lock(false);
|
||||
int fv = mesh_index * 4, ft = mesh_index * 2;
|
||||
mesh->setVertex(fv + 0, &verts[0].x, null, tex_coords0);
|
||||
mesh->setVertex(fv + 1, &verts[1].x, null, tex_coords1);
|
||||
mesh->setVertex(fv + 2, &verts[2].x, null, tex_coords2);
|
||||
mesh->setVertex(fv + 3, &verts[3].x, null, tex_coords3);
|
||||
if (rc.isReflected()) {
|
||||
mesh->setTriangle(ft + 0, 0, 2, 1);
|
||||
mesh->setTriangle(ft + 1, 0, 3, 2);
|
||||
} else {
|
||||
mesh->setTriangle(ft + 0, 0, 1, 2);
|
||||
mesh->setTriangle(ft + 1, 0, 2, 3);
|
||||
}
|
||||
mesh->unlock();
|
||||
|
||||
enqueue( mesh,fv,4,ft,2 );
|
||||
enqueue(mesh, fv, 4, ft, 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
+29
-23
@@ -2,42 +2,48 @@
|
||||
#ifndef SPRITE_H
|
||||
#define SPRITE_H
|
||||
|
||||
#include "model.hpp"
|
||||
#include "brush.hpp"
|
||||
#include "../gxruntime/gxmesh.hpp"
|
||||
#include "gxmesh.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
class Sprite : public Model{
|
||||
public:
|
||||
enum{
|
||||
VIEW_MODE_FREE=1, //visible from any angle
|
||||
VIEW_MODE_FIXED=2, //visible only from front
|
||||
VIEW_MODE_UPRIGHT=3, //upright tree-style
|
||||
VIEW_MODE_UPRIGHT2=4 //better upright tree-style
|
||||
class Sprite : public Model {
|
||||
public:
|
||||
enum {
|
||||
VIEW_MODE_FREE = 1, //visible from any angle
|
||||
VIEW_MODE_FIXED = 2, //visible only from front
|
||||
VIEW_MODE_UPRIGHT = 3, //upright tree-style
|
||||
VIEW_MODE_UPRIGHT2 = 4 //better upright tree-style
|
||||
};
|
||||
|
||||
Sprite();
|
||||
Sprite( const Sprite &t );
|
||||
Sprite(const Sprite& t);
|
||||
~Sprite();
|
||||
|
||||
Sprite *getSprite(){ return this; }
|
||||
Sprite* getSprite()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
Entity *clone(){ return new Sprite( *this ); }
|
||||
Entity* clone()
|
||||
{
|
||||
return new Sprite(*this);
|
||||
}
|
||||
|
||||
void capture();
|
||||
bool beginRender( float tween );
|
||||
bool beginRender(float tween);
|
||||
|
||||
void setRotation( float angle );
|
||||
void setScale( float x_scale,float y_scale );
|
||||
void setHandle( float x,float y );
|
||||
void setViewmode( int mode );
|
||||
void setRotation(float angle);
|
||||
void setScale(float x_scale, float y_scale);
|
||||
void setHandle(float x, float y);
|
||||
void setViewmode(int mode);
|
||||
|
||||
bool render( const RenderContext &rc );
|
||||
bool render(const RenderContext& rc);
|
||||
|
||||
private:
|
||||
float xhandle,yhandle;
|
||||
float rot,xscale,yscale;
|
||||
float r_rot,r_xscale,r_yscale;
|
||||
int view_mode,mesh_index;
|
||||
private:
|
||||
float xhandle, yhandle;
|
||||
float rot, xscale, yscale;
|
||||
float r_rot, r_xscale, r_yscale;
|
||||
int view_mode, mesh_index;
|
||||
bool captured;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
#ifndef STD_H
|
||||
#define STD_H
|
||||
|
||||
#pragma warning( disable:4786 )
|
||||
#pragma warning(disable : 4786)
|
||||
|
||||
#include "config.hpp"
|
||||
#include "stdutil.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
#include "stdutil.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
+129
-99
@@ -1,155 +1,186 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "surface.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
static Surface::Monitor nop_mon;
|
||||
|
||||
Surface::Surface():
|
||||
mesh(0),mesh_vs(0),mesh_ts(0),valid_vs(0),valid_ts(0),mon( &nop_mon ){
|
||||
Surface::Surface() : mesh(0), mesh_vs(0), mesh_ts(0), valid_vs(0), valid_ts(0), mon(&nop_mon) {}
|
||||
|
||||
Surface::Surface(Monitor* m) : mesh(0), mesh_vs(0), mesh_ts(0), valid_vs(0), valid_ts(0), mon(m) {}
|
||||
|
||||
Surface::~Surface()
|
||||
{
|
||||
if (mesh)
|
||||
gx_graphics->freeMesh(mesh);
|
||||
}
|
||||
|
||||
Surface::Surface( Monitor *m ):
|
||||
mesh(0),mesh_vs(0),mesh_ts(0),valid_vs(0),valid_ts(0),mon(m){
|
||||
}
|
||||
|
||||
Surface::~Surface(){
|
||||
if( mesh ) gx_graphics->freeMesh( mesh );
|
||||
}
|
||||
|
||||
void Surface::setBrush( const Brush &b ){
|
||||
brush=b;
|
||||
void Surface::setBrush(const Brush& b)
|
||||
{
|
||||
brush = b;
|
||||
++mon->brush_changes;
|
||||
}
|
||||
|
||||
void Surface::setName( const string &n ){
|
||||
name=n;
|
||||
void Surface::setName(const string& n)
|
||||
{
|
||||
name = n;
|
||||
}
|
||||
|
||||
void Surface::clear( bool verts,bool tris ){
|
||||
if( verts ){ vertices.clear();valid_vs=0; }
|
||||
if( tris ){ triangles.clear();valid_ts=0; }
|
||||
void Surface::clear(bool verts, bool tris)
|
||||
{
|
||||
if (verts) {
|
||||
vertices.clear();
|
||||
valid_vs = 0;
|
||||
}
|
||||
if (tris) {
|
||||
triangles.clear();
|
||||
valid_ts = 0;
|
||||
}
|
||||
++mon->geom_changes;
|
||||
}
|
||||
|
||||
void Surface::addVertices( const vector<Vertex> &verts ){
|
||||
vertices.insert( vertices.end(),verts.begin(),verts.end() );
|
||||
void Surface::addVertices(const vector<Vertex>& verts)
|
||||
{
|
||||
vertices.insert(vertices.end(), verts.begin(), verts.end());
|
||||
++mon->geom_changes;
|
||||
}
|
||||
|
||||
void Surface::setColor( int n,const Vector &v ){
|
||||
int r=floor(v.x*255);if(r<0)r=0;else if(r>255)r=255;
|
||||
int g=floor(v.y*255);if(g<0)g=0;else if(g>255)g=255;
|
||||
int b=floor(v.z*255);if(b<0)b=0;else if(b>255)b=255;
|
||||
void Surface::setColor(int n, const Vector& v)
|
||||
{
|
||||
int r = floor(v.x * 255);
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
else if (r > 255)
|
||||
r = 255;
|
||||
int g = floor(v.y * 255);
|
||||
if (g < 0)
|
||||
g = 0;
|
||||
else if (g > 255)
|
||||
g = 255;
|
||||
int b = floor(v.z * 255);
|
||||
if (b < 0)
|
||||
b = 0;
|
||||
else if (b > 255)
|
||||
b = 255;
|
||||
|
||||
unsigned argb=0xff000000|(r<<16)|(g<<8)|b;
|
||||
unsigned argb = 0xff000000 | (r << 16) | (g << 8) | b;
|
||||
|
||||
vertices[n].color=argb;
|
||||
if( n<valid_vs ) valid_vs=n;
|
||||
vertices[n].color = argb;
|
||||
if (n < valid_vs)
|
||||
valid_vs = n;
|
||||
}
|
||||
|
||||
Vector Surface::getColor( int n )const{
|
||||
float r=(vertices[n].color&0x00ff0000)>>16;
|
||||
float g=(vertices[n].color&0x0000ff00)>>8;
|
||||
float b= vertices[n].color&0x000000ff;
|
||||
return Vector( r/255.0f,g/255.0f,b/255.0f );
|
||||
Vector Surface::getColor(int n) const
|
||||
{
|
||||
float r = (vertices[n].color & 0x00ff0000) >> 16;
|
||||
float g = (vertices[n].color & 0x0000ff00) >> 8;
|
||||
float b = vertices[n].color & 0x000000ff;
|
||||
return Vector(r / 255.0f, g / 255.0f, b / 255.0f);
|
||||
}
|
||||
|
||||
void Surface::addTriangles( const vector<Triangle> &tris ){
|
||||
triangles.insert( triangles.end(),tris.begin(),tris.end() );
|
||||
void Surface::addTriangles(const vector<Triangle>& tris)
|
||||
{
|
||||
triangles.insert(triangles.end(), tris.begin(), tris.end());
|
||||
}
|
||||
|
||||
void Surface::updateNormals(){
|
||||
void Surface::updateNormals()
|
||||
{
|
||||
int k;
|
||||
map<Vector,Vector> norm_map;
|
||||
for( k=0;k<triangles.size();++k ){
|
||||
const Triangle &t=triangles[k];
|
||||
const Vector &v0=vertices[t.verts[0]].coords;
|
||||
const Vector &v1=vertices[t.verts[1]].coords;
|
||||
const Vector &v2=vertices[t.verts[2]].coords;
|
||||
Vector n=(v1-v0).cross(v2-v0);
|
||||
if( n.length()<= FLT_EPSILON ) continue;
|
||||
map<Vector, Vector> norm_map;
|
||||
for (k = 0; k < triangles.size(); ++k) {
|
||||
const Triangle& t = triangles[k];
|
||||
const Vector& v0 = vertices[t.verts[0]].coords;
|
||||
const Vector& v1 = vertices[t.verts[1]].coords;
|
||||
const Vector& v2 = vertices[t.verts[2]].coords;
|
||||
Vector n = (v1 - v0).cross(v2 - v0);
|
||||
if (n.length() <= FLT_EPSILON)
|
||||
continue;
|
||||
n.normalize();
|
||||
norm_map[v0]+=n;
|
||||
norm_map[v1]+=n;
|
||||
norm_map[v2]+=n;
|
||||
norm_map[v0] += n;
|
||||
norm_map[v1] += n;
|
||||
norm_map[v2] += n;
|
||||
}
|
||||
for( k=0;k<vertices.size();++k ){
|
||||
Vertex *v=&vertices[k];
|
||||
v->normal=norm_map[v->coords].normalized();
|
||||
for (k = 0; k < vertices.size(); ++k) {
|
||||
Vertex* v = &vertices[k];
|
||||
v->normal = norm_map[v->coords].normalized();
|
||||
}
|
||||
}
|
||||
|
||||
gxMesh *Surface::getMesh(){
|
||||
if( mesh && mesh->dirty() ) valid_vs=0;
|
||||
gxMesh* Surface::getMesh()
|
||||
{
|
||||
if (mesh && mesh->dirty())
|
||||
valid_vs = 0;
|
||||
|
||||
if( valid_vs==vertices.size() && valid_ts==triangles.size() ) return mesh;
|
||||
if (valid_vs == vertices.size() && valid_ts == triangles.size())
|
||||
return mesh;
|
||||
|
||||
valid_vs=valid_ts=0;
|
||||
valid_vs = valid_ts = 0;
|
||||
|
||||
if( mesh_vs<vertices.size() || mesh_ts<triangles.size() ){
|
||||
if( mesh ){
|
||||
gx_graphics->freeMesh( mesh );
|
||||
mesh_vs=vertices.size()+mesh_vs/2;
|
||||
mesh_ts=triangles.size()+mesh_ts/2;
|
||||
}else{
|
||||
mesh_vs=vertices.size();
|
||||
mesh_ts=triangles.size();
|
||||
if (mesh_vs < vertices.size() || mesh_ts < triangles.size()) {
|
||||
if (mesh) {
|
||||
gx_graphics->freeMesh(mesh);
|
||||
mesh_vs = vertices.size() + mesh_vs / 2;
|
||||
mesh_ts = triangles.size() + mesh_ts / 2;
|
||||
} else {
|
||||
mesh_vs = vertices.size();
|
||||
mesh_ts = triangles.size();
|
||||
}
|
||||
mesh=gx_graphics->createMesh( mesh_vs,mesh_ts,0 );
|
||||
mesh = gx_graphics->createMesh(mesh_vs, mesh_ts, 0);
|
||||
}
|
||||
|
||||
mesh->lock( true );
|
||||
for( ;valid_vs<vertices.size();++valid_vs ){
|
||||
mesh->setVertex( valid_vs,&vertices[valid_vs] );
|
||||
mesh->lock(true);
|
||||
for (; valid_vs < vertices.size(); ++valid_vs) {
|
||||
mesh->setVertex(valid_vs, &vertices[valid_vs]);
|
||||
}
|
||||
for( ;valid_ts<triangles.size();++valid_ts ){
|
||||
const Triangle &t=triangles[valid_ts];
|
||||
mesh->setTriangle( valid_ts,t.verts[0],t.verts[1],t.verts[2] );
|
||||
for (; valid_ts < triangles.size(); ++valid_ts) {
|
||||
const Triangle& t = triangles[valid_ts];
|
||||
mesh->setTriangle(valid_ts, t.verts[0], t.verts[1], t.verts[2]);
|
||||
}
|
||||
mesh->unlock();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
gxMesh *Surface::getMesh( const vector<Bone> &bones ){
|
||||
gxMesh* Surface::getMesh(const vector<Bone>& bones)
|
||||
{
|
||||
valid_vs = valid_ts = 0;
|
||||
|
||||
valid_vs=valid_ts=0;
|
||||
|
||||
if( mesh_vs<vertices.size() || mesh_ts<triangles.size() ){
|
||||
if( mesh ) gx_graphics->freeMesh( mesh );
|
||||
mesh_vs=vertices.size();
|
||||
mesh_ts=triangles.size();
|
||||
mesh=gx_graphics->createMesh( mesh_vs,mesh_ts,0 );
|
||||
if (mesh_vs < vertices.size() || mesh_ts < triangles.size()) {
|
||||
if (mesh)
|
||||
gx_graphics->freeMesh(mesh);
|
||||
mesh_vs = vertices.size();
|
||||
mesh_ts = triangles.size();
|
||||
mesh = gx_graphics->createMesh(mesh_vs, mesh_ts, 0);
|
||||
}
|
||||
|
||||
mesh->lock( true );
|
||||
for( ;valid_vs<vertices.size();++valid_vs ){
|
||||
const Vertex &v=vertices[valid_vs];
|
||||
if( v.bone_bones[0]==255 ){
|
||||
mesh->lock(true);
|
||||
for (; valid_vs < vertices.size(); ++valid_vs) {
|
||||
const Vertex& v = vertices[valid_vs];
|
||||
if (v.bone_bones[0] == 255) {
|
||||
//no bone!
|
||||
const Bone &bone=bones[0];
|
||||
mesh->setVertex( valid_vs,bone.coord_tform * v.coords,bone.normal_tform * v.normal,v.color,v.tex_coords );
|
||||
}else if( v.bone_bones[1]==255 ){
|
||||
const Bone& bone = bones[0];
|
||||
mesh->setVertex(valid_vs, bone.coord_tform * v.coords, bone.normal_tform * v.normal, v.color, v.tex_coords);
|
||||
} else if (v.bone_bones[1] == 255) {
|
||||
//one bone only
|
||||
const Bone &bone=bones[v.bone_bones[0]];
|
||||
mesh->setVertex( valid_vs,bone.coord_tform * v.coords,bone.normal_tform * v.normal,v.color,v.tex_coords );
|
||||
}else{
|
||||
const Vertex &v=vertices[valid_vs];
|
||||
const Bone& bone = bones[v.bone_bones[0]];
|
||||
mesh->setVertex(valid_vs, bone.coord_tform * v.coords, bone.normal_tform * v.normal, v.color, v.tex_coords);
|
||||
} else {
|
||||
const Vertex& v = vertices[valid_vs];
|
||||
//two or more bones
|
||||
Vector tv,tn;
|
||||
for( int n=0;n<MAX_SURFACE_BONES;++n ){
|
||||
if( v.bone_bones[n]==255 ) break;
|
||||
const Bone &bone=bones[v.bone_bones[n]];
|
||||
tv+=bone.coord_tform * v.coords * v.bone_weights[n];
|
||||
tn+=bone.normal_tform * v.normal * v.bone_weights[n];
|
||||
Vector tv, tn;
|
||||
for (int n = 0; n < MAX_SURFACE_BONES; ++n) {
|
||||
if (v.bone_bones[n] == 255)
|
||||
break;
|
||||
const Bone& bone = bones[v.bone_bones[n]];
|
||||
tv += bone.coord_tform * v.coords * v.bone_weights[n];
|
||||
tn += bone.normal_tform * v.normal * v.bone_weights[n];
|
||||
}
|
||||
mesh->setVertex( valid_vs,tv,tn.normalized(),v.color,v.tex_coords );
|
||||
mesh->setVertex(valid_vs, tv, tn.normalized(), v.color, v.tex_coords);
|
||||
}
|
||||
}
|
||||
for( ;valid_ts<triangles.size();++valid_ts ){
|
||||
const Triangle &t=triangles[valid_ts];
|
||||
mesh->setTriangle( valid_ts,t.verts[0],t.verts[1],t.verts[2] );
|
||||
for (; valid_ts < triangles.size(); ++valid_ts) {
|
||||
const Triangle& t = triangles[valid_ts];
|
||||
mesh->setTriangle(valid_ts, t.verts[0], t.verts[1], t.verts[2]);
|
||||
}
|
||||
mesh->unlock();
|
||||
return mesh;
|
||||
@@ -235,4 +266,3 @@ gxMesh *Surface::getMesh( const vector<Bone> &bones,gxMesh *mesh ){
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
+88
-54
@@ -6,9 +6,9 @@
|
||||
|
||||
#define MAX_SURFACE_BONES 4
|
||||
|
||||
class Surface{
|
||||
public:
|
||||
struct Vertex{
|
||||
class Surface {
|
||||
public:
|
||||
struct Vertex {
|
||||
Vector coords;
|
||||
Vector normal;
|
||||
unsigned color;
|
||||
@@ -16,101 +16,135 @@ public:
|
||||
unsigned char bone_bones[MAX_SURFACE_BONES];
|
||||
float bone_weights[MAX_SURFACE_BONES];
|
||||
|
||||
Vertex():color(~0){
|
||||
bone_bones[0]=255;
|
||||
memset(tex_coords,0,sizeof(tex_coords));
|
||||
Vertex() : color(~0)
|
||||
{
|
||||
bone_bones[0] = 255;
|
||||
memset(tex_coords, 0, sizeof(tex_coords));
|
||||
}
|
||||
|
||||
bool operator<( const Vertex &t )const{
|
||||
return memcmp( this,&t,sizeof(*this) )==-1;
|
||||
bool operator<(const Vertex& t) const
|
||||
{
|
||||
return memcmp(this, &t, sizeof(*this)) == -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct Triangle{
|
||||
struct Triangle {
|
||||
unsigned short verts[3];
|
||||
};
|
||||
|
||||
struct Bone{
|
||||
struct Bone {
|
||||
Transform coord_tform;
|
||||
Matrix normal_tform;
|
||||
};
|
||||
|
||||
struct Monitor{
|
||||
int brush_changes,geom_changes;
|
||||
struct Monitor {
|
||||
int brush_changes, geom_changes;
|
||||
};
|
||||
|
||||
Surface();
|
||||
Surface( Monitor *mon );
|
||||
Surface(Monitor* mon);
|
||||
~Surface();
|
||||
|
||||
void setName( const string &t );
|
||||
void setBrush( const Brush &b );
|
||||
void setName(const string& t);
|
||||
void setBrush(const Brush& b);
|
||||
|
||||
void clear( bool verts,bool tris );
|
||||
void clear(bool verts, bool tris);
|
||||
|
||||
void addVertex( const Vertex &v ){
|
||||
void addVertex(const Vertex& v)
|
||||
{
|
||||
vertices.push_back(v);
|
||||
++mon->geom_changes;
|
||||
}
|
||||
void setVertex( int n,const Vertex &v ){
|
||||
vertices[n]=v;
|
||||
if( n<valid_vs ) valid_vs=n;
|
||||
void setVertex(int n, const Vertex& v)
|
||||
{
|
||||
vertices[n] = v;
|
||||
if (n < valid_vs)
|
||||
valid_vs = n;
|
||||
++mon->geom_changes;
|
||||
}
|
||||
void setCoords( int n,const Vector &v ){
|
||||
vertices[n].coords=v;
|
||||
if( n<valid_vs ) valid_vs=n;
|
||||
void setCoords(int n, const Vector& v)
|
||||
{
|
||||
vertices[n].coords = v;
|
||||
if (n < valid_vs)
|
||||
valid_vs = n;
|
||||
++mon->geom_changes;
|
||||
}
|
||||
void setNormal( int n,const Vector &v ){
|
||||
vertices[n].normal=v;
|
||||
if( n<valid_vs ) valid_vs=n;
|
||||
void setNormal(int n, const Vector& v)
|
||||
{
|
||||
vertices[n].normal = v;
|
||||
if (n < valid_vs)
|
||||
valid_vs = n;
|
||||
}
|
||||
void setColor( int n,unsigned argb ){
|
||||
vertices[n].color=argb;
|
||||
if( n<valid_vs ) valid_vs=n;
|
||||
void setColor(int n, unsigned argb)
|
||||
{
|
||||
vertices[n].color = argb;
|
||||
if (n < valid_vs)
|
||||
valid_vs = n;
|
||||
}
|
||||
void setTexCoords( int n,const Vector &v,int i ){
|
||||
vertices[n].tex_coords[i][0]=v.x;
|
||||
vertices[n].tex_coords[i][1]=v.y;
|
||||
if( n<valid_vs ) valid_vs=n;
|
||||
void setTexCoords(int n, const Vector& v, int i)
|
||||
{
|
||||
vertices[n].tex_coords[i][0] = v.x;
|
||||
vertices[n].tex_coords[i][1] = v.y;
|
||||
if (n < valid_vs)
|
||||
valid_vs = n;
|
||||
}
|
||||
void addTriangle( const Triangle &t ){
|
||||
void addTriangle(const Triangle& t)
|
||||
{
|
||||
triangles.push_back(t);
|
||||
++mon->geom_changes;
|
||||
}
|
||||
void setTriangle( int n,const Triangle &t ){
|
||||
triangles[n]=t;
|
||||
if( n<valid_ts ) valid_ts=n;
|
||||
void setTriangle(int n, const Triangle& t)
|
||||
{
|
||||
triangles[n] = t;
|
||||
if (n < valid_ts)
|
||||
valid_ts = n;
|
||||
++mon->geom_changes;
|
||||
}
|
||||
|
||||
Vector getColor( int index )const;
|
||||
void setColor( int index,const Vector &v );
|
||||
void addVertices( const vector<Vertex> &verts );
|
||||
void addTriangles( const vector<Triangle> &tris );
|
||||
Vector getColor(int index) const;
|
||||
void setColor(int index, const Vector& v);
|
||||
void addVertices(const vector<Vertex>& verts);
|
||||
void addTriangles(const vector<Triangle>& tris);
|
||||
|
||||
void updateNormals();
|
||||
|
||||
gxMesh *getMesh();
|
||||
gxMesh *getMesh( const vector<Bone> &bones );
|
||||
gxMesh* getMesh();
|
||||
gxMesh* getMesh(const vector<Bone>& bones);
|
||||
|
||||
string getName()const{ return name; }
|
||||
const Brush &getBrush()const{ return brush; }
|
||||
int numVertices()const{ return vertices.size(); }
|
||||
int numTriangles()const{ return triangles.size(); }
|
||||
const Vertex &getVertex( int n )const{ return vertices[n]; }
|
||||
const Triangle &getTriangle( int n )const{ return triangles[n]; }
|
||||
string getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
const Brush& getBrush() const
|
||||
{
|
||||
return brush;
|
||||
}
|
||||
int numVertices() const
|
||||
{
|
||||
return vertices.size();
|
||||
}
|
||||
int numTriangles() const
|
||||
{
|
||||
return triangles.size();
|
||||
}
|
||||
const Vertex& getVertex(int n) const
|
||||
{
|
||||
return vertices[n];
|
||||
}
|
||||
const Triangle& getTriangle(int n) const
|
||||
{
|
||||
return triangles[n];
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
Brush brush;
|
||||
string name;
|
||||
gxMesh *mesh;
|
||||
gxMesh* mesh;
|
||||
vector<Vertex> vertices;
|
||||
vector<Triangle> triangles;
|
||||
int mesh_vs,mesh_ts;
|
||||
int valid_vs,valid_ts;
|
||||
Monitor *mon;
|
||||
int mesh_vs, mesh_ts;
|
||||
int valid_vs, valid_ts;
|
||||
Monitor* mon;
|
||||
};
|
||||
|
||||
#endif
|
||||
+25
-18
@@ -1,41 +1,48 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "terrain.hpp"
|
||||
#include "std.hpp"
|
||||
#include "terrainrep.hpp"
|
||||
|
||||
Terrain::Terrain( int size_shift ):
|
||||
rep( new TerrainRep( size_shift ) ){
|
||||
}
|
||||
Terrain::Terrain(int size_shift) : rep(new TerrainRep(size_shift)) {}
|
||||
|
||||
Terrain::~Terrain(){
|
||||
Terrain::~Terrain()
|
||||
{
|
||||
delete rep;
|
||||
}
|
||||
|
||||
void Terrain::setDetail( int n,bool m ){
|
||||
rep->setDetail( n,m );
|
||||
void Terrain::setDetail(int n, bool m)
|
||||
{
|
||||
rep->setDetail(n, m);
|
||||
}
|
||||
|
||||
void Terrain::setShading( bool t ){
|
||||
rep->setShading( t );
|
||||
void Terrain::setShading(bool t)
|
||||
{
|
||||
rep->setShading(t);
|
||||
}
|
||||
|
||||
void Terrain::setHeight( int x,int z,float h,bool realtime ){
|
||||
if( x>=0 && z>=0 && x<=rep->getSize() && z<=rep->getSize() ) rep->setHeight( x,z,h,realtime );
|
||||
void Terrain::setHeight(int x, int z, float h, bool realtime)
|
||||
{
|
||||
if (x >= 0 && z >= 0 && x <= rep->getSize() && z <= rep->getSize())
|
||||
rep->setHeight(x, z, h, realtime);
|
||||
}
|
||||
|
||||
int Terrain::getSize()const{
|
||||
int Terrain::getSize() const
|
||||
{
|
||||
return rep->getSize();
|
||||
}
|
||||
|
||||
float Terrain::getHeight( int x,int z )const{
|
||||
return (x>=0 && z>=0 && x<=rep->getSize() && z<=rep->getSize() ) ? rep->getHeight( x,z ) : 0;
|
||||
float Terrain::getHeight(int x, int z) const
|
||||
{
|
||||
return (x >= 0 && z >= 0 && x <= rep->getSize() && z <= rep->getSize()) ? rep->getHeight(x, z) : 0;
|
||||
}
|
||||
|
||||
bool Terrain::render( const RenderContext &rc ){
|
||||
rep->render( this,rc );
|
||||
bool Terrain::render(const RenderContext& rc)
|
||||
{
|
||||
rep->render(this, rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Terrain::collide( const Line &line,float radius,Collision *curr_coll,const Transform &tf ){
|
||||
return rep->collide( line,radius,curr_coll,tf );
|
||||
bool Terrain::collide(const Line& line, float radius, Collision* curr_coll, const Transform& tf)
|
||||
{
|
||||
return rep->collide(line, radius, curr_coll, tf);
|
||||
}
|
||||
|
||||
+16
-13
@@ -6,28 +6,31 @@
|
||||
|
||||
struct TerrainRep;
|
||||
|
||||
class Terrain : public Model{
|
||||
public:
|
||||
Terrain( int size_shift );
|
||||
class Terrain : public Model {
|
||||
public:
|
||||
Terrain(int size_shift);
|
||||
~Terrain();
|
||||
|
||||
Terrain *getTerrain(){ return this; }
|
||||
Terrain* getTerrain()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void setDetail( int n,bool morph );
|
||||
void setHeight( int x,int z,float h,bool realtime );
|
||||
void setShading( bool shading );
|
||||
void setDetail(int n, bool morph);
|
||||
void setHeight(int x, int z, float h, bool realtime);
|
||||
void setShading(bool shading);
|
||||
|
||||
int getSize()const;
|
||||
float getHeight( int x,int z )const;
|
||||
int getSize() const;
|
||||
float getHeight(int x, int z) const;
|
||||
|
||||
//model interface
|
||||
bool render( const RenderContext &rc );
|
||||
bool render(const RenderContext& rc);
|
||||
|
||||
//object interface
|
||||
bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &tf );
|
||||
bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& tf);
|
||||
|
||||
private:
|
||||
TerrainRep *rep;
|
||||
private:
|
||||
TerrainRep* rep;
|
||||
};
|
||||
|
||||
#endif
|
||||
+453
-382
File diff suppressed because it is too large
Load Diff
@@ -6,50 +6,52 @@
|
||||
|
||||
#include "model.hpp"
|
||||
|
||||
struct TerrainRep{
|
||||
public:
|
||||
TerrainRep( int cell_shift );
|
||||
struct TerrainRep {
|
||||
public:
|
||||
TerrainRep(int cell_shift);
|
||||
~TerrainRep();
|
||||
|
||||
void clear();
|
||||
void setShading( bool shading );
|
||||
void setDetail( int n,bool morph );
|
||||
void setHeight( int x,int z,float h,bool realtime );
|
||||
void setTile( int x,int z,const Brush &brush );
|
||||
void render( Model *model,const RenderContext &rc );
|
||||
void setShading(bool shading);
|
||||
void setDetail(int n, bool morph);
|
||||
void setHeight(int x, int z, float h, bool realtime);
|
||||
void setTile(int x, int z, const Brush& brush);
|
||||
void render(Model* model, const RenderContext& rc);
|
||||
|
||||
int getSize()const;
|
||||
float getHeight( int x,int z )const;
|
||||
bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &tform )const;
|
||||
int getSize() const;
|
||||
float getHeight(int x, int z) const;
|
||||
bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& tform) const;
|
||||
|
||||
struct Tri;
|
||||
struct Vert;
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Cell;
|
||||
struct Error;
|
||||
|
||||
friend struct Tri;
|
||||
friend struct Vert;
|
||||
|
||||
Cell *cells;
|
||||
Error *errors;
|
||||
gxMesh *mesh;
|
||||
Cell* cells;
|
||||
Error* errors;
|
||||
gxMesh* mesh;
|
||||
|
||||
int cell_size,cell_shift,cell_mask;
|
||||
int end_tri_id,detail,mesh_verts,mesh_tris;
|
||||
bool morph,shading;
|
||||
int cell_size, cell_shift, cell_mask;
|
||||
int end_tri_id, detail, mesh_verts, mesh_tris;
|
||||
bool morph, shading;
|
||||
mutable bool errs_valid;
|
||||
|
||||
void insert( Tri *t );
|
||||
void split( Tri *t );
|
||||
void insert(Tri* t);
|
||||
void split(Tri* t);
|
||||
|
||||
void validateErrs()const;
|
||||
Vector getNormal( int x,int z )const;
|
||||
Error calcErr( int id,const Vert &v0,const Vert &v1,const Vert &v2 )const;
|
||||
Error calcErr( int id,int x,int z,const Vert &v0,const Vert &v1,const Vert &v2 )const;
|
||||
bool collide( const Line &line,Collision *curr_coll,const Transform &tform,int id,const Vert &v0,const Vert &v1,const Vert &v2,const Line &l )const;
|
||||
bool collide( const Line &line,float radius,Collision *curr_coll,const Transform &tform,int id,const Vert &v0,const Vert &v1,const Vert &v2,const Box &box )const;
|
||||
void validateErrs() const;
|
||||
Vector getNormal(int x, int z) const;
|
||||
Error calcErr(int id, const Vert& v0, const Vert& v1, const Vert& v2) const;
|
||||
Error calcErr(int id, int x, int z, const Vert& v0, const Vert& v1, const Vert& v2) const;
|
||||
bool collide(const Line& line, Collision* curr_coll, const Transform& tform, int id, const Vert& v0, const Vert& v1,
|
||||
const Vert& v2, const Line& l) const;
|
||||
bool collide(const Line& line, float radius, Collision* curr_coll, const Transform& tform, int id, const Vert& v0,
|
||||
const Vert& v1, const Vert& v2, const Box& box) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
+99
-72
@@ -1,24 +1,24 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "geom.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "cachedtexture.hpp"
|
||||
#include "geom.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
#include "../gxruntime/gxgraphics.hpp"
|
||||
|
||||
extern gxScene *gx_scene;
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxScene* gx_scene;
|
||||
extern gxGraphics* gx_graphics;
|
||||
|
||||
struct Filter {
|
||||
string t;
|
||||
int flags;
|
||||
Filter(const string &t, int flags) :t(t), flags(flags) {
|
||||
}
|
||||
Filter(const string& t, int flags) : t(t), flags(flags) {}
|
||||
};
|
||||
|
||||
static vector<Filter> filters;
|
||||
|
||||
static int filterFile(const string &t, int flags) {
|
||||
static int filterFile(const string& t, int flags)
|
||||
{
|
||||
//check filters...
|
||||
string l = tolower(t);
|
||||
for (size_t k = 0; k < filters.size(); ++k) {
|
||||
@@ -30,7 +30,6 @@ static int filterFile(const string &t, int flags) {
|
||||
}
|
||||
|
||||
struct Texture::Rep {
|
||||
|
||||
int ref_cnt;
|
||||
CachedTextureFactory cached_tex;
|
||||
vector<gxCanvas*> tex_frames;
|
||||
@@ -42,138 +41,162 @@ struct Texture::Rep {
|
||||
bool mat_used, mat_valid;
|
||||
gxScene::Matrix matrix;
|
||||
|
||||
Rep(int w, int h, int flags, int cnt) :
|
||||
ref_cnt(1), cached_tex(w, h, flags, cnt),
|
||||
tex_blend(gxScene::BLEND_MULTIPLY), tex_flags(0),
|
||||
sx(1), sy(1), tx(0), ty(0), rot(0), mat_used(false) {
|
||||
Rep(int w, int h, int flags, int cnt)
|
||||
: ref_cnt(1), cached_tex(w, h, flags, cnt), tex_blend(gxScene::BLEND_MULTIPLY), tex_flags(0), sx(1), sy(1),
|
||||
tx(0), ty(0), rot(0), mat_used(false)
|
||||
{
|
||||
tex_frames = cached_tex.getFrames();
|
||||
transparent =
|
||||
(flags & gxCanvas::CANVAS_TEX_ALPHA) &&
|
||||
!(flags & gxCanvas::CANVAS_TEX_MASK);
|
||||
transparent = (flags & gxCanvas::CANVAS_TEX_ALPHA) && !(flags & gxCanvas::CANVAS_TEX_MASK);
|
||||
memset(&matrix, 0, sizeof(matrix));
|
||||
}
|
||||
|
||||
Rep(const string &f, int flags, int w, int h, int first, int cnt) :
|
||||
ref_cnt(1), cached_tex(f, flags, w, h, first, cnt),
|
||||
tex_blend(gxScene::BLEND_MULTIPLY), tex_flags(0),
|
||||
sx(1), sy(1), tx(0), ty(0), rot(0), mat_used(false) {
|
||||
Rep(const string& f, int flags, int w, int h, int first, int cnt)
|
||||
: ref_cnt(1), cached_tex(f, flags, w, h, first, cnt), tex_blend(gxScene::BLEND_MULTIPLY), tex_flags(0), sx(1),
|
||||
sy(1), tx(0), ty(0), rot(0), mat_used(false)
|
||||
{
|
||||
tex_frames = cached_tex.getFrames();
|
||||
transparent =
|
||||
(flags & gxCanvas::CANVAS_TEX_ALPHA) &&
|
||||
!(flags & gxCanvas::CANVAS_TEX_MASK);
|
||||
transparent = (flags & gxCanvas::CANVAS_TEX_ALPHA) && !(flags & gxCanvas::CANVAS_TEX_MASK);
|
||||
memset(&matrix, 0, sizeof(matrix));
|
||||
}
|
||||
|
||||
Rep(const Rep &t) :
|
||||
ref_cnt(1), cached_tex(t.cached_tex), tex_frames(t.tex_frames),
|
||||
tex_blend(t.tex_blend), tex_flags(t.tex_flags),
|
||||
sx(t.sx), sy(t.sy), tx(t.tx), ty(t.ty), rot(t.rot),
|
||||
mat_used(t.mat_used), mat_valid(t.mat_valid), matrix(t.matrix),
|
||||
transparent(t.transparent) {
|
||||
}
|
||||
Rep(const Rep& t)
|
||||
: ref_cnt(1), cached_tex(t.cached_tex), tex_frames(t.tex_frames), tex_blend(t.tex_blend),
|
||||
tex_flags(t.tex_flags), sx(t.sx), sy(t.sy), tx(t.tx), ty(t.ty), rot(t.rot), mat_used(t.mat_used),
|
||||
mat_valid(t.mat_valid), matrix(t.matrix), transparent(t.transparent)
|
||||
{}
|
||||
};
|
||||
|
||||
Texture::Texture() :rep(0) {
|
||||
}
|
||||
Texture::Texture() : rep(0) {}
|
||||
|
||||
Texture::Texture(const string &f, int flags) {
|
||||
Texture::Texture(const string& f, int flags)
|
||||
{
|
||||
flags = filterFile(f, flags) | gxCanvas::CANVAS_TEXTURE;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK) flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK)
|
||||
flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
|
||||
rep = new Rep(f, flags, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
Texture::Texture(const string &f, int flags, int w, int h, int first, int cnt) {
|
||||
Texture::Texture(const string& f, int flags, int w, int h, int first, int cnt)
|
||||
{
|
||||
flags = filterFile(f, flags) | gxCanvas::CANVAS_TEXTURE;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK) flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK)
|
||||
flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
|
||||
rep = new Rep(f, flags, w, h, first, cnt);
|
||||
}
|
||||
|
||||
Texture::Texture(int w, int h, int flags, int cnt) {
|
||||
Texture::Texture(int w, int h, int flags, int cnt)
|
||||
{
|
||||
flags |= gxCanvas::CANVAS_TEXTURE;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK) flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK)
|
||||
flags |= gxCanvas::CANVAS_TEX_RGB | gxCanvas::CANVAS_TEX_ALPHA;
|
||||
rep = new Rep(w, h, flags, cnt);
|
||||
}
|
||||
|
||||
Texture::Texture(const Texture &t) :
|
||||
rep(t.rep) {
|
||||
if (rep) ++rep->ref_cnt;
|
||||
Texture::Texture(const Texture& t) : rep(t.rep)
|
||||
{
|
||||
if (rep)
|
||||
++rep->ref_cnt;
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if (rep && !--rep->ref_cnt) delete rep;
|
||||
Texture::~Texture()
|
||||
{
|
||||
if (rep && !--rep->ref_cnt)
|
||||
delete rep;
|
||||
}
|
||||
|
||||
Texture &Texture::operator=(const Texture &t) {
|
||||
if (t.rep) ++t.rep->ref_cnt;
|
||||
if (rep && !--rep->ref_cnt) delete rep;
|
||||
Texture& Texture::operator=(const Texture& t)
|
||||
{
|
||||
if (t.rep)
|
||||
++t.rep->ref_cnt;
|
||||
if (rep && !--rep->ref_cnt)
|
||||
delete rep;
|
||||
rep = t.rep;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Texture::setScale(float u_scale, float v_scale) {
|
||||
if (!rep) return;
|
||||
rep->sx = u_scale; rep->sy = v_scale;
|
||||
void Texture::setScale(float u_scale, float v_scale)
|
||||
{
|
||||
if (!rep)
|
||||
return;
|
||||
rep->sx = u_scale;
|
||||
rep->sy = v_scale;
|
||||
rep->mat_valid = false;
|
||||
rep->mat_used = true;
|
||||
}
|
||||
|
||||
void Texture::setRotation(float angle) {
|
||||
if (!rep) return;
|
||||
void Texture::setRotation(float angle)
|
||||
{
|
||||
if (!rep)
|
||||
return;
|
||||
rep->rot = angle;
|
||||
rep->mat_valid = false;
|
||||
rep->mat_used = true;
|
||||
}
|
||||
|
||||
void Texture::setPosition(float u_pos, float v_pos) {
|
||||
if (!rep) return;
|
||||
void Texture::setPosition(float u_pos, float v_pos)
|
||||
{
|
||||
if (!rep)
|
||||
return;
|
||||
rep->tx = u_pos;
|
||||
rep->ty = v_pos;
|
||||
rep->mat_valid = false;
|
||||
rep->mat_used = true;
|
||||
}
|
||||
|
||||
void Texture::setBlend(int blend) {
|
||||
if (!rep) return;
|
||||
void Texture::setBlend(int blend)
|
||||
{
|
||||
if (!rep)
|
||||
return;
|
||||
rep->tex_blend = blend;
|
||||
}
|
||||
|
||||
void Texture::setFlags(int flags) {
|
||||
if (!rep) return;
|
||||
void Texture::setFlags(int flags)
|
||||
{
|
||||
if (!rep)
|
||||
return;
|
||||
rep->tex_flags = flags;
|
||||
}
|
||||
|
||||
bool Texture::isTransparent()const {
|
||||
bool Texture::isTransparent() const
|
||||
{
|
||||
return rep ? rep->transparent : false;
|
||||
}
|
||||
|
||||
gxCanvas *Texture::getCanvas(int n)const {
|
||||
gxCanvas* Texture::getCanvas(int n) const
|
||||
{
|
||||
return rep && n >= 0 && n < rep->tex_frames.size() ? rep->tex_frames[n] : 0;
|
||||
}
|
||||
|
||||
int Texture::getCanvasFlags()const {
|
||||
int Texture::getCanvasFlags() const
|
||||
{
|
||||
return rep && rep->tex_frames.size() ? rep->tex_frames[0]->getFlags() : 0;
|
||||
}
|
||||
|
||||
CachedTextureFactory *Texture::getCachedTexture()const {
|
||||
CachedTextureFactory* Texture::getCachedTexture() const
|
||||
{
|
||||
return rep ? &rep->cached_tex : 0;
|
||||
}
|
||||
|
||||
int Texture::getBlend()const {
|
||||
int Texture::getBlend() const
|
||||
{
|
||||
return rep ? rep->tex_blend : 0;
|
||||
}
|
||||
|
||||
int Texture::getFlags()const {
|
||||
int Texture::getFlags() const
|
||||
{
|
||||
return rep ? rep->tex_flags : 0;
|
||||
}
|
||||
|
||||
const gxScene::Matrix *Texture::getMatrix()const {
|
||||
if (!rep || !rep->mat_used) return 0;
|
||||
const gxScene::Matrix* Texture::getMatrix() const
|
||||
{
|
||||
if (!rep || !rep->mat_used)
|
||||
return 0;
|
||||
if (!rep->mat_valid) {
|
||||
float c = cos(rep->rot), s = sin(rep->rot);
|
||||
rep->matrix.elements[0][0] = c*rep->sx;
|
||||
rep->matrix.elements[1][0] = s*rep->sx;
|
||||
rep->matrix.elements[0][1] = -s*rep->sy;
|
||||
rep->matrix.elements[1][1] = c*rep->sy;
|
||||
rep->matrix.elements[0][0] = c * rep->sx;
|
||||
rep->matrix.elements[1][0] = s * rep->sx;
|
||||
rep->matrix.elements[0][1] = -s * rep->sy;
|
||||
rep->matrix.elements[1][1] = c * rep->sy;
|
||||
rep->matrix.elements[2][0] = rep->tx;
|
||||
rep->matrix.elements[2][1] = rep->ty;
|
||||
rep->mat_valid = true;
|
||||
@@ -181,15 +204,19 @@ const gxScene::Matrix *Texture::getMatrix()const {
|
||||
return &rep->matrix;
|
||||
}
|
||||
|
||||
bool Texture::operator<(const Texture &t)const {
|
||||
if (rep && t.rep) return rep->cached_tex < t.rep->cached_tex;
|
||||
bool Texture::operator<(const Texture& t) const
|
||||
{
|
||||
if (rep && t.rep)
|
||||
return rep->cached_tex < t.rep->cached_tex;
|
||||
return rep < t.rep;
|
||||
}
|
||||
|
||||
void Texture::clearFilters() {
|
||||
void Texture::clearFilters()
|
||||
{
|
||||
filters.clear();
|
||||
}
|
||||
|
||||
void Texture::addFilter(const string &t, int flags) {
|
||||
void Texture::addFilter(const string& t, int flags)
|
||||
{
|
||||
filters.push_back(Filter(tolower(t), flags));
|
||||
}
|
||||
|
||||
+24
-24
@@ -6,41 +6,41 @@
|
||||
|
||||
#include "cachedtexture.hpp"
|
||||
|
||||
#include "../gxruntime/gxcanvas.hpp"
|
||||
#include "gxcanvas.hpp"
|
||||
|
||||
class Texture{
|
||||
public:
|
||||
class Texture {
|
||||
public:
|
||||
Texture();
|
||||
Texture( const std::string &file,int flags );
|
||||
Texture( const std::string &file,int flags,int w,int h,int first,int cnt );
|
||||
Texture( int width,int height,int flags,int cnt );
|
||||
Texture( const Texture &texture );
|
||||
Texture(const std::string& file, int flags);
|
||||
Texture(const std::string& file, int flags, int w, int h, int first, int cnt);
|
||||
Texture(int width, int height, int flags, int cnt);
|
||||
Texture(const Texture& texture);
|
||||
~Texture();
|
||||
|
||||
Texture &operator=( const Texture &texture );
|
||||
Texture& operator=(const Texture& texture);
|
||||
|
||||
void setScale( float u_scale,float v_scale );
|
||||
void setRotation( float rot );
|
||||
void setPosition( float u_pos,float v_pos );
|
||||
void setBlend( int blend );
|
||||
void setFlags( int flags );
|
||||
void setScale(float u_scale, float v_scale);
|
||||
void setRotation(float rot);
|
||||
void setPosition(float u_pos, float v_pos);
|
||||
void setBlend(int blend);
|
||||
void setFlags(int flags);
|
||||
|
||||
int getCanvasFlags()const;
|
||||
gxCanvas *getCanvas( int frame )const;
|
||||
const gxScene::Matrix *getMatrix()const;
|
||||
int getBlend()const;
|
||||
int getFlags()const;
|
||||
CachedTextureFactory *getCachedTexture()const;
|
||||
int getCanvasFlags() const;
|
||||
gxCanvas* getCanvas(int frame) const;
|
||||
const gxScene::Matrix* getMatrix() const;
|
||||
int getBlend() const;
|
||||
int getFlags() const;
|
||||
CachedTextureFactory* getCachedTexture() const;
|
||||
|
||||
bool isTransparent()const;
|
||||
bool operator<( const Texture &t )const;
|
||||
bool isTransparent() const;
|
||||
bool operator<(const Texture& t) const;
|
||||
|
||||
static void clearFilters();
|
||||
static void addFilter( const std::string &filter,int flags );
|
||||
static void addFilter(const std::string& filter, int flags);
|
||||
|
||||
private:
|
||||
private:
|
||||
struct Rep;
|
||||
Rep *rep;
|
||||
Rep* rep;
|
||||
};
|
||||
|
||||
#endif
|
||||
+143
-107
@@ -1,27 +1,29 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include <queue>
|
||||
#include "world.hpp"
|
||||
#include <queue>
|
||||
#include "std.hpp"
|
||||
|
||||
//0=tris compared for collision
|
||||
//1=max proj err of terrain
|
||||
float stats3d[10];
|
||||
|
||||
extern gxScene *gx_scene;
|
||||
extern gxRuntime *gx_runtime;
|
||||
extern gxScene* gx_scene;
|
||||
extern gxRuntime* gx_runtime;
|
||||
|
||||
static std::list<Object*> s_objectsEnabled, s_objectsVisible;
|
||||
|
||||
static void StaticEnumerateEnabled() {
|
||||
static void StaticEnumerateEnabled()
|
||||
{
|
||||
s_objectsEnabled.clear();
|
||||
for (Entity *e = Entity::GetEntityOrphans(); e; e = e->GetSuccessor()) {
|
||||
for (Entity* e = Entity::GetEntityOrphans(); e; e = e->GetSuccessor()) {
|
||||
e->EnumerateEnabled(s_objectsEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void StaticEnumerateVisible() {
|
||||
static void StaticEnumerateVisible()
|
||||
{
|
||||
s_objectsVisible.clear();
|
||||
for (Entity *e = Entity::GetEntityOrphans(); e; e = e->GetSuccessor()) {
|
||||
for (Entity* e = Entity::GetEntityOrphans(); e; e = e->GetSuccessor()) {
|
||||
e->EnumerateVisible(s_objectsVisible);
|
||||
}
|
||||
}
|
||||
@@ -32,8 +34,9 @@ static vector<Object*> _objsByType[1000];
|
||||
|
||||
static vector<ObjCollision*> free_colls, used_colls;
|
||||
|
||||
static ObjCollision *allocObjColl(Object *with, const Vector &coords, const Collision &coll) {
|
||||
ObjCollision *c;
|
||||
static ObjCollision* allocObjColl(Object* with, const Vector& coords, const Collision& coll)
|
||||
{
|
||||
ObjCollision* c;
|
||||
if (free_colls.size()) {
|
||||
c = free_colls.back();
|
||||
free_colls.pop_back();
|
||||
@@ -47,10 +50,10 @@ static ObjCollision *allocObjColl(Object *with, const Vector &coords, const Coll
|
||||
return c;
|
||||
}
|
||||
|
||||
static void collided(Object *src, Object *dest, const Line &line, const Collision &coll, float y_scale) {
|
||||
|
||||
ObjCollision *c;
|
||||
const Vector &coords = line*coll.time - coll.normal*src->getCollisionRadii().x;
|
||||
static void collided(Object* src, Object* dest, const Line& line, const Collision& coll, float y_scale)
|
||||
{
|
||||
ObjCollision* c;
|
||||
const Vector& coords = line * coll.time - coll.normal * src->getCollisionRadii().x;
|
||||
|
||||
c = allocObjColl(dest, coords, coll);
|
||||
c->coords.y *= y_scale;
|
||||
@@ -61,25 +64,28 @@ static void collided(Object *src, Object *dest, const Line &line, const Collisio
|
||||
dest->addCollision(c);
|
||||
}
|
||||
|
||||
void World::clearCollisions() {
|
||||
void World::clearCollisions()
|
||||
{
|
||||
for (int k = 0; k < 1000; ++k) {
|
||||
_collInfo[k].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void World::addCollision(int src_type, int dst_type, int method, int response) {
|
||||
|
||||
vector<CollInfo> &info = _collInfo[src_type];
|
||||
void World::addCollision(int src_type, int dst_type, int method, int response)
|
||||
{
|
||||
vector<CollInfo>& info = _collInfo[src_type];
|
||||
for (size_t k = 0; k < info.size(); ++k) {
|
||||
const CollInfo &t = info[k];
|
||||
if (dst_type == t.dst_type) return;
|
||||
const CollInfo& t = info[k];
|
||||
if (dst_type == t.dst_type)
|
||||
return;
|
||||
}
|
||||
|
||||
CollInfo co = { dst_type,method,response };
|
||||
CollInfo co = {dst_type, method, response};
|
||||
_collInfo[src_type].push_back(co);
|
||||
}
|
||||
|
||||
bool World::hitTest(const Line &line, float radius, Object *obj, const Transform &tf, int method, Collision *curr_coll) {
|
||||
bool World::hitTest(const Line& line, float radius, Object* obj, const Transform& tf, int method, Collision* curr_coll)
|
||||
{
|
||||
switch (method) {
|
||||
case COLLISION_METHOD_SPHERE:
|
||||
return curr_coll->sphereCollide(line, radius, tf.v, obj->getCollisionRadii().x);
|
||||
@@ -87,26 +93,29 @@ bool World::hitTest(const Line &line, float radius, Object *obj, const Transform
|
||||
return obj->collide(line, radius, curr_coll, tf);
|
||||
case COLLISION_METHOD_BOX:
|
||||
Transform t = tf;
|
||||
t.m.i.normalize(); t.m.j.normalize(); t.m.k.normalize();
|
||||
if (curr_coll->boxCollide(~t*line, radius, obj->getCollisionBox())) {
|
||||
curr_coll->normal = t.m*curr_coll->normal;
|
||||
t.m.i.normalize();
|
||||
t.m.j.normalize();
|
||||
t.m.k.normalize();
|
||||
if (curr_coll->boxCollide(~t * line, radius, obj->getCollisionBox())) {
|
||||
curr_coll->normal = t.m * curr_coll->normal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool World::CheckLineOfSight(Object *src, Object *dest) {
|
||||
|
||||
bool World::CheckLineOfSight(Object* src, Object* dest)
|
||||
{
|
||||
StaticEnumerateEnabled();
|
||||
|
||||
Object *coll_obj = 0;
|
||||
Object* coll_obj = 0;
|
||||
Collision curr_coll;
|
||||
|
||||
Line line(src->GetWorldPosition(), dest->GetWorldPosition() - src->GetWorldPosition());
|
||||
|
||||
for (Object* obj : s_objectsEnabled) {
|
||||
if (obj == src || obj == dest || !obj->getPickGeometry() || !obj->getObscurer()) continue;
|
||||
if (obj == src || obj == dest || !obj->getPickGeometry() || !obj->getObscurer())
|
||||
continue;
|
||||
|
||||
if (hitTest(line, 0, obj, obj->GetWorldTransform(), obj->getPickGeometry(), &curr_coll)) {
|
||||
return false;
|
||||
@@ -115,22 +124,22 @@ bool World::CheckLineOfSight(Object *src, Object *dest) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Object *World::traceRay(const Line &line, float radius, ObjCollision *curr_coll) {
|
||||
|
||||
Object* World::traceRay(const Line& line, float radius, ObjCollision* curr_coll)
|
||||
{
|
||||
StaticEnumerateEnabled();
|
||||
|
||||
Object *coll_obj = 0;
|
||||
Object* coll_obj = 0;
|
||||
|
||||
for (Object* obj : s_objectsEnabled) {
|
||||
|
||||
if (!obj->getPickGeometry()) continue;
|
||||
if (!obj->getPickGeometry())
|
||||
continue;
|
||||
|
||||
if (hitTest(line, radius, obj, obj->GetWorldTransform(), obj->getPickGeometry(), &curr_coll->collision)) {
|
||||
coll_obj = obj;
|
||||
}
|
||||
}
|
||||
if (curr_coll->with = coll_obj) {
|
||||
curr_coll->coords = line*curr_coll->collision.time - curr_coll->collision.normal*radius;
|
||||
curr_coll->coords = line * curr_coll->collision.time - curr_coll->collision.normal * radius;
|
||||
}
|
||||
return coll_obj;
|
||||
}
|
||||
@@ -138,7 +147,8 @@ Object *World::traceRay(const Line &line, float radius, ObjCollision *curr_coll)
|
||||
//
|
||||
// NEW VERSION
|
||||
//
|
||||
void World::collide(Object *src) {
|
||||
void World::collide(Object* src)
|
||||
{
|
||||
Vector dv = src->GetWorldTransform().v;
|
||||
Vector sv = src->getPrevWorldTform().v;
|
||||
|
||||
@@ -153,7 +163,7 @@ void World::collide(Object *src) {
|
||||
|
||||
static Transform y_tform;
|
||||
|
||||
const Vector &radii = src->getCollisionRadii();
|
||||
const Vector& radii = src->getCollisionRadii();
|
||||
|
||||
float radius = radii.x, inv_y_scale;
|
||||
float y_scale = inv_y_scale = y_tform.m.j.y = 1;
|
||||
@@ -173,57 +183,54 @@ void World::collide(Object *src) {
|
||||
float td = coll_line.d.length();
|
||||
float td_xz = Vector(coll_line.d.x, 0, coll_line.d.z).length();
|
||||
|
||||
const vector<CollInfo> &collinfos = _collInfo[src->getCollisionType()];
|
||||
const vector<CollInfo>& collinfos = _collInfo[src->getCollisionType()];
|
||||
|
||||
int hits = 0;
|
||||
for (;;) {
|
||||
Collision coll;
|
||||
Object *coll_obj = 0;
|
||||
Object* coll_obj = 0;
|
||||
vector<CollInfo>::const_iterator coll_it, coll_info;
|
||||
|
||||
for (coll_it = collinfos.begin(); coll_it != collinfos.end(); ++coll_it) {
|
||||
// const std::list<Object*> &dst_objs = _objsByType[coll_it->dst_type];
|
||||
for (Object* dst : /*dst_objs*/_objsByType[coll_it->dst_type]) {
|
||||
// const std::list<Object*> &dst_objs = _objsByType[coll_it->dst_type];
|
||||
for (Object* dst : /*dst_objs*/ _objsByType[coll_it->dst_type]) {
|
||||
if (src == dst)
|
||||
continue;
|
||||
|
||||
if (src == dst) continue;
|
||||
|
||||
const Transform &dst_tform = dst->getPrevWorldTform();
|
||||
const Transform& dst_tform = dst->getPrevWorldTform();
|
||||
|
||||
if (y_scale == 1) {
|
||||
if (hitTest(
|
||||
coll_line, radius, dst, dst_tform,
|
||||
coll_it->method, &coll)) {
|
||||
if (hitTest(coll_line, radius, dst, dst_tform, coll_it->method, &coll)) {
|
||||
coll_obj = dst;
|
||||
coll_info = coll_it;
|
||||
}
|
||||
} else {
|
||||
if (hitTest(
|
||||
coll_line, radius, dst, y_tform * dst_tform,
|
||||
coll_it->method, &coll)) {
|
||||
if (hitTest(coll_line, radius, dst, y_tform * dst_tform, coll_it->method, &coll)) {
|
||||
coll_obj = dst;
|
||||
coll_info = coll_it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!coll_obj) break;
|
||||
if (!coll_obj)
|
||||
break;
|
||||
|
||||
//register collision
|
||||
if (++hits == WORLD_COLLISION_HITS) {
|
||||
// exit(0);
|
||||
// exit(0);
|
||||
break;
|
||||
}
|
||||
|
||||
collided(src, coll_obj, coll_line, coll, inv_y_scale);
|
||||
|
||||
Plane coll_plane(coll_line*coll.time, coll.normal);
|
||||
Plane coll_plane(coll_line * coll.time, coll.normal);
|
||||
|
||||
coll_plane.d -= COLLISION_FLT_EPSILON;
|
||||
coll.time = coll_plane.t_intersect(coll_line);
|
||||
|
||||
if (coll.time > 0) {// && fabs(coll.normal.dot( coll_line.d ))>FLT_EPSILON ){
|
||||
if (coll.time > 0) { // && fabs(coll.normal.dot( coll_line.d ))>FLT_EPSILON ){
|
||||
//update source position - ONLY IF AHEAD!
|
||||
sv = coll_line*coll.time;
|
||||
sv = coll_line * coll.time;
|
||||
td *= 1 - coll.time;
|
||||
td_xz *= 1 - coll.time;
|
||||
}
|
||||
@@ -240,37 +247,53 @@ void World::collide(Object *src) {
|
||||
dv = nv;
|
||||
} else if (n_hit == 1) {
|
||||
if (planes[0].distance(nv) >= 0) {
|
||||
dv = nv; n_hit = 0;
|
||||
dv = nv;
|
||||
n_hit = 0;
|
||||
} else if (fabs(planes[0].n.dot(coll_plane.n)) < 1 - FLT_EPSILON) {
|
||||
dv = coll_plane.intersect(planes[0]).nearest(dv);
|
||||
} else {
|
||||
//SQUISHED!
|
||||
//exit(0);
|
||||
hits = WORLD_COLLISION_HITS; break;
|
||||
hits = WORLD_COLLISION_HITS;
|
||||
break;
|
||||
}
|
||||
} else if (planes[0].distance(nv) >= 0 && planes[1].distance(nv) >= 0) {
|
||||
dv = nv; n_hit = 0;
|
||||
dv = nv;
|
||||
n_hit = 0;
|
||||
} else {
|
||||
dv = sv; break;
|
||||
dv = sv;
|
||||
break;
|
||||
}
|
||||
|
||||
Vector dd(dv - sv);
|
||||
|
||||
//going behind initial direction? really necessary?
|
||||
if (dd.dot(dir) <= 0) { dv = sv; break; }
|
||||
if (dd.dot(dir) <= 0) {
|
||||
dv = sv;
|
||||
break;
|
||||
}
|
||||
|
||||
if (coll_info->response == COLLISION_RESPONSE_SLIDE) {
|
||||
float d = dd.length();
|
||||
if (d <= FLT_EPSILON) { dv = sv; break; }
|
||||
if (d > td) dd *= td / d;
|
||||
if (d <= FLT_EPSILON) {
|
||||
dv = sv;
|
||||
break;
|
||||
}
|
||||
if (d > td)
|
||||
dd *= td / d;
|
||||
} else if (coll_info->response == COLLISION_RESPONSE_SLIDEXZ) {
|
||||
float d = Vector(dd.x, 0, dd.z).length();
|
||||
if (d <= FLT_EPSILON) { dv = sv; break; }
|
||||
if (d > td_xz) dd *= td_xz / d;
|
||||
if (d <= FLT_EPSILON) {
|
||||
dv = sv;
|
||||
break;
|
||||
}
|
||||
if (d > td_xz)
|
||||
dd *= td_xz / d;
|
||||
}
|
||||
|
||||
coll_line.o = sv;
|
||||
coll_line.d = dd; dv = sv + dd;
|
||||
coll_line.d = dd;
|
||||
dv = sv + dd;
|
||||
planes[n_hit++] = coll_plane;
|
||||
}
|
||||
|
||||
@@ -447,8 +470,8 @@ void World::collide( Object *src ){
|
||||
}
|
||||
*/
|
||||
|
||||
void World::update(float elapsed) {
|
||||
|
||||
void World::update(float elapsed)
|
||||
{
|
||||
stats3d[0] = 0;
|
||||
|
||||
for (; used_colls.size(); used_colls.pop_back()) {
|
||||
@@ -463,7 +486,8 @@ void World::update(float elapsed) {
|
||||
}
|
||||
|
||||
o->beginUpdate(elapsed);
|
||||
if (o->getCollisionType()) collide(o);
|
||||
if (o->getCollisionType())
|
||||
collide(o);
|
||||
o->endUpdate();
|
||||
}
|
||||
|
||||
@@ -482,16 +506,16 @@ static vector<Mirror*> _mirrors;
|
||||
static vector<Listener*> _listeners;
|
||||
|
||||
struct OrderComp {
|
||||
bool operator()(Object *a, Object *b) {
|
||||
bool operator()(Object* a, Object* b)
|
||||
{
|
||||
return a->getOrder() < b->getOrder();
|
||||
}
|
||||
};
|
||||
|
||||
struct TransComp {
|
||||
bool operator()(Model *a, Model *b)const {
|
||||
return
|
||||
cam_tform.v.distance(a->getRenderTform().v) <
|
||||
cam_tform.v.distance(b->getRenderTform().v);
|
||||
bool operator()(Model* a, Model* b) const
|
||||
{
|
||||
return cam_tform.v.distance(a->getRenderTform().v) < cam_tform.v.distance(b->getRenderTform().v);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -503,8 +527,8 @@ static priority_queue<Camera*, vector<Camera*>, OrderComp> cam_que;
|
||||
|
||||
static priority_queue<Model*, vector<Model*>, TransComp> transparents;
|
||||
|
||||
void World::capture() {
|
||||
|
||||
void World::capture()
|
||||
{
|
||||
StaticEnumerateVisible();
|
||||
|
||||
for (Object* o : s_objectsVisible) {
|
||||
@@ -512,8 +536,8 @@ void World::capture() {
|
||||
}
|
||||
}
|
||||
|
||||
void World::render(float tween) {
|
||||
|
||||
void World::render(float tween)
|
||||
{
|
||||
//set render tweens, and build ordered and unordered model lists...
|
||||
ord_mods.clear();
|
||||
unord_mods.clear();
|
||||
@@ -526,29 +550,38 @@ void World::render(float tween) {
|
||||
StaticEnumerateVisible();
|
||||
|
||||
for (Object* o : s_objectsVisible) {
|
||||
if (!o->beginRender(tween)) continue;
|
||||
if (!o->beginRender(tween))
|
||||
continue;
|
||||
|
||||
if (Light *t = o->getLight()) _lights.push_back(t->getGxLight());
|
||||
else if (Camera *t = o->getCamera()) cam_que.push(t);
|
||||
else if (Mirror *t = o->getMirror()) _mirrors.push_back(t);
|
||||
else if (Listener *t = o->getListener()) _listeners.push_back(t);
|
||||
else if (Model *t = o->getModel()) {
|
||||
if (t->getOrder()) ord_que.push(t);
|
||||
else unord_mods.push_back(t);
|
||||
if (Light* t = o->getLight())
|
||||
_lights.push_back(t->getGxLight());
|
||||
else if (Camera* t = o->getCamera())
|
||||
cam_que.push(t);
|
||||
else if (Mirror* t = o->getMirror())
|
||||
_mirrors.push_back(t);
|
||||
else if (Listener* t = o->getListener())
|
||||
_listeners.push_back(t);
|
||||
else if (Model* t = o->getModel()) {
|
||||
if (t->getOrder())
|
||||
ord_que.push(t);
|
||||
else
|
||||
unord_mods.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
for (; ord_que.size(); ord_que.pop()) ord_mods.push_back(ord_que.top());
|
||||
for (; ord_que.size(); ord_que.pop())
|
||||
ord_mods.push_back(ord_que.top());
|
||||
|
||||
// gx_runtime->debugLog( "RenderWorld" );
|
||||
// gx_runtime->debugLog( "RenderWorld" );
|
||||
|
||||
if (!gx_scene->begin(_lights)) return;
|
||||
if (!gx_scene->begin(_lights))
|
||||
return;
|
||||
|
||||
for (; cam_que.size(); cam_que.pop()) {
|
||||
Camera* cam = cam_que.top();
|
||||
|
||||
Camera *cam = cam_que.top();
|
||||
|
||||
if (!cam->beginRenderFrame()) continue;
|
||||
if (!cam->beginRenderFrame())
|
||||
continue;
|
||||
|
||||
vector<Mirror*>::const_iterator mir_it;
|
||||
for (mir_it = _mirrors.begin(); mir_it != _mirrors.end(); ++mir_it) {
|
||||
@@ -560,7 +593,7 @@ void World::render(float tween) {
|
||||
|
||||
gx_scene->end();
|
||||
|
||||
// gx_runtime->debugLog( "End RenderWorld" );
|
||||
// gx_runtime->debugLog( "End RenderWorld" );
|
||||
|
||||
vector<Listener*>::const_iterator lis_it;
|
||||
for (lis_it = _listeners.begin(); lis_it != _listeners.end(); ++lis_it) {
|
||||
@@ -568,10 +601,10 @@ void World::render(float tween) {
|
||||
}
|
||||
}
|
||||
|
||||
void World::render(Camera *cam, Mirror *mirror) {
|
||||
|
||||
void World::render(Camera* cam, Mirror* mirror)
|
||||
{
|
||||
if (mirror) {
|
||||
const Transform &t = mirror->getRenderTform();
|
||||
const Transform& t = mirror->getRenderTform();
|
||||
cam_tform = t * Transform(scaleMatrix(1, -1, 1)) * -t * cam->getRenderTform();
|
||||
gx_scene->setFlippedTris(true);
|
||||
} else {
|
||||
@@ -588,17 +621,19 @@ void World::render(Camera *cam, Mirror *mirror) {
|
||||
//draw everything in order
|
||||
size_t ord = 0;
|
||||
gx_scene->setZMode(gxScene::ZMODE_DISABLE);
|
||||
while (ord < ord_mods.size() && ord_mods[ord]->getOrder()>0) {
|
||||
Model *mod = ord_mods[ord++];
|
||||
if (!mod->doAutoFade(cam_tform.v)) continue;
|
||||
while (ord < ord_mods.size() && ord_mods[ord]->getOrder() > 0) {
|
||||
Model* mod = ord_mods[ord++];
|
||||
if (!mod->doAutoFade(cam_tform.v))
|
||||
continue;
|
||||
render(mod, rc);
|
||||
flushTransparent();
|
||||
}
|
||||
|
||||
gx_scene->setZMode(gxScene::ZMODE_NORMAL);
|
||||
for (size_t k = 0; k < unord_mods.size(); ++k) {
|
||||
Model *mod = unord_mods[k];
|
||||
if (!mod->doAutoFade(cam_tform.v)) continue;
|
||||
Model* mod = unord_mods[k];
|
||||
if (!mod->doAutoFade(cam_tform.v))
|
||||
continue;
|
||||
render(mod, rc);
|
||||
}
|
||||
gx_scene->setZMode(gxScene::ZMODE_CMPONLY);
|
||||
@@ -606,15 +641,16 @@ void World::render(Camera *cam, Mirror *mirror) {
|
||||
|
||||
gx_scene->setZMode(gxScene::ZMODE_DISABLE);
|
||||
while (ord < ord_mods.size()) {
|
||||
Model *mod = ord_mods[ord++];
|
||||
if (!mod->doAutoFade(cam_tform.v)) continue;
|
||||
Model* mod = ord_mods[ord++];
|
||||
if (!mod->doAutoFade(cam_tform.v))
|
||||
continue;
|
||||
render(mod, rc);
|
||||
flushTransparent();
|
||||
}
|
||||
}
|
||||
|
||||
void World::render(Model *mod, const RenderContext &rc) {
|
||||
|
||||
void World::render(Model* mod, const RenderContext& rc)
|
||||
{
|
||||
bool trans = mod->render(rc);
|
||||
|
||||
if (mod->queueSize(Model::QUEUE_OPAQUE)) {
|
||||
@@ -631,12 +667,12 @@ void World::render(Model *mod, const RenderContext &rc) {
|
||||
}
|
||||
}
|
||||
|
||||
void World::flushTransparent() {
|
||||
|
||||
void World::flushTransparent()
|
||||
{
|
||||
bool local = true;
|
||||
|
||||
for (; transparents.size(); transparents.pop()) {
|
||||
Model *mod = transparents.top();
|
||||
Model* mod = transparents.top();
|
||||
if (mod->getRenderSpace() == Model::RENDER_SPACE_LOCAL) {
|
||||
gx_scene->setWorldMatrix((gxScene::Matrix*)&mod->getRenderTform());
|
||||
local = true;
|
||||
|
||||
+22
-27
@@ -4,57 +4,52 @@
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "model.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "light.hpp"
|
||||
#include "mirror.hpp"
|
||||
#include "listener.hpp"
|
||||
#include "mirror.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
#define WORLD_COLLISION_TYPES 16
|
||||
#define WORLD_COLLISION_HITS 4
|
||||
|
||||
class World{
|
||||
public:
|
||||
class World {
|
||||
public:
|
||||
//collision methods
|
||||
enum{
|
||||
COLLISION_METHOD_SPHERE=1,
|
||||
COLLISION_METHOD_POLYGON=2,
|
||||
COLLISION_METHOD_BOX=3
|
||||
};
|
||||
enum { COLLISION_METHOD_SPHERE = 1, COLLISION_METHOD_POLYGON = 2, COLLISION_METHOD_BOX = 3 };
|
||||
|
||||
//collision actions
|
||||
enum{
|
||||
COLLISION_RESPONSE_NONE=0,
|
||||
COLLISION_RESPONSE_STOP=1,
|
||||
COLLISION_RESPONSE_SLIDE=2,
|
||||
COLLISION_RESPONSE_SLIDEXZ=3,
|
||||
enum {
|
||||
COLLISION_RESPONSE_NONE = 0,
|
||||
COLLISION_RESPONSE_STOP = 1,
|
||||
COLLISION_RESPONSE_SLIDE = 2,
|
||||
COLLISION_RESPONSE_SLIDEXZ = 3,
|
||||
};
|
||||
|
||||
void clearCollisions();
|
||||
void addCollision( int src_type,int dest_type,int method,int response );
|
||||
void addCollision(int src_type, int dest_type, int method, int response);
|
||||
|
||||
void update( float elapsed );
|
||||
void update(float elapsed);
|
||||
void capture();
|
||||
void render( float tween );
|
||||
void render(float tween);
|
||||
|
||||
bool CheckLineOfSight( Object *src,Object *dest );
|
||||
bool hitTest( const Line &line,float radius,Object *obj,const Transform &tf,int method,Collision *curr_coll );
|
||||
Object *traceRay( const Line &line,float radius,ObjCollision *curr_coll );
|
||||
bool CheckLineOfSight(Object* src, Object* dest);
|
||||
bool hitTest(const Line& line, float radius, Object* obj, const Transform& tf, int method, Collision* curr_coll);
|
||||
Object* traceRay(const Line& line, float radius, ObjCollision* curr_coll);
|
||||
|
||||
private:
|
||||
struct CollInfo{
|
||||
int dst_type,method,response;
|
||||
private:
|
||||
struct CollInfo {
|
||||
int dst_type, method, response;
|
||||
};
|
||||
|
||||
vector<CollInfo> _collInfo[WORLD_COLLISION_TYPES];
|
||||
std::list<Object*> _objsByType[WORLD_COLLISION_TYPES];
|
||||
std::list<Object*> _objsByTypeSwappable[WORLD_COLLISION_TYPES];
|
||||
|
||||
void collide( Object *src );
|
||||
void render( Camera *c,Mirror *m );
|
||||
void render( Model *m,const RenderContext &rc );
|
||||
void collide(Object* src);
|
||||
void render(Camera* c, Mirror* m);
|
||||
void render(Model* m, const RenderContext& rc);
|
||||
void flushTransparent();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,10 @@ add_library(${PROJECT_NAME} STATIC
|
||||
"bbmath.hpp"
|
||||
"bbruntime.cpp"
|
||||
"bbruntime.hpp"
|
||||
"bbsockets.cpp"
|
||||
"bbsockets.hpp"
|
||||
"bbstream.cpp"
|
||||
"bbstream.hpp"
|
||||
"bbstring.cpp"
|
||||
"bbstring.hpp"
|
||||
"bbsys.cpp"
|
||||
@@ -33,8 +37,8 @@ add_library(${PROJECT_NAME} STATIC
|
||||
"runtime.cpp"
|
||||
"std.cpp"
|
||||
"std.hpp"
|
||||
"userlib.cpp"
|
||||
"userlib.hpp"
|
||||
# "userlib.cpp"
|
||||
# "userlib.hpp"
|
||||
"userlibs.cpp"
|
||||
"userlibs.hpp"
|
||||
)
|
||||
@@ -42,10 +46,11 @@ add_library(${PROJECT_NAME} STATIC
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
stdutil
|
||||
gxruntime
|
||||
runtime_gfx
|
||||
ddraw
|
||||
dsound
|
||||
dxguid
|
||||
mswsock
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
@@ -61,7 +66,7 @@ if (WIN32)
|
||||
WIN32_LEAN_AND_MEAN
|
||||
NOGPICAPMASKS
|
||||
NOVIRTUALKEYCODES
|
||||
#NOWINMESSAGES
|
||||
NOWINMESSAGES
|
||||
NOWINSTYLES
|
||||
NOSYSMETRICS
|
||||
NOMENUS
|
||||
@@ -78,7 +83,7 @@ if (WIN32)
|
||||
#NOGDI
|
||||
NOKERNEL
|
||||
#NOUSER
|
||||
#NONLS
|
||||
NONLS
|
||||
NOMB
|
||||
NOMEMMGR
|
||||
NOMETAFILE
|
||||
@@ -88,7 +93,7 @@ if (WIN32)
|
||||
NOSCROLL
|
||||
NOSERVICE
|
||||
NOSOUND
|
||||
#NOTEXTMETRIC
|
||||
NOTEXTMETRIC
|
||||
NOWH
|
||||
NOWINOFFSETS
|
||||
NOCOMM
|
||||
|
||||
+282
-149
@@ -1,5 +1,5 @@
|
||||
#include "std.hpp"
|
||||
#include "bbsys.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
//how many strings allocated
|
||||
static int stringCnt;
|
||||
@@ -17,7 +17,7 @@ static const int OBJ_NEW_INC = 512;
|
||||
static const int STR_NEW_INC = 512;
|
||||
|
||||
//current data ptr
|
||||
static BBData *dataPtr;
|
||||
static BBData* dataPtr;
|
||||
|
||||
//chunks of mem - WHAT THE FUCK WAS I ON?!?!?!?
|
||||
//static list<char*> memBlks;
|
||||
@@ -37,7 +37,8 @@ static BBType _bbFltType(BBTYPE_FLT);
|
||||
static BBType _bbStrType(BBTYPE_STR);
|
||||
static BBType _bbCStrType(BBTYPE_CSTR);
|
||||
|
||||
static void *bbMalloc(int size) {
|
||||
static void* bbMalloc(int size)
|
||||
{
|
||||
return malloc(size);
|
||||
/*
|
||||
char *c=new char[ size ];
|
||||
@@ -46,7 +47,8 @@ static void *bbMalloc(int size) {
|
||||
*/
|
||||
}
|
||||
|
||||
static void bbFree(void *q) {
|
||||
static void bbFree(void* q)
|
||||
{
|
||||
free(q);
|
||||
/*
|
||||
if( !q ) return;
|
||||
@@ -56,151 +58,196 @@ static void bbFree(void *q) {
|
||||
*/
|
||||
}
|
||||
|
||||
static void removeStr(BBStr *str) {
|
||||
static void removeStr(BBStr* str)
|
||||
{
|
||||
str->next->prev = str->prev;
|
||||
str->prev->next = str->next;
|
||||
}
|
||||
|
||||
static void insertStr(BBStr *str, BBStr *next) {
|
||||
static void insertStr(BBStr* str, BBStr* next)
|
||||
{
|
||||
str->next = next;
|
||||
str->prev = next->prev;
|
||||
str->prev->next = str;
|
||||
next->prev = str;
|
||||
}
|
||||
|
||||
void *BBStr::operator new(size_t size) {
|
||||
void* BBStr::operator new(size_t size)
|
||||
{
|
||||
if (freeStrs.next == &freeStrs) {
|
||||
BBStr *t = (BBStr*)bbMalloc(sizeof(BBStr)*STR_NEW_INC);
|
||||
for (int k = 0; k < STR_NEW_INC; ++k) insertStr(t++, &freeStrs);
|
||||
BBStr* t = (BBStr*)bbMalloc(sizeof(BBStr) * STR_NEW_INC);
|
||||
for (int k = 0; k < STR_NEW_INC; ++k)
|
||||
insertStr(t++, &freeStrs);
|
||||
}
|
||||
BBStr *t = freeStrs.next;
|
||||
removeStr(t); insertStr(t, &usedStrs);
|
||||
BBStr* t = freeStrs.next;
|
||||
removeStr(t);
|
||||
insertStr(t, &usedStrs);
|
||||
return t;
|
||||
}
|
||||
|
||||
void BBStr::operator delete(void *q) {
|
||||
if (!q) return;
|
||||
BBStr *t = (BBStr*)q;
|
||||
removeStr(t); insertStr(t, &freeStrs);
|
||||
void BBStr::operator delete(void* q)
|
||||
{
|
||||
if (!q)
|
||||
return;
|
||||
BBStr* t = (BBStr*)q;
|
||||
removeStr(t);
|
||||
insertStr(t, &freeStrs);
|
||||
}
|
||||
|
||||
BBStr::BBStr() {
|
||||
BBStr::BBStr()
|
||||
{
|
||||
++stringCnt;
|
||||
}
|
||||
|
||||
BBStr::BBStr(const char *s) :string(s) {
|
||||
BBStr::BBStr(const char* s) : string(s)
|
||||
{
|
||||
++stringCnt;
|
||||
}
|
||||
|
||||
BBStr::BBStr(const char *s, int n) : string(s, n) {
|
||||
BBStr::BBStr(const char* s, int n) : string(s, n)
|
||||
{
|
||||
++stringCnt;
|
||||
}
|
||||
|
||||
BBStr::BBStr(const BBStr &s) : string(s) {
|
||||
BBStr::BBStr(const BBStr& s) : string(s)
|
||||
{
|
||||
++stringCnt;
|
||||
}
|
||||
|
||||
BBStr::BBStr(const string &s) : string(s) {
|
||||
BBStr::BBStr(const string& s) : string(s)
|
||||
{
|
||||
++stringCnt;
|
||||
}
|
||||
|
||||
BBStr &BBStr::operator=(const char *s) {
|
||||
string::operator=(s); return *this;
|
||||
BBStr& BBStr::operator=(const char* s)
|
||||
{
|
||||
string::operator=(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BBStr &BBStr::operator=(const BBStr &s) {
|
||||
string::operator=(s); return *this;
|
||||
BBStr& BBStr::operator=(const BBStr& s)
|
||||
{
|
||||
string::operator=(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BBStr &BBStr::operator=(const string &s) {
|
||||
string::operator=(s); return *this;
|
||||
BBStr& BBStr::operator=(const string& s)
|
||||
{
|
||||
string::operator=(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BBStr::~BBStr() {
|
||||
BBStr::~BBStr()
|
||||
{
|
||||
--stringCnt;
|
||||
}
|
||||
|
||||
BBStr *_bbStrLoad(BBStr **var) {
|
||||
BBStr* _bbStrLoad(BBStr** var)
|
||||
{
|
||||
return *var ? new BBStr(**var) : new BBStr();
|
||||
}
|
||||
|
||||
void _bbStrRelease(BBStr *str) {
|
||||
void _bbStrRelease(BBStr* str)
|
||||
{
|
||||
delete str;
|
||||
}
|
||||
|
||||
void _bbStrStore(BBStr **var, BBStr *str) {
|
||||
_bbStrRelease(*var); *var = str;
|
||||
void _bbStrStore(BBStr** var, BBStr* str)
|
||||
{
|
||||
_bbStrRelease(*var);
|
||||
*var = str;
|
||||
}
|
||||
|
||||
BBStr *_bbStrConcat(BBStr *s1, BBStr *s2) {
|
||||
*s1 += *s2; delete s2; return s1;
|
||||
BBStr* _bbStrConcat(BBStr* s1, BBStr* s2)
|
||||
{
|
||||
*s1 += *s2;
|
||||
delete s2;
|
||||
return s1;
|
||||
}
|
||||
|
||||
int _bbStrCompare(BBStr *lhs, BBStr *rhs) {
|
||||
int _bbStrCompare(BBStr* lhs, BBStr* rhs)
|
||||
{
|
||||
int n = lhs->compare(*rhs);
|
||||
delete lhs; delete rhs; return n;
|
||||
delete lhs;
|
||||
delete rhs;
|
||||
return n;
|
||||
}
|
||||
|
||||
int _bbStrToInt(BBStr *s) {
|
||||
int _bbStrToInt(BBStr* s)
|
||||
{
|
||||
int n = atoi(*s);
|
||||
delete s; return n;
|
||||
delete s;
|
||||
return n;
|
||||
}
|
||||
|
||||
BBStr *_bbStrFromInt(int n) {
|
||||
BBStr* _bbStrFromInt(int n)
|
||||
{
|
||||
return new BBStr(itoa(n));
|
||||
}
|
||||
|
||||
float _bbStrToFloat(BBStr *s) {
|
||||
float _bbStrToFloat(BBStr* s)
|
||||
{
|
||||
float n = (float)atof(*s);
|
||||
delete s; return n;
|
||||
delete s;
|
||||
return n;
|
||||
}
|
||||
|
||||
BBStr *_bbStrFromFloat(float n) {
|
||||
BBStr* _bbStrFromFloat(float n)
|
||||
{
|
||||
return new BBStr(ftoa(n));
|
||||
}
|
||||
|
||||
BBStr *_bbStrConst(const char *s) {
|
||||
BBStr* _bbStrConst(const char* s)
|
||||
{
|
||||
return new BBStr(s);
|
||||
}
|
||||
|
||||
void * _bbVecAlloc(BBVecType *type) {
|
||||
void *vec = bbMalloc(type->size * 4);
|
||||
void* _bbVecAlloc(BBVecType* type)
|
||||
{
|
||||
void* vec = bbMalloc(type->size * 4);
|
||||
memset(vec, 0, type->size * 4);
|
||||
return vec;
|
||||
}
|
||||
|
||||
void _bbVecFree(void *vec, BBVecType *type) {
|
||||
void _bbVecFree(void* vec, BBVecType* type)
|
||||
{
|
||||
if (type->elementType->type == BBTYPE_STR) {
|
||||
BBStr **p = (BBStr**)vec;
|
||||
BBStr** p = (BBStr**)vec;
|
||||
for (int k = 0; k < type->size; ++p, ++k) {
|
||||
if (*p) _bbStrRelease(*p);
|
||||
if (*p)
|
||||
_bbStrRelease(*p);
|
||||
}
|
||||
} else if (type->elementType->type == BBTYPE_OBJ) {
|
||||
BBObj **p = (BBObj**)vec;
|
||||
BBObj** p = (BBObj**)vec;
|
||||
for (int k = 0; k < type->size; ++p, ++k) {
|
||||
if (*p) _bbObjRelease(*p);
|
||||
if (*p)
|
||||
_bbObjRelease(*p);
|
||||
}
|
||||
}
|
||||
bbFree(vec);
|
||||
}
|
||||
|
||||
void _bbVecBoundsEx() {
|
||||
void _bbVecBoundsEx()
|
||||
{
|
||||
ThrowRuntimeException("Blitz array index out of bounds");
|
||||
}
|
||||
|
||||
void _bbUndimArray(BBArray *array) {
|
||||
if (void *t = array->data) {
|
||||
void _bbUndimArray(BBArray* array)
|
||||
{
|
||||
if (void* t = array->data) {
|
||||
if (array->elementType == BBTYPE_STR) {
|
||||
BBStr **p = (BBStr**)t;
|
||||
BBStr** p = (BBStr**)t;
|
||||
int size = array->scales[array->dims - 1];
|
||||
for (int k = 0; k < size; ++p, ++k) {
|
||||
if (*p) _bbStrRelease(*p);
|
||||
if (*p)
|
||||
_bbStrRelease(*p);
|
||||
}
|
||||
} else if (array->elementType == BBTYPE_OBJ) {
|
||||
BBObj **p = (BBObj**)t;
|
||||
BBObj** p = (BBObj**)t;
|
||||
int size = array->scales[array->dims - 1];
|
||||
for (int k = 0; k < size; ++p, ++k) {
|
||||
if (*p) _bbObjRelease(*p);
|
||||
if (*p)
|
||||
_bbObjRelease(*p);
|
||||
}
|
||||
}
|
||||
bbFree(t);
|
||||
@@ -208,9 +255,11 @@ void _bbUndimArray(BBArray *array) {
|
||||
}
|
||||
}
|
||||
|
||||
void _bbDimArray(BBArray *array) {
|
||||
void _bbDimArray(BBArray* array)
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < array->dims; ++k) ++array->scales[k];
|
||||
for (k = 0; k < array->dims; ++k)
|
||||
++array->scales[k];
|
||||
for (k = 1; k < array->dims; ++k) {
|
||||
array->scales[k] *= array->scales[k - 1];
|
||||
}
|
||||
@@ -219,32 +268,36 @@ void _bbDimArray(BBArray *array) {
|
||||
memset(array->data, 0, size * 4);
|
||||
}
|
||||
|
||||
void _bbArrayBoundsEx() {
|
||||
void _bbArrayBoundsEx()
|
||||
{
|
||||
ThrowRuntimeException("Array index out of bounds");
|
||||
}
|
||||
|
||||
static void unlinkObj(BBObj *obj) {
|
||||
static void unlinkObj(BBObj* obj)
|
||||
{
|
||||
obj->next->prev = obj->prev;
|
||||
obj->prev->next = obj->next;
|
||||
}
|
||||
|
||||
static void insertObj(BBObj *obj, BBObj *next) {
|
||||
static void insertObj(BBObj* obj, BBObj* next)
|
||||
{
|
||||
obj->next = next;
|
||||
obj->prev = next->prev;
|
||||
next->prev->next = obj;
|
||||
next->prev = obj;
|
||||
}
|
||||
|
||||
BBObj *_bbObjNew(BBObjType *type) {
|
||||
BBObj* _bbObjNew(BBObjType* type)
|
||||
{
|
||||
if (type->free.next == &type->free) {
|
||||
int obj_size = sizeof(BBObj) + type->fieldCnt * 4;
|
||||
BBObj *o = (BBObj*)bbMalloc(obj_size*OBJ_NEW_INC);
|
||||
BBObj* o = (BBObj*)bbMalloc(obj_size * OBJ_NEW_INC);
|
||||
for (int k = 0; k < OBJ_NEW_INC; ++k) {
|
||||
insertObj(o, &type->free);
|
||||
o = (BBObj*)((char*)o + obj_size);
|
||||
}
|
||||
}
|
||||
BBObj *o = type->free.next;
|
||||
BBObj* o = type->free.next;
|
||||
unlinkObj(o);
|
||||
o->type = type;
|
||||
o->ref_cnt = 1;
|
||||
@@ -264,11 +317,14 @@ BBObj *_bbObjNew(BBObjType *type) {
|
||||
return o;
|
||||
}
|
||||
|
||||
void _bbObjDelete(BBObj *obj) {
|
||||
if (!obj) return;
|
||||
BBField *fields = obj->fields;
|
||||
if (!fields) return;
|
||||
BBObjType *type = obj->type;
|
||||
void _bbObjDelete(BBObj* obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
BBField* fields = obj->fields;
|
||||
if (!fields)
|
||||
return;
|
||||
BBObjType* type = obj->type;
|
||||
for (int k = 0; k < type->fieldCnt; ++k) {
|
||||
switch (type->fieldTypes[k]->type) {
|
||||
case BBTYPE_STR:
|
||||
@@ -292,122 +348,157 @@ void _bbObjDelete(BBObj *obj) {
|
||||
--objCnt;
|
||||
}
|
||||
|
||||
void _bbObjDeleteEach(BBObjType *type) {
|
||||
BBObj *obj = type->used.next;
|
||||
void _bbObjDeleteEach(BBObjType* type)
|
||||
{
|
||||
BBObj* obj = type->used.next;
|
||||
while (obj->type) {
|
||||
BBObj *next = obj->next;
|
||||
if (obj->fields) _bbObjDelete(obj);
|
||||
BBObj* next = obj->next;
|
||||
if (obj->fields)
|
||||
_bbObjDelete(obj);
|
||||
obj = next;
|
||||
}
|
||||
}
|
||||
|
||||
extern void bbDebugLog(BBStr *t);
|
||||
extern void bbDebugLog(BBStr* t);
|
||||
extern void bbStop();
|
||||
|
||||
void _bbObjRelease(BBObj *obj) {
|
||||
if (!obj || --obj->ref_cnt) return;
|
||||
void _bbObjRelease(BBObj* obj)
|
||||
{
|
||||
if (!obj || --obj->ref_cnt)
|
||||
return;
|
||||
unlinkObj(obj);
|
||||
insertObj(obj, &obj->type->free);
|
||||
--unrelObjCnt;
|
||||
}
|
||||
|
||||
void _bbObjStore(BBObj **var, BBObj *obj) {
|
||||
if (obj) ++obj->ref_cnt; //do this first incase of self-assignment
|
||||
void _bbObjStore(BBObj** var, BBObj* obj)
|
||||
{
|
||||
if (obj)
|
||||
++obj->ref_cnt; //do this first incase of self-assignment
|
||||
_bbObjRelease(*var);
|
||||
*var = obj;
|
||||
}
|
||||
|
||||
int _bbObjCompare(BBObj *o1, BBObj *o2) {
|
||||
int _bbObjCompare(BBObj* o1, BBObj* o2)
|
||||
{
|
||||
return (o1 ? o1->fields : 0) != (o2 ? o2->fields : 0);
|
||||
}
|
||||
|
||||
BBObj *_bbObjNext(BBObj *obj) {
|
||||
BBObj* _bbObjNext(BBObj* obj)
|
||||
{
|
||||
do {
|
||||
obj = obj->next;
|
||||
if (!obj->type) return 0;
|
||||
if (!obj->type)
|
||||
return 0;
|
||||
} while (!obj->fields);
|
||||
return obj;
|
||||
}
|
||||
|
||||
BBObj *_bbObjPrev(BBObj *obj) {
|
||||
BBObj* _bbObjPrev(BBObj* obj)
|
||||
{
|
||||
do {
|
||||
obj = obj->prev;
|
||||
if (!obj->type) return 0;
|
||||
if (!obj->type)
|
||||
return 0;
|
||||
} while (!obj->fields);
|
||||
return obj;
|
||||
}
|
||||
|
||||
BBObj *_bbObjFirst(BBObjType *type) {
|
||||
BBObj* _bbObjFirst(BBObjType* type)
|
||||
{
|
||||
return _bbObjNext(&type->used);
|
||||
}
|
||||
|
||||
BBObj *_bbObjLast(BBObjType *type) {
|
||||
BBObj* _bbObjLast(BBObjType* type)
|
||||
{
|
||||
return _bbObjPrev(&type->used);
|
||||
}
|
||||
|
||||
void _bbObjInsBefore(BBObj *o1, BBObj *o2) {
|
||||
if (o1 == o2) return;
|
||||
void _bbObjInsBefore(BBObj* o1, BBObj* o2)
|
||||
{
|
||||
if (o1 == o2)
|
||||
return;
|
||||
unlinkObj(o1);
|
||||
insertObj(o1, o2);
|
||||
}
|
||||
|
||||
void _bbObjInsAfter(BBObj *o1, BBObj *o2) {
|
||||
if (o1 == o2) return;
|
||||
void _bbObjInsAfter(BBObj* o1, BBObj* o2)
|
||||
{
|
||||
if (o1 == o2)
|
||||
return;
|
||||
unlinkObj(o1);
|
||||
insertObj(o1, o2->next);
|
||||
}
|
||||
|
||||
int _bbObjEachFirst(BBObj **var, BBObjType *type) {
|
||||
int _bbObjEachFirst(BBObj** var, BBObjType* type)
|
||||
{
|
||||
_bbObjStore(var, _bbObjFirst(type));
|
||||
return *var != 0;
|
||||
}
|
||||
|
||||
int _bbObjEachNext(BBObj **var) {
|
||||
int _bbObjEachNext(BBObj** var)
|
||||
{
|
||||
_bbObjStore(var, _bbObjNext(*var));
|
||||
return *var != 0;
|
||||
}
|
||||
|
||||
int _bbObjEachFirst2(BBObj **var, BBObjType *type) {
|
||||
int _bbObjEachFirst2(BBObj** var, BBObjType* type)
|
||||
{
|
||||
*var = _bbObjFirst(type);
|
||||
return *var != 0;
|
||||
}
|
||||
|
||||
int _bbObjEachNext2(BBObj **var) {
|
||||
int _bbObjEachNext2(BBObj** var)
|
||||
{
|
||||
*var = _bbObjNext(*var);
|
||||
return *var != 0;
|
||||
}
|
||||
|
||||
BBStr *_bbObjToStr(BBObj *obj) {
|
||||
if (!obj || !obj->fields) return new BBStr("[NULL]");
|
||||
BBStr* _bbObjToStr(BBObj* obj)
|
||||
{
|
||||
if (!obj || !obj->fields)
|
||||
return new BBStr("[NULL]");
|
||||
|
||||
static BBObj *root;
|
||||
static BBObj* root;
|
||||
static int recurs_cnt;
|
||||
|
||||
if (obj == root) return new BBStr("[ROOT]");
|
||||
if (recurs_cnt == 8) return new BBStr("....");
|
||||
if (obj == root)
|
||||
return new BBStr("[ROOT]");
|
||||
if (recurs_cnt == 8)
|
||||
return new BBStr("....");
|
||||
|
||||
++recurs_cnt;
|
||||
BBObj *oldRoot = root;
|
||||
if (!root) root = obj;
|
||||
BBObj* oldRoot = root;
|
||||
if (!root)
|
||||
root = obj;
|
||||
|
||||
BBObjType *type = obj->type;
|
||||
BBField *fields = obj->fields;
|
||||
BBStr *s = new BBStr("["), *t;
|
||||
BBObjType* type = obj->type;
|
||||
BBField* fields = obj->fields;
|
||||
BBStr * s = new BBStr("["), *t;
|
||||
for (int k = 0; k < type->fieldCnt; ++k) {
|
||||
if (k) *s += ',';
|
||||
if (k)
|
||||
*s += ',';
|
||||
switch (type->fieldTypes[k]->type) {
|
||||
case BBTYPE_INT:
|
||||
t = _bbStrFromInt(fields[k].INT); *s += *t; delete t;
|
||||
t = _bbStrFromInt(fields[k].INT);
|
||||
*s += *t;
|
||||
delete t;
|
||||
break;
|
||||
case BBTYPE_FLT:
|
||||
t = _bbStrFromFloat(fields[k].FLT); *s += *t; delete t;
|
||||
t = _bbStrFromFloat(fields[k].FLT);
|
||||
*s += *t;
|
||||
delete t;
|
||||
break;
|
||||
case BBTYPE_STR:
|
||||
if (fields[k].STR) *s += '\"' + *fields[k].STR + '\"';
|
||||
else *s += "\"\"";
|
||||
if (fields[k].STR)
|
||||
*s += '\"' + *fields[k].STR + '\"';
|
||||
else
|
||||
*s += "\"\"";
|
||||
break;
|
||||
case BBTYPE_OBJ:
|
||||
t = _bbObjToStr(fields[k].OBJ); *s += *t; delete t;
|
||||
t = _bbObjToStr(fields[k].OBJ);
|
||||
*s += *t;
|
||||
delete t;
|
||||
break;
|
||||
default:
|
||||
*s += "???";
|
||||
@@ -419,90 +510,129 @@ BBStr *_bbObjToStr(BBObj *obj) {
|
||||
return s;
|
||||
}
|
||||
|
||||
int _bbObjToHandle(BBObj *obj) {
|
||||
if (!obj || !obj->fields) return 0;
|
||||
int _bbObjToHandle(BBObj* obj)
|
||||
{
|
||||
if (!obj || !obj->fields)
|
||||
return 0;
|
||||
map<BBObj*, int>::const_iterator it = object_map.find(obj);
|
||||
if (it != object_map.end()) return it->second;
|
||||
if (it != object_map.end())
|
||||
return it->second;
|
||||
++next_handle;
|
||||
object_map[obj] = next_handle;
|
||||
handle_map[next_handle] = obj;
|
||||
return next_handle;
|
||||
}
|
||||
|
||||
BBObj *_bbObjFromHandle(int handle, BBObjType *type) {
|
||||
BBObj* _bbObjFromHandle(int handle, BBObjType* type)
|
||||
{
|
||||
map<int, BBObj*>::const_iterator it = handle_map.find(handle);
|
||||
if (it == handle_map.end()) return 0;
|
||||
BBObj *obj = it->second;
|
||||
if (it == handle_map.end())
|
||||
return 0;
|
||||
BBObj* obj = it->second;
|
||||
return obj->type == type ? obj : 0;
|
||||
}
|
||||
|
||||
void _bbNullObjEx() {
|
||||
void _bbNullObjEx()
|
||||
{
|
||||
ThrowRuntimeException("Object does not exist");
|
||||
}
|
||||
|
||||
void _bbRestore(BBData *data) {
|
||||
void _bbRestore(BBData* data)
|
||||
{
|
||||
dataPtr = data;
|
||||
}
|
||||
|
||||
int _bbReadInt() {
|
||||
int _bbReadInt()
|
||||
{
|
||||
switch (dataPtr->fieldType) {
|
||||
case BBTYPE_END:ThrowRuntimeException("Out of data"); return 0;
|
||||
case BBTYPE_INT:return dataPtr++->field.INT;
|
||||
case BBTYPE_FLT:return dataPtr++->field.FLT;
|
||||
case BBTYPE_CSTR:return atoi(dataPtr++->field.CSTR);
|
||||
default:ThrowRuntimeException("Bad data type"); return 0;
|
||||
case BBTYPE_END:
|
||||
ThrowRuntimeException("Out of data");
|
||||
return 0;
|
||||
case BBTYPE_INT:
|
||||
return dataPtr++->field.INT;
|
||||
case BBTYPE_FLT:
|
||||
return dataPtr++->field.FLT;
|
||||
case BBTYPE_CSTR:
|
||||
return atoi(dataPtr++->field.CSTR);
|
||||
default:
|
||||
ThrowRuntimeException("Bad data type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float _bbReadFloat() {
|
||||
float _bbReadFloat()
|
||||
{
|
||||
switch (dataPtr->fieldType) {
|
||||
case BBTYPE_END:ThrowRuntimeException("Out of data"); return 0;
|
||||
case BBTYPE_INT:return dataPtr++->field.INT;
|
||||
case BBTYPE_FLT:return dataPtr++->field.FLT;
|
||||
case BBTYPE_CSTR:return atof(dataPtr++->field.CSTR);
|
||||
default:ThrowRuntimeException("Bad data type"); return 0;
|
||||
case BBTYPE_END:
|
||||
ThrowRuntimeException("Out of data");
|
||||
return 0;
|
||||
case BBTYPE_INT:
|
||||
return dataPtr++->field.INT;
|
||||
case BBTYPE_FLT:
|
||||
return dataPtr++->field.FLT;
|
||||
case BBTYPE_CSTR:
|
||||
return atof(dataPtr++->field.CSTR);
|
||||
default:
|
||||
ThrowRuntimeException("Bad data type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
BBStr *_bbReadStr() {
|
||||
BBStr* _bbReadStr()
|
||||
{
|
||||
switch (dataPtr->fieldType) {
|
||||
case BBTYPE_END:ThrowRuntimeException("Out of data"); return 0;
|
||||
case BBTYPE_INT:return new BBStr(itoa(dataPtr++->field.INT));
|
||||
case BBTYPE_FLT:return new BBStr(ftoa(dataPtr++->field.FLT));
|
||||
case BBTYPE_CSTR:return new BBStr(dataPtr++->field.CSTR);
|
||||
default:ThrowRuntimeException("Bad data type"); return 0;
|
||||
case BBTYPE_END:
|
||||
ThrowRuntimeException("Out of data");
|
||||
return 0;
|
||||
case BBTYPE_INT:
|
||||
return new BBStr(itoa(dataPtr++->field.INT));
|
||||
case BBTYPE_FLT:
|
||||
return new BBStr(ftoa(dataPtr++->field.FLT));
|
||||
case BBTYPE_CSTR:
|
||||
return new BBStr(dataPtr++->field.CSTR);
|
||||
default:
|
||||
ThrowRuntimeException("Bad data type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int _bbAbs(int n) {
|
||||
int _bbAbs(int n)
|
||||
{
|
||||
return n >= 0 ? n : -n;
|
||||
}
|
||||
|
||||
int _bbSgn(int n) {
|
||||
int _bbSgn(int n)
|
||||
{
|
||||
return n > 0 ? 1 : (n < 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
int _bbMod(int x, int y) {
|
||||
return x%y;
|
||||
int _bbMod(int x, int y)
|
||||
{
|
||||
return x % y;
|
||||
}
|
||||
|
||||
float _bbFAbs(float n) {
|
||||
float _bbFAbs(float n)
|
||||
{
|
||||
return n >= 0 ? n : -n;
|
||||
}
|
||||
|
||||
float _bbFSgn(float n) {
|
||||
float _bbFSgn(float n)
|
||||
{
|
||||
return n > 0 ? 1 : (n < 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
float _bbFMod(float x, float y) {
|
||||
float _bbFMod(float x, float y)
|
||||
{
|
||||
return (float)fmod(x, y);
|
||||
}
|
||||
|
||||
float _bbFPow(float x, float y) {
|
||||
float _bbFPow(float x, float y)
|
||||
{
|
||||
return (float)pow(x, y);
|
||||
}
|
||||
|
||||
void bbRuntimeStats() {
|
||||
void bbRuntimeStats()
|
||||
{
|
||||
gx_runtime->debugLog(("Active strings :" + itoa(stringCnt)).c_str());
|
||||
gx_runtime->debugLog(("Active objects :" + itoa(objCnt)).c_str());
|
||||
gx_runtime->debugLog(("Unreleased objs:" + itoa(unrelObjCnt)).c_str());
|
||||
@@ -516,7 +646,8 @@ void bbRuntimeStats() {
|
||||
*/
|
||||
}
|
||||
|
||||
bool basic_create() {
|
||||
bool basic_create()
|
||||
{
|
||||
next_handle = 0;
|
||||
// memBlks.clear();
|
||||
handle_map.clear();
|
||||
@@ -527,16 +658,18 @@ bool basic_create() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool basic_destroy() {
|
||||
while (usedStrs.next != &usedStrs) delete usedStrs.next;
|
||||
bool basic_destroy()
|
||||
{
|
||||
while (usedStrs.next != &usedStrs)
|
||||
delete usedStrs.next;
|
||||
// while( memBlks.size() ) bbFree( memBlks.back() );
|
||||
handle_map.clear();
|
||||
object_map.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
void basic_link(void(*rtSym)(const char *sym, void *pc)) {
|
||||
|
||||
void basic_link(void (*rtSym)(const char* sym, void* pc))
|
||||
{
|
||||
rtSym("_bbIntType", &_bbIntType);
|
||||
rtSym("_bbFltType", &_bbFltType);
|
||||
rtSym("_bbStrType", &_bbStrType);
|
||||
|
||||
+70
-61
@@ -2,17 +2,20 @@
|
||||
#ifndef BASIC_H
|
||||
#define BASIC_H
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
enum {
|
||||
BBTYPE_END = 0,
|
||||
BBTYPE_INT = 1, BBTYPE_FLT = 2,
|
||||
BBTYPE_STR = 3, BBTYPE_CSTR = 4,
|
||||
BBTYPE_OBJ = 5, BBTYPE_VEC = 6
|
||||
BBTYPE_INT = 1,
|
||||
BBTYPE_FLT = 2,
|
||||
BBTYPE_STR = 3,
|
||||
BBTYPE_CSTR = 4,
|
||||
BBTYPE_OBJ = 5,
|
||||
BBTYPE_VEC = 6
|
||||
};
|
||||
|
||||
#pragma pack( push,1 )
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct BBObj;
|
||||
struct BBStr;
|
||||
@@ -23,39 +26,39 @@ union BBField;
|
||||
struct BBArray;
|
||||
|
||||
struct BBObj {
|
||||
BBField *fields;
|
||||
BBObj *next, *prev;
|
||||
BBObjType *type;
|
||||
BBField* fields;
|
||||
BBObj * next, *prev;
|
||||
BBObjType* type;
|
||||
int ref_cnt;
|
||||
};
|
||||
|
||||
struct BBType {
|
||||
int type;
|
||||
BBType(int n) :type(n) {}
|
||||
BBType(int n) : type(n) {}
|
||||
};
|
||||
|
||||
struct BBObjType : public BBType {
|
||||
BBObj used, free;
|
||||
int fieldCnt;
|
||||
BBType *fieldTypes[1];
|
||||
BBType* fieldTypes[1];
|
||||
};
|
||||
|
||||
struct BBVecType : public BBType {
|
||||
int size;
|
||||
BBType *elementType;
|
||||
BBType* elementType;
|
||||
};
|
||||
|
||||
union BBField {
|
||||
int INT;
|
||||
float FLT;
|
||||
BBStr *STR;
|
||||
char *CSTR;
|
||||
BBObj *OBJ;
|
||||
void *VEC;
|
||||
BBStr* STR;
|
||||
char* CSTR;
|
||||
BBObj* OBJ;
|
||||
void* VEC;
|
||||
};
|
||||
|
||||
struct BBArray {
|
||||
void *data;
|
||||
void* data;
|
||||
int elementType, dims, scales[1];
|
||||
};
|
||||
|
||||
@@ -63,20 +66,26 @@ struct BBStr : public std::string {
|
||||
BBStr *next, *prev;
|
||||
|
||||
BBStr();
|
||||
BBStr(const char *s);
|
||||
BBStr(const char *s, int n);
|
||||
BBStr(const BBStr &s);
|
||||
BBStr(const std::string &s);
|
||||
BBStr &operator=(const char *s);
|
||||
BBStr &operator=(const BBStr &s);
|
||||
BBStr &operator=(const std::string &s);
|
||||
BBStr(const char* s);
|
||||
BBStr(const char* s, int n);
|
||||
BBStr(const BBStr& s);
|
||||
BBStr(const std::string& s);
|
||||
BBStr& operator=(const char* s);
|
||||
BBStr& operator=(const BBStr& s);
|
||||
BBStr& operator=(const std::string& s);
|
||||
~BBStr();
|
||||
|
||||
void *operator new(size_t size);
|
||||
void operator delete(void *q);
|
||||
void* operator new(size_t size);
|
||||
void operator delete(void* q);
|
||||
|
||||
void *operator new(size_t size, const char *file, int line) { return operator new(size); }
|
||||
void operator delete(void *q, const char *file, int line) { operator delete(q); }
|
||||
void* operator new(size_t size, const char* file, int line)
|
||||
{
|
||||
return operator new(size);
|
||||
}
|
||||
void operator delete(void* q, const char* file, int line)
|
||||
{
|
||||
operator delete(q);
|
||||
}
|
||||
};
|
||||
|
||||
struct BBData {
|
||||
@@ -84,7 +93,7 @@ struct BBData {
|
||||
BBField field;
|
||||
};
|
||||
|
||||
#pragma pack( pop )
|
||||
#pragma pack(pop)
|
||||
|
||||
void basic_link();
|
||||
|
||||
@@ -93,49 +102,49 @@ extern BBType _bbFltType;
|
||||
extern BBType _bbStrType;
|
||||
extern BBType _bbCStrType;
|
||||
|
||||
BBStr * _bbStrLoad(BBStr **var);
|
||||
void _bbStrRelease(BBStr *str);
|
||||
void _bbStrStore(BBStr **var, BBStr *str);
|
||||
int _bbStrCompare(BBStr *lhs, BBStr *rhs);
|
||||
BBStr* _bbStrLoad(BBStr** var);
|
||||
void _bbStrRelease(BBStr* str);
|
||||
void _bbStrStore(BBStr** var, BBStr* str);
|
||||
int _bbStrCompare(BBStr* lhs, BBStr* rhs);
|
||||
|
||||
BBStr * _bbStrConcat(BBStr *s1, BBStr *s2);
|
||||
int _bbStrToInt(BBStr *s);
|
||||
BBStr * _bbStrFromInt(int n);
|
||||
float _bbStrToFloat(BBStr *s);
|
||||
BBStr * _bbStrFromFloat(float n);
|
||||
BBStr * _bbStrConst(const char *s);
|
||||
BBStr* _bbStrConcat(BBStr* s1, BBStr* s2);
|
||||
int _bbStrToInt(BBStr* s);
|
||||
BBStr* _bbStrFromInt(int n);
|
||||
float _bbStrToFloat(BBStr* s);
|
||||
BBStr* _bbStrFromFloat(float n);
|
||||
BBStr* _bbStrConst(const char* s);
|
||||
|
||||
void _bbDimArray(BBArray *array);
|
||||
void _bbUndimArray(BBArray *array);
|
||||
void _bbDimArray(BBArray* array);
|
||||
void _bbUndimArray(BBArray* array);
|
||||
void _bbArrayBoundsEx();
|
||||
|
||||
void * _bbVecAlloc(BBVecType *type);
|
||||
void _bbVecFree(void *vec, BBVecType *type);
|
||||
void* _bbVecAlloc(BBVecType* type);
|
||||
void _bbVecFree(void* vec, BBVecType* type);
|
||||
void _bbVecBoundsEx();
|
||||
|
||||
BBObj * _bbObjNew(BBObjType *t);
|
||||
void _bbObjDelete(BBObj *obj);
|
||||
void _bbObjDeleteEach(BBObjType *type);
|
||||
void _bbObjRelease(BBObj *obj);
|
||||
void _bbObjStore(BBObj **var, BBObj *obj);
|
||||
BBObj * _bbObjNext(BBObj *obj);
|
||||
BBObj * _bbObjPrev(BBObj *obj);
|
||||
BBObj * _bbObjFirst(BBObjType *t);
|
||||
BBObj * _bbObjLast(BBObjType *t);
|
||||
void _bbObjInsBefore(BBObj *o1, BBObj *o2);
|
||||
void _bbObjInsAfter(BBObj *o1, BBObj *o2);
|
||||
int _bbObjEachFirst(BBObj **var, BBObjType *type);
|
||||
int _bbObjEachNext(BBObj **var);
|
||||
int _bbObjCompare(BBObj *o1, BBObj *o2);
|
||||
BBStr * _bbObjToStr(BBObj *obj);
|
||||
int _bbObjToHandle(BBObj *obj);
|
||||
BBObj * _bbObjFromHandle(int handle, BBObjType *type);
|
||||
BBObj* _bbObjNew(BBObjType* t);
|
||||
void _bbObjDelete(BBObj* obj);
|
||||
void _bbObjDeleteEach(BBObjType* type);
|
||||
void _bbObjRelease(BBObj* obj);
|
||||
void _bbObjStore(BBObj** var, BBObj* obj);
|
||||
BBObj* _bbObjNext(BBObj* obj);
|
||||
BBObj* _bbObjPrev(BBObj* obj);
|
||||
BBObj* _bbObjFirst(BBObjType* t);
|
||||
BBObj* _bbObjLast(BBObjType* t);
|
||||
void _bbObjInsBefore(BBObj* o1, BBObj* o2);
|
||||
void _bbObjInsAfter(BBObj* o1, BBObj* o2);
|
||||
int _bbObjEachFirst(BBObj** var, BBObjType* type);
|
||||
int _bbObjEachNext(BBObj** var);
|
||||
int _bbObjCompare(BBObj* o1, BBObj* o2);
|
||||
BBStr* _bbObjToStr(BBObj* obj);
|
||||
int _bbObjToHandle(BBObj* obj);
|
||||
BBObj* _bbObjFromHandle(int handle, BBObjType* type);
|
||||
void _bbNullObjEx();
|
||||
|
||||
void _bbRestore(BBData *data);
|
||||
void _bbRestore(BBData* data);
|
||||
int _bbReadInt();
|
||||
float _bbReadFloat();
|
||||
BBStr * _bbReadStr();
|
||||
BBStr* _bbReadStr();
|
||||
|
||||
int _bbAbs(int n);
|
||||
int _bbSgn(int n);
|
||||
|
||||
+42
-41
@@ -1,19 +1,22 @@
|
||||
|
||||
enum{
|
||||
BBTYPE_END=0,
|
||||
BBTYPE_INT=1,BBTYPE_FLOAT=2,
|
||||
BBTYPE_STRING=3,BBTYPE_CSTR=4,
|
||||
BBTYPE_OBJECT=5,BBTYPE_VECTOR=6
|
||||
enum {
|
||||
BBTYPE_END = 0,
|
||||
BBTYPE_INT = 1,
|
||||
BBTYPE_FLOAT = 2,
|
||||
BBTYPE_STRING = 3,
|
||||
BBTYPE_CSTR = 4,
|
||||
BBTYPE_OBJECT = 5,
|
||||
BBTYPE_VECTOR = 6
|
||||
};
|
||||
|
||||
typedef int bbInt;
|
||||
typedef float bbFloat;
|
||||
typedef bbStringhandle *bbString;
|
||||
typedef bbObjectHandle *bbObject;
|
||||
typedef bbVectorHandle *bbVector;
|
||||
typedef const char * bbCStr;
|
||||
typedef bbStringhandle* bbString;
|
||||
typedef bbObjectHandle* bbObject;
|
||||
typedef bbVectorHandle* bbVector;
|
||||
typedef const char* bbCStr;
|
||||
|
||||
union bbValue{
|
||||
union bbValue {
|
||||
bbInt INT;
|
||||
bbFloat FLOAT;
|
||||
bbString STRING;
|
||||
@@ -22,61 +25,59 @@ union bbValue{
|
||||
bbCStr CSTR;
|
||||
};
|
||||
|
||||
struct bbType{
|
||||
struct bbType {
|
||||
int id;
|
||||
bbType( int n ):id(n(){}
|
||||
};
|
||||
|
||||
struct bbInstance{
|
||||
struct bbInstance {
|
||||
bbValue value;
|
||||
};
|
||||
|
||||
struct bbHandle{
|
||||
bbInstance *instance;
|
||||
struct bbHandle {
|
||||
bbInstance* instance;
|
||||
int ref_cnt;
|
||||
bbType *type;
|
||||
bbType* type;
|
||||
};
|
||||
|
||||
struct bbEnviron{
|
||||
bbVector *variables;
|
||||
struct bbEnviron {
|
||||
bbVector* variables;
|
||||
};
|
||||
|
||||
struct bbIntType : public bbType{
|
||||
bbInt():bbType( BBTYPE_INT ){}
|
||||
struct bbIntType : public bbType {
|
||||
bbInt() : bbType(BBTYPE_INT) {}
|
||||
};
|
||||
|
||||
struct bbFloatType : public bbType{
|
||||
bbFloat():bbType( BBTYPE_FLOAT ){}
|
||||
struct bbFloatType : public bbType {
|
||||
bbFloat() : bbType(BBTYPE_FLOAT) {}
|
||||
};
|
||||
|
||||
struct bbCStrType : public bbType{
|
||||
bbCStrType():bbType( BBTYPE_CSTR ){}
|
||||
struct bbCStrType : public bbType {
|
||||
bbCStrType() : bbType(BBTYPE_CSTR) {}
|
||||
};
|
||||
|
||||
struct bbStringType : public bbType{
|
||||
bbStringType():bbType( BBTYPE_STRING ){}
|
||||
struct bbStringType : public bbType {
|
||||
bbStringType() : bbType(BBTYPE_STRING) {}
|
||||
};
|
||||
|
||||
struct bbVectorType : public bbType{
|
||||
bbType *element_type;
|
||||
bbVectorType( bbType *e ):bbType( BBTYPE_VECTOR ),element_type( e ){}
|
||||
struct bbVectorType : public bbType {
|
||||
bbType* element_type;
|
||||
bbVectorType(bbType* e) : bbType(BBTYPE_VECTOR), element_type(e) {}
|
||||
}
|
||||
|
||||
struct bbObjectType : public bbType{
|
||||
bbEnviron *environ;
|
||||
bbObject *first_used,*last_used;
|
||||
bbObject *first_free,*last_free;
|
||||
bbObjectType( bbEnviron *e ):bbType( BBTYPE_OBJECT ),environ( e ){}
|
||||
struct bbObjectType : public bbType {
|
||||
bbEnviron* environ;
|
||||
bbObject * first_used, *last_used;
|
||||
bbObject * first_free, *last_free;
|
||||
bbObjectType(bbEnviron* e) : bbType(BBTYPE_OBJECT), environ(e) {}
|
||||
};
|
||||
|
||||
struct bbStringHandle : public bbHandle{
|
||||
struct bbStringHandle : public bbHandle {};
|
||||
|
||||
struct bbObjectHandle : public bbHandle {
|
||||
bbObject *next, *prev;
|
||||
};
|
||||
|
||||
struct bbObjectHandle : public bbHandle{
|
||||
bbObject *next,*prev;
|
||||
};
|
||||
struct bbVectorHandle : public bbHandle {};
|
||||
|
||||
struct bbVectorHandle : public bbHandle{
|
||||
};
|
||||
|
||||
void assign( bbHandleVariable dest,bbHandle src );
|
||||
void assign(bbHandleVariable dest, bbHandle src);
|
||||
|
||||
+122
-83
@@ -1,138 +1,177 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "bbaudio.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
gxAudio *gx_audio;
|
||||
gxAudio* gx_audio;
|
||||
|
||||
static inline void debugSound( gxSound *s ){
|
||||
if( debug ){
|
||||
if( !gx_audio->verifySound( s ) ) ThrowRuntimeException( "Sound does not exist" );
|
||||
static inline void debugSound(gxSound* s)
|
||||
{
|
||||
if (debug) {
|
||||
if (!gx_audio->verifySound(s))
|
||||
ThrowRuntimeException("Sound does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
static gxSound *loadSound( BBStr *f,bool use_3d ){
|
||||
string t=*f;delete f;
|
||||
return gx_audio ? gx_audio->loadSound( t,use_3d ) : 0;
|
||||
static gxSound* loadSound(BBStr* f, bool use_3d)
|
||||
{
|
||||
string t = *f;
|
||||
delete f;
|
||||
return gx_audio ? gx_audio->loadSound(t, use_3d) : 0;
|
||||
}
|
||||
|
||||
static gxChannel *playMusic( BBStr *f,bool use_3d ){
|
||||
string t=*f;delete f;
|
||||
return gx_audio ? gx_audio->playFile( t,use_3d ) : 0;
|
||||
static gxChannel* playMusic(BBStr* f, bool use_3d)
|
||||
{
|
||||
string t = *f;
|
||||
delete f;
|
||||
return gx_audio ? gx_audio->playFile(t, use_3d) : 0;
|
||||
}
|
||||
|
||||
gxSound *bbLoadSound( BBStr *f ){
|
||||
return loadSound( f,false );
|
||||
gxSound* bbLoadSound(BBStr* f)
|
||||
{
|
||||
return loadSound(f, false);
|
||||
}
|
||||
|
||||
void bbFreeSound( gxSound *sound ){
|
||||
if( !sound ) return;
|
||||
debugSound( sound );
|
||||
gx_audio->freeSound( sound );
|
||||
void bbFreeSound(gxSound* sound)
|
||||
{
|
||||
if (!sound)
|
||||
return;
|
||||
debugSound(sound);
|
||||
gx_audio->freeSound(sound);
|
||||
}
|
||||
|
||||
void bbLoopSound( gxSound *sound ){
|
||||
if( !sound ) return;
|
||||
debugSound( sound );
|
||||
sound->setLoop( true );
|
||||
void bbLoopSound(gxSound* sound)
|
||||
{
|
||||
if (!sound)
|
||||
return;
|
||||
debugSound(sound);
|
||||
sound->setLoop(true);
|
||||
}
|
||||
|
||||
void bbSoundPitch( gxSound *sound,int pitch ){
|
||||
if( !sound ) return;
|
||||
debugSound( sound );
|
||||
sound->setPitch( pitch );
|
||||
void bbSoundPitch(gxSound* sound, int pitch)
|
||||
{
|
||||
if (!sound)
|
||||
return;
|
||||
debugSound(sound);
|
||||
sound->setPitch(pitch);
|
||||
}
|
||||
|
||||
void bbSoundVolume( gxSound *sound,float volume ){
|
||||
if( !sound ) return;
|
||||
debugSound( sound );
|
||||
sound->setVolume( volume );
|
||||
void bbSoundVolume(gxSound* sound, float volume)
|
||||
{
|
||||
if (!sound)
|
||||
return;
|
||||
debugSound(sound);
|
||||
sound->setVolume(volume);
|
||||
}
|
||||
|
||||
void bbSoundPan( gxSound *sound,float pan ){
|
||||
if( !sound ) return;
|
||||
debugSound( sound );
|
||||
sound->setPan( pan );
|
||||
void bbSoundPan(gxSound* sound, float pan)
|
||||
{
|
||||
if (!sound)
|
||||
return;
|
||||
debugSound(sound);
|
||||
sound->setPan(pan);
|
||||
}
|
||||
|
||||
gxChannel *bbPlaySound( gxSound *sound ){
|
||||
if( !sound ) return 0;
|
||||
debugSound( sound );
|
||||
gxChannel* bbPlaySound(gxSound* sound)
|
||||
{
|
||||
if (!sound)
|
||||
return 0;
|
||||
debugSound(sound);
|
||||
return sound->play();
|
||||
}
|
||||
|
||||
gxChannel *bbPlayMusic( BBStr *f ){
|
||||
return playMusic( f,false );
|
||||
gxChannel* bbPlayMusic(BBStr* f)
|
||||
{
|
||||
return playMusic(f, false);
|
||||
}
|
||||
|
||||
gxChannel *bbPlayCDTrack( int track,int mode ){
|
||||
return gx_audio ? gx_audio->playCDTrack( track,mode ) : 0;
|
||||
gxChannel* bbPlayCDTrack(int track, int mode)
|
||||
{
|
||||
return gx_audio ? gx_audio->playCDTrack(track, mode) : 0;
|
||||
}
|
||||
|
||||
void bbStopChannel( gxChannel *channel ){
|
||||
if( !channel ) return;
|
||||
void bbStopChannel(gxChannel* channel)
|
||||
{
|
||||
if (!channel)
|
||||
return;
|
||||
channel->stop();
|
||||
}
|
||||
|
||||
void bbPauseChannel( gxChannel *channel ){
|
||||
if( !channel ) return;
|
||||
channel->setPaused( true );
|
||||
void bbPauseChannel(gxChannel* channel)
|
||||
{
|
||||
if (!channel)
|
||||
return;
|
||||
channel->setPaused(true);
|
||||
}
|
||||
|
||||
void bbResumeChannel( gxChannel *channel ){
|
||||
if( !channel ) return;
|
||||
channel->setPaused( false );
|
||||
void bbResumeChannel(gxChannel* channel)
|
||||
{
|
||||
if (!channel)
|
||||
return;
|
||||
channel->setPaused(false);
|
||||
}
|
||||
|
||||
void bbChannelPitch( gxChannel *channel,int pitch ){
|
||||
if( !channel ) return;
|
||||
channel->setPitch( pitch );
|
||||
void bbChannelPitch(gxChannel* channel, int pitch)
|
||||
{
|
||||
if (!channel)
|
||||
return;
|
||||
channel->setPitch(pitch);
|
||||
}
|
||||
|
||||
void bbChannelVolume( gxChannel *channel,float volume ){
|
||||
if( !channel ) return;
|
||||
channel->setVolume( volume );
|
||||
void bbChannelVolume(gxChannel* channel, float volume)
|
||||
{
|
||||
if (!channel)
|
||||
return;
|
||||
channel->setVolume(volume);
|
||||
}
|
||||
|
||||
void bbChannelPan( gxChannel *channel,float pan ){
|
||||
if( !channel ) return;
|
||||
channel->setPan( pan );
|
||||
void bbChannelPan(gxChannel* channel, float pan)
|
||||
{
|
||||
if (!channel)
|
||||
return;
|
||||
channel->setPan(pan);
|
||||
}
|
||||
|
||||
int bbChannelPlaying( gxChannel *channel ){
|
||||
int bbChannelPlaying(gxChannel* channel)
|
||||
{
|
||||
return channel ? channel->isPlaying() : 0;
|
||||
}
|
||||
|
||||
gxSound *bbLoad3DSound( BBStr *f ){
|
||||
return loadSound( f,true );
|
||||
gxSound* bbLoad3DSound(BBStr* f)
|
||||
{
|
||||
return loadSound(f, true);
|
||||
}
|
||||
|
||||
bool audio_create(){
|
||||
gx_audio=gx_runtime->openAudio( 0 );
|
||||
bool audio_create()
|
||||
{
|
||||
gx_audio = gx_runtime->openAudio(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool audio_destroy(){
|
||||
if( gx_audio ) gx_runtime->closeAudio( gx_audio );
|
||||
gx_audio=0;
|
||||
bool audio_destroy()
|
||||
{
|
||||
if (gx_audio)
|
||||
gx_runtime->closeAudio(gx_audio);
|
||||
gx_audio = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void audio_link( void(*rtSym)(const char*,void*) ){
|
||||
rtSym( "%LoadSound$filename",bbLoadSound );
|
||||
rtSym( "FreeSound%sound",bbFreeSound );
|
||||
rtSym( "LoopSound%sound",bbLoopSound );
|
||||
rtSym( "SoundPitch%sound%pitch",bbSoundPitch );
|
||||
rtSym( "SoundVolume%sound#volume",bbSoundVolume );
|
||||
rtSym( "SoundPan%sound#pan",bbSoundPan );
|
||||
rtSym( "%PlaySound%sound",bbPlaySound );
|
||||
rtSym( "%PlayMusic$midifile",bbPlayMusic );
|
||||
rtSym( "%PlayCDTrack%track%mode=1",bbPlayCDTrack );
|
||||
rtSym( "StopChannel%channel",bbStopChannel );
|
||||
rtSym( "PauseChannel%channel",bbPauseChannel );
|
||||
rtSym( "ResumeChannel%channel",bbResumeChannel );
|
||||
rtSym( "ChannelPitch%channel%pitch",bbChannelPitch );
|
||||
rtSym( "ChannelVolume%channel#volume",bbChannelVolume );
|
||||
rtSym( "ChannelPan%channel#pan",bbChannelPan );
|
||||
rtSym( "%ChannelPlaying%channel",bbChannelPlaying );
|
||||
rtSym( "%Load3DSound$filename",bbLoad3DSound );
|
||||
void audio_link(void (*rtSym)(const char*, void*))
|
||||
{
|
||||
rtSym("%LoadSound$filename", bbLoadSound);
|
||||
rtSym("FreeSound%sound", bbFreeSound);
|
||||
rtSym("LoopSound%sound", bbLoopSound);
|
||||
rtSym("SoundPitch%sound%pitch", bbSoundPitch);
|
||||
rtSym("SoundVolume%sound#volume", bbSoundVolume);
|
||||
rtSym("SoundPan%sound#pan", bbSoundPan);
|
||||
rtSym("%PlaySound%sound", bbPlaySound);
|
||||
rtSym("%PlayMusic$midifile", bbPlayMusic);
|
||||
rtSym("%PlayCDTrack%track%mode=1", bbPlayCDTrack);
|
||||
rtSym("StopChannel%channel", bbStopChannel);
|
||||
rtSym("PauseChannel%channel", bbPauseChannel);
|
||||
rtSym("ResumeChannel%channel", bbResumeChannel);
|
||||
rtSym("ChannelPitch%channel%pitch", bbChannelPitch);
|
||||
rtSym("ChannelVolume%channel#volume", bbChannelVolume);
|
||||
rtSym("ChannelPan%channel#pan", bbChannelPan);
|
||||
rtSym("%ChannelPlaying%channel", bbChannelPlaying);
|
||||
rtSym("%Load3DSound$filename", bbLoad3DSound);
|
||||
}
|
||||
|
||||
+18
-19
@@ -3,26 +3,25 @@
|
||||
#define BBAUDIO_H
|
||||
|
||||
#include "bbsys.hpp"
|
||||
#include "../gxruntime/gxaudio.hpp"
|
||||
#include "gxaudio.hpp"
|
||||
|
||||
extern gxAudio *gx_audio;
|
||||
extern gxAudio* gx_audio;
|
||||
|
||||
gxSound * bbLoadSound( BBStr *file );
|
||||
void bbFreeSound( gxSound *sound );
|
||||
gxChannel * bbPlaySound( gxSound *sound );
|
||||
void bbLoopSound( gxSound *sound );
|
||||
void bbSoundPitch( gxSound *sound,int pitch );
|
||||
void bbSoundVolume( gxSound *sound,float volume );
|
||||
void bbSoundPan( gxSound *sound,float pan );
|
||||
gxChannel * bbPlayMusic( BBStr *s );
|
||||
gxChannel * bbPlayCDTrack( int track,int mode );
|
||||
void bbStopChannel( gxChannel *channel );
|
||||
void bbPauseChannel( gxChannel *channel );
|
||||
void bbResumeChannel( gxChannel *channel );
|
||||
void bbChannelPitch( gxChannel *channel,int pitch );
|
||||
void bbChannelVolume( gxChannel *channel,float volume );
|
||||
void bbChannelPan( gxChannel *channel,float pan );
|
||||
int bbChannelPlaying( gxChannel *channel );
|
||||
gxSound* bbLoadSound(BBStr* file);
|
||||
void bbFreeSound(gxSound* sound);
|
||||
gxChannel* bbPlaySound(gxSound* sound);
|
||||
void bbLoopSound(gxSound* sound);
|
||||
void bbSoundPitch(gxSound* sound, int pitch);
|
||||
void bbSoundVolume(gxSound* sound, float volume);
|
||||
void bbSoundPan(gxSound* sound, float pan);
|
||||
gxChannel* bbPlayMusic(BBStr* s);
|
||||
gxChannel* bbPlayCDTrack(int track, int mode);
|
||||
void bbStopChannel(gxChannel* channel);
|
||||
void bbPauseChannel(gxChannel* channel);
|
||||
void bbResumeChannel(gxChannel* channel);
|
||||
void bbChannelPitch(gxChannel* channel, int pitch);
|
||||
void bbChannelVolume(gxChannel* channel, float volume);
|
||||
void bbChannelPan(gxChannel* channel, float pan);
|
||||
int bbChannelPlaying(gxChannel* channel);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+156
-123
@@ -1,170 +1,203 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "bbbank.hpp"
|
||||
#include "bbstream.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
struct bbBank{
|
||||
char *data;
|
||||
int size,capacity;
|
||||
struct bbBank {
|
||||
char* data;
|
||||
int size, capacity;
|
||||
|
||||
bbBank( int sz ):size(sz){
|
||||
capacity=(size+15)&~15;
|
||||
data=new char[capacity];
|
||||
memset( data,0,size );
|
||||
bbBank(int sz) : size(sz)
|
||||
{
|
||||
capacity = (size + 15) & ~15;
|
||||
data = new char[capacity];
|
||||
memset(data, 0, size);
|
||||
}
|
||||
virtual ~bbBank(){
|
||||
virtual ~bbBank()
|
||||
{
|
||||
delete[] data;
|
||||
}
|
||||
void resize( int n ){
|
||||
if( n>size ){
|
||||
if( n>capacity ){
|
||||
capacity=capacity*3/2;
|
||||
if( n>capacity ) capacity=n;
|
||||
capacity=(capacity+15)&~15;
|
||||
char *p=new char[capacity];
|
||||
memcpy( p,data,size );
|
||||
void resize(int n)
|
||||
{
|
||||
if (n > size) {
|
||||
if (n > capacity) {
|
||||
capacity = capacity * 3 / 2;
|
||||
if (n > capacity)
|
||||
capacity = n;
|
||||
capacity = (capacity + 15) & ~15;
|
||||
char* p = new char[capacity];
|
||||
memcpy(p, data, size);
|
||||
delete[] data;
|
||||
data=p;
|
||||
}else memset( data+size,0,n-size );
|
||||
data = p;
|
||||
} else
|
||||
memset(data + size, 0, n - size);
|
||||
}
|
||||
size=n;
|
||||
size = n;
|
||||
}
|
||||
};
|
||||
|
||||
static set<bbBank*> bank_set;
|
||||
|
||||
static inline void debugBank( bbBank *b ){
|
||||
if( debug ){
|
||||
if( !bank_set.count( b ) ) ThrowRuntimeException( "bbBank does not exist" );
|
||||
static inline void debugBank(bbBank* b)
|
||||
{
|
||||
if (debug) {
|
||||
if (!bank_set.count(b))
|
||||
ThrowRuntimeException("bbBank does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void debugBank( bbBank *b,int offset ){
|
||||
if( debug ){
|
||||
debugBank( b );
|
||||
if( offset>=b->size ) ThrowRuntimeException( "Offset out of range" );
|
||||
static inline void debugBank(bbBank* b, int offset)
|
||||
{
|
||||
if (debug) {
|
||||
debugBank(b);
|
||||
if (offset >= b->size)
|
||||
ThrowRuntimeException("Offset out of range");
|
||||
}
|
||||
}
|
||||
|
||||
bbBank *bbCreateBank( int size ){
|
||||
bbBank *b=new bbBank( size );
|
||||
bank_set.insert( b );
|
||||
bbBank* bbCreateBank(int size)
|
||||
{
|
||||
bbBank* b = new bbBank(size);
|
||||
bank_set.insert(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
void bbFreeBank( bbBank *b ){
|
||||
if( bank_set.erase( b ) ) delete b;
|
||||
void bbFreeBank(bbBank* b)
|
||||
{
|
||||
if (bank_set.erase(b))
|
||||
delete b;
|
||||
}
|
||||
|
||||
int bbBankSize( bbBank *b ){
|
||||
debugBank( b );
|
||||
int bbBankSize(bbBank* b)
|
||||
{
|
||||
debugBank(b);
|
||||
return b->size;
|
||||
}
|
||||
|
||||
void bbResizeBank( bbBank *b,int size ){
|
||||
debugBank( b );
|
||||
b->resize( size );
|
||||
void bbResizeBank(bbBank* b, int size)
|
||||
{
|
||||
debugBank(b);
|
||||
b->resize(size);
|
||||
}
|
||||
|
||||
void bbCopyBank( bbBank *src,int src_p,bbBank *dest,int dest_p,int count ){
|
||||
if( debug ){ debugBank( src,src_p+count-1 );debugBank( dest,dest_p+count-1 ); }
|
||||
memmove( dest->data+dest_p,src->data+src_p,count );
|
||||
}
|
||||
|
||||
int bbPeekByte( bbBank *b,int offset ){
|
||||
debugBank( b,offset );
|
||||
return *(unsigned char*)(b->data+offset);
|
||||
}
|
||||
|
||||
int bbPeekShort( bbBank *b,int offset ){
|
||||
debugBank( b,offset+1 );
|
||||
return *(unsigned short*)(b->data+offset);
|
||||
}
|
||||
|
||||
int bbPeekInt( bbBank *b,int offset ){
|
||||
debugBank( b,offset+3 );
|
||||
return *(int*)(b->data+offset);
|
||||
}
|
||||
|
||||
float bbPeekFloat( bbBank *b,int offset ){
|
||||
debugBank( b,offset+3 );
|
||||
return *(float*)(b->data+offset);
|
||||
}
|
||||
|
||||
void bbPokeByte( bbBank *b,int offset,int value ){
|
||||
debugBank( b,offset );
|
||||
*(char*)(b->data+offset)=value;
|
||||
}
|
||||
|
||||
void bbPokeShort( bbBank *b,int offset,int value ){
|
||||
debugBank( b,offset );
|
||||
*(unsigned short*)(b->data+offset)=value;
|
||||
}
|
||||
|
||||
void bbPokeInt( bbBank *b,int offset,int value ){
|
||||
debugBank( b,offset );
|
||||
*(int*)(b->data+offset)=value;
|
||||
}
|
||||
|
||||
void bbPokeFloat( bbBank *b,int offset,float value ){
|
||||
debugBank( b,offset );
|
||||
*(float*)(b->data+offset)=value;
|
||||
}
|
||||
|
||||
int bbReadBytes( bbBank *b,bbStream *s,int offset,int count ){
|
||||
if( debug ){
|
||||
debugBank( b,offset+count-1 );
|
||||
debugStream( s );
|
||||
void bbCopyBank(bbBank* src, int src_p, bbBank* dest, int dest_p, int count)
|
||||
{
|
||||
if (debug) {
|
||||
debugBank(src, src_p + count - 1);
|
||||
debugBank(dest, dest_p + count - 1);
|
||||
}
|
||||
return s->read( b->data+offset,count );
|
||||
memmove(dest->data + dest_p, src->data + src_p, count);
|
||||
}
|
||||
|
||||
int bbWriteBytes( bbBank *b,bbStream *s,int offset,int count ){
|
||||
if( debug ){
|
||||
debugBank( b,offset+count-1 );
|
||||
debugStream( s );
|
||||
}
|
||||
return s->write( b->data+offset,count );
|
||||
int bbPeekByte(bbBank* b, int offset)
|
||||
{
|
||||
debugBank(b, offset);
|
||||
return *(unsigned char*)(b->data + offset);
|
||||
}
|
||||
|
||||
int bbCallDLL( BBStr *dll,BBStr *fun,bbBank *in,bbBank *out ){
|
||||
if( debug ){
|
||||
if( in ) debugBank( in );
|
||||
if( out ) debugBank( out );
|
||||
int bbPeekShort(bbBank* b, int offset)
|
||||
{
|
||||
debugBank(b, offset + 1);
|
||||
return *(unsigned short*)(b->data + offset);
|
||||
}
|
||||
|
||||
int bbPeekInt(bbBank* b, int offset)
|
||||
{
|
||||
debugBank(b, offset + 3);
|
||||
return *(int*)(b->data + offset);
|
||||
}
|
||||
|
||||
float bbPeekFloat(bbBank* b, int offset)
|
||||
{
|
||||
debugBank(b, offset + 3);
|
||||
return *(float*)(b->data + offset);
|
||||
}
|
||||
|
||||
void bbPokeByte(bbBank* b, int offset, int value)
|
||||
{
|
||||
debugBank(b, offset);
|
||||
*(char*)(b->data + offset) = value;
|
||||
}
|
||||
|
||||
void bbPokeShort(bbBank* b, int offset, int value)
|
||||
{
|
||||
debugBank(b, offset);
|
||||
*(unsigned short*)(b->data + offset) = value;
|
||||
}
|
||||
|
||||
void bbPokeInt(bbBank* b, int offset, int value)
|
||||
{
|
||||
debugBank(b, offset);
|
||||
*(int*)(b->data + offset) = value;
|
||||
}
|
||||
|
||||
void bbPokeFloat(bbBank* b, int offset, float value)
|
||||
{
|
||||
debugBank(b, offset);
|
||||
*(float*)(b->data + offset) = value;
|
||||
}
|
||||
|
||||
int bbReadBytes(bbBank* b, bbStream* s, int offset, int count)
|
||||
{
|
||||
if (debug) {
|
||||
debugBank(b, offset + count - 1);
|
||||
debugStream(s);
|
||||
}
|
||||
int t=gx_runtime->callDll( *dll,*fun,
|
||||
in ? in->data : 0,in ? in->size : 0,
|
||||
out ? out->data : 0,out ? out->size : 0 );
|
||||
delete dll;delete fun;
|
||||
return s->read(b->data + offset, count);
|
||||
}
|
||||
|
||||
int bbWriteBytes(bbBank* b, bbStream* s, int offset, int count)
|
||||
{
|
||||
if (debug) {
|
||||
debugBank(b, offset + count - 1);
|
||||
debugStream(s);
|
||||
}
|
||||
return s->write(b->data + offset, count);
|
||||
}
|
||||
|
||||
int bbCallDLL(BBStr* dll, BBStr* fun, bbBank* in, bbBank* out)
|
||||
{
|
||||
if (debug) {
|
||||
if (in)
|
||||
debugBank(in);
|
||||
if (out)
|
||||
debugBank(out);
|
||||
}
|
||||
int t =
|
||||
gx_runtime->callDll(*dll, *fun, in ? in->data : 0, in ? in->size : 0, out ? out->data : 0, out ? out->size : 0);
|
||||
delete dll;
|
||||
delete fun;
|
||||
return t;
|
||||
}
|
||||
|
||||
bool bank_create(){
|
||||
bool bank_create()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bank_destroy(){
|
||||
while( bank_set.size() ) bbFreeBank( *bank_set.begin() );
|
||||
bool bank_destroy()
|
||||
{
|
||||
while (bank_set.size())
|
||||
bbFreeBank(*bank_set.begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
void bank_link( void(*rtSym)(const char*,void*) ){
|
||||
rtSym( "%CreateBank%size=0",bbCreateBank );
|
||||
rtSym( "FreeBank%bank",bbFreeBank );
|
||||
rtSym( "%BankSize%bank",bbBankSize );
|
||||
rtSym( "ResizeBank%bank%size",bbResizeBank );
|
||||
rtSym( "CopyBank%src_bank%src_offset%dest_bank%dest_offset%count",bbCopyBank );
|
||||
rtSym( "%PeekByte%bank%offset",bbPeekByte );
|
||||
rtSym( "%PeekShort%bank%offset",bbPeekShort );
|
||||
rtSym( "%PeekInt%bank%offset",bbPeekInt );
|
||||
rtSym( "#PeekFloat%bank%offset",bbPeekFloat );
|
||||
rtSym( "PokeByte%bank%offset%value",bbPokeByte );
|
||||
rtSym( "PokeShort%bank%offset%value",bbPokeShort );
|
||||
rtSym( "PokeInt%bank%offset%value",bbPokeInt );
|
||||
rtSym( "PokeFloat%bank%offset#value",bbPokeFloat );
|
||||
rtSym( "%ReadBytes%bank%file%offset%count",bbReadBytes );
|
||||
rtSym( "%WriteBytes%bank%file%offset%count",bbWriteBytes );
|
||||
rtSym( "%CallDLL$dll_name$func_name%in_bank=0%out_bank=0",bbCallDLL );
|
||||
void bank_link(void (*rtSym)(const char*, void*))
|
||||
{
|
||||
rtSym("%CreateBank%size=0", bbCreateBank);
|
||||
rtSym("FreeBank%bank", bbFreeBank);
|
||||
rtSym("%BankSize%bank", bbBankSize);
|
||||
rtSym("ResizeBank%bank%size", bbResizeBank);
|
||||
rtSym("CopyBank%src_bank%src_offset%dest_bank%dest_offset%count", bbCopyBank);
|
||||
rtSym("%PeekByte%bank%offset", bbPeekByte);
|
||||
rtSym("%PeekShort%bank%offset", bbPeekShort);
|
||||
rtSym("%PeekInt%bank%offset", bbPeekInt);
|
||||
rtSym("#PeekFloat%bank%offset", bbPeekFloat);
|
||||
rtSym("PokeByte%bank%offset%value", bbPokeByte);
|
||||
rtSym("PokeShort%bank%offset%value", bbPokeShort);
|
||||
rtSym("PokeInt%bank%offset%value", bbPokeInt);
|
||||
rtSym("PokeFloat%bank%offset#value", bbPokeFloat);
|
||||
rtSym("%ReadBytes%bank%file%offset%count", bbReadBytes);
|
||||
rtSym("%WriteBytes%bank%file%offset%count", bbWriteBytes);
|
||||
rtSym("%CallDLL$dll_name$func_name%in_bank=0%out_bank=0", bbCallDLL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+976
-535
File diff suppressed because it is too large
Load Diff
@@ -3,9 +3,8 @@
|
||||
#define BBBLITZ3D_H
|
||||
|
||||
#include "bbsys.hpp"
|
||||
#include "../gxruntime/gxscene.hpp"
|
||||
#include "gxscene.hpp"
|
||||
|
||||
extern gxScene *gx_scene;
|
||||
extern gxScene* gx_scene;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+127
-93
@@ -1,170 +1,204 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "bbfilesystem.hpp"
|
||||
#include "bbstream.hpp"
|
||||
#include <fstream>
|
||||
#include "bbstream.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
gxFileSystem *gx_filesys;
|
||||
gxFileSystem* gx_filesys;
|
||||
|
||||
struct bbFile : public bbStream{
|
||||
filebuf *buf;
|
||||
bbFile( filebuf *f ):buf(f){
|
||||
}
|
||||
~bbFile(){
|
||||
struct bbFile : public bbStream {
|
||||
filebuf* buf;
|
||||
bbFile(filebuf* f) : buf(f) {}
|
||||
~bbFile()
|
||||
{
|
||||
delete buf;
|
||||
}
|
||||
int read( char *buff,int size ){
|
||||
return buf->sgetn( (char*)buff,size );
|
||||
int read(char* buff, int size)
|
||||
{
|
||||
return buf->sgetn((char*)buff, size);
|
||||
}
|
||||
int write( const char *buff,int size ){
|
||||
return buf->sputn( (char*)buff,size );
|
||||
int write(const char* buff, int size)
|
||||
{
|
||||
return buf->sputn((char*)buff, size);
|
||||
}
|
||||
int avail(){
|
||||
int avail()
|
||||
{
|
||||
return buf->in_avail();
|
||||
}
|
||||
int eof(){
|
||||
return buf->sgetc()==EOF;
|
||||
int eof()
|
||||
{
|
||||
return buf->sgetc() == EOF;
|
||||
}
|
||||
};
|
||||
|
||||
static set<bbFile*> file_set;
|
||||
|
||||
static inline void debugFile( bbFile *f ){
|
||||
if( debug ){
|
||||
if( !file_set.count( f ) ) ThrowRuntimeException( "File does not exist" );
|
||||
static inline void debugFile(bbFile* f)
|
||||
{
|
||||
if (debug) {
|
||||
if (!file_set.count(f))
|
||||
ThrowRuntimeException("File does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void debugDir( gxDir *d ){
|
||||
if( debug ){
|
||||
if( !gx_filesys->verifyDir( d ) ) ThrowRuntimeException( "Directory does not exist" );
|
||||
static inline void debugDir(gxDir* d)
|
||||
{
|
||||
if (debug) {
|
||||
if (!gx_filesys->verifyDir(d))
|
||||
ThrowRuntimeException("Directory does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
static bbFile *open( BBStr *f,int n ){
|
||||
string t=*f;
|
||||
filebuf *buf=new filebuf();
|
||||
if( buf->open( t.c_str(),n|ios_base::binary ) ){
|
||||
bbFile *f=new bbFile( buf );
|
||||
file_set.insert( f );
|
||||
return f;
|
||||
static bbFile* open(BBStr* file_path, int flags)
|
||||
{
|
||||
string t = *file_path;
|
||||
filebuf* buf = new filebuf();
|
||||
if (buf->open(t.c_str(), flags | ios_base::binary)) {
|
||||
bbFile* file = new bbFile(buf);
|
||||
file_set.insert(file);
|
||||
return file;
|
||||
}
|
||||
delete buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bbFile *bbReadFile( BBStr *f ){
|
||||
return open( f,ios_base::in );
|
||||
bbFile* bbReadFile(BBStr* f)
|
||||
{
|
||||
return open(f, ios_base::in);
|
||||
}
|
||||
|
||||
bbFile *bbWriteFile( BBStr *f ){
|
||||
return open( f,ios_base::out|ios_base::trunc );
|
||||
bbFile* bbWriteFile(BBStr* f)
|
||||
{
|
||||
return open(f, ios_base::out | ios_base::trunc);
|
||||
}
|
||||
|
||||
bbFile *bbOpenFile( BBStr *f ){
|
||||
return open( f,ios_base::in|ios_base::out );
|
||||
bbFile* bbOpenFile(BBStr* f)
|
||||
{
|
||||
return open(f, ios_base::in | ios_base::out);
|
||||
}
|
||||
|
||||
void bbCloseFile( bbFile *f ){
|
||||
debugFile( f );
|
||||
file_set.erase( f );
|
||||
void bbCloseFile(bbFile* f)
|
||||
{
|
||||
debugFile(f);
|
||||
file_set.erase(f);
|
||||
delete f;
|
||||
}
|
||||
|
||||
int bbFilePos( bbFile *f ){
|
||||
return f->buf->pubseekoff( 0,ios_base::cur );
|
||||
int bbFilePos(bbFile* f)
|
||||
{
|
||||
return f->buf->pubseekoff(0, ios_base::cur);
|
||||
}
|
||||
|
||||
int bbSeekFile( bbFile *f,int pos ){
|
||||
return f->buf->pubseekoff( pos,ios_base::beg );
|
||||
int bbSeekFile(bbFile* f, int pos)
|
||||
{
|
||||
return f->buf->pubseekoff(pos, ios_base::beg);
|
||||
}
|
||||
|
||||
gxDir *bbReadDir( BBStr *d ){
|
||||
string t=*d;delete d;
|
||||
return gx_filesys->openDir( t,0 );
|
||||
gxDir* bbReadDir(BBStr* d)
|
||||
{
|
||||
string t = *d;
|
||||
delete d;
|
||||
return gx_filesys->openDir(t, 0);
|
||||
}
|
||||
|
||||
void bbCloseDir( gxDir *d ){
|
||||
gx_filesys->closeDir( d );
|
||||
void bbCloseDir(gxDir* d)
|
||||
{
|
||||
gx_filesys->closeDir(d);
|
||||
}
|
||||
|
||||
BBStr *bbNextFile( gxDir *d ){
|
||||
debugDir( d );
|
||||
return new BBStr( d->getNextFile() );
|
||||
BBStr* bbNextFile(gxDir* d)
|
||||
{
|
||||
debugDir(d);
|
||||
return new BBStr(d->getNextFile());
|
||||
}
|
||||
|
||||
BBStr *bbCurrentDir(){
|
||||
return new BBStr( gx_filesys->getCurrentDir() );
|
||||
BBStr* bbCurrentDir()
|
||||
{
|
||||
return new BBStr(gx_filesys->getCurrentDir());
|
||||
}
|
||||
|
||||
void bbChangeDir( BBStr *d ){
|
||||
gx_filesys->setCurrentDir( *d );
|
||||
void bbChangeDir(BBStr* d)
|
||||
{
|
||||
gx_filesys->setCurrentDir(*d);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void bbCreateDir( BBStr *d ){
|
||||
gx_filesys->createDir( *d );
|
||||
void bbCreateDir(BBStr* d)
|
||||
{
|
||||
gx_filesys->createDir(*d);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void bbDeleteDir( BBStr *d ){
|
||||
gx_filesys->deleteDir( *d );
|
||||
void bbDeleteDir(BBStr* d)
|
||||
{
|
||||
gx_filesys->deleteDir(*d);
|
||||
delete d;
|
||||
}
|
||||
|
||||
int bbFileType( BBStr *f ){
|
||||
string t=*f;delete f;
|
||||
int n=gx_filesys->getFileType( t );
|
||||
return n==gxFileSystem::FILE_TYPE_FILE ? 1 : (n==gxFileSystem::FILE_TYPE_DIR ? 2 : 0);
|
||||
int bbFileType(BBStr* f)
|
||||
{
|
||||
string t = *f;
|
||||
delete f;
|
||||
int n = gx_filesys->getFileType(t);
|
||||
return n == gxFileSystem::FILE_TYPE_FILE ? 1 : (n == gxFileSystem::FILE_TYPE_DIR ? 2 : 0);
|
||||
}
|
||||
|
||||
int bbFileSize( BBStr *f ){
|
||||
string t=*f;delete f;
|
||||
return gx_filesys->getFileSize( t );
|
||||
int bbFileSize(BBStr* f)
|
||||
{
|
||||
string t = *f;
|
||||
delete f;
|
||||
return gx_filesys->getFileSize(t);
|
||||
}
|
||||
|
||||
void bbCopyFile( BBStr *f,BBStr *to ){
|
||||
string src=*f,dest=*to;
|
||||
delete f;delete to;
|
||||
gx_filesys->copyFile( src,dest );
|
||||
void bbCopyFile(BBStr* f, BBStr* to)
|
||||
{
|
||||
string src = *f, dest = *to;
|
||||
delete f;
|
||||
delete to;
|
||||
gx_filesys->copyFile(src, dest);
|
||||
}
|
||||
|
||||
void bbDeleteFile( BBStr *f ){
|
||||
gx_filesys->deleteFile( *f );
|
||||
void bbDeleteFile(BBStr* f)
|
||||
{
|
||||
gx_filesys->deleteFile(*f);
|
||||
delete f;
|
||||
}
|
||||
|
||||
bool filesystem_create(){
|
||||
if( gx_filesys=gx_runtime->openFileSystem( 0 ) ){
|
||||
bool filesystem_create()
|
||||
{
|
||||
if (gx_filesys = gx_runtime->openFileSystem(0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool filesystem_destroy(){
|
||||
while( file_set.size() ) bbCloseFile( *file_set.begin() );
|
||||
gx_runtime->closeFileSystem( gx_filesys );
|
||||
bool filesystem_destroy()
|
||||
{
|
||||
while (file_set.size())
|
||||
bbCloseFile(*file_set.begin());
|
||||
gx_runtime->closeFileSystem(gx_filesys);
|
||||
return true;
|
||||
}
|
||||
|
||||
void filesystem_link( void(*rtSym)(const char*,void*) ){
|
||||
rtSym( "%OpenFile$filename",bbOpenFile );
|
||||
rtSym( "%ReadFile$filename",bbReadFile );
|
||||
rtSym( "%WriteFile$filename",bbWriteFile );
|
||||
rtSym( "CloseFile%file_stream",bbCloseFile );
|
||||
rtSym( "%FilePos%file_stream",bbFilePos );
|
||||
rtSym( "%SeekFile%file_stream%pos",bbSeekFile );
|
||||
void filesystem_link(void (*rtSym)(const char*, void*))
|
||||
{
|
||||
rtSym("%OpenFile$filename", bbOpenFile);
|
||||
rtSym("%ReadFile$filename", bbReadFile);
|
||||
rtSym("%WriteFile$filename", bbWriteFile);
|
||||
rtSym("CloseFile%file_stream", bbCloseFile);
|
||||
rtSym("%FilePos%file_stream", bbFilePos);
|
||||
rtSym("%SeekFile%file_stream%pos", bbSeekFile);
|
||||
|
||||
rtSym( "%ReadDir$dirname",bbReadDir );
|
||||
rtSym( "CloseDir%dir",bbCloseDir );
|
||||
rtSym( "$NextFile%dir",bbNextFile );
|
||||
rtSym( "$CurrentDir",bbCurrentDir );
|
||||
rtSym( "ChangeDir$dir",bbChangeDir );
|
||||
rtSym( "CreateDir$dir",bbCreateDir );
|
||||
rtSym( "DeleteDir$dir",bbDeleteDir );
|
||||
rtSym("%ReadDir$dirname", bbReadDir);
|
||||
rtSym("CloseDir%dir", bbCloseDir);
|
||||
rtSym("$NextFile%dir", bbNextFile);
|
||||
rtSym("$CurrentDir", bbCurrentDir);
|
||||
rtSym("ChangeDir$dir", bbChangeDir);
|
||||
rtSym("CreateDir$dir", bbCreateDir);
|
||||
rtSym("DeleteDir$dir", bbDeleteDir);
|
||||
|
||||
rtSym( "%FileSize$file",bbFileSize );
|
||||
rtSym( "%FileType$file",bbFileType );
|
||||
rtSym( "CopyFile$file$to",bbCopyFile );
|
||||
rtSym( "DeleteFile$file",bbDeleteFile );
|
||||
rtSym("%FileSize$file", bbFileSize);
|
||||
rtSym("%FileType$file", bbFileType);
|
||||
rtSym("CopyFile$file$to", bbCopyFile);
|
||||
rtSym("DeleteFile$file", bbDeleteFile);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#define BBFILESYSTEM_H
|
||||
|
||||
#include "bbsys.hpp"
|
||||
#include "../gxruntime/gxfilesystem.hpp"
|
||||
#include "gxfilesystem.hpp"
|
||||
|
||||
extern gxFileSystem *gx_filesys;
|
||||
extern gxFileSystem* gx_filesys;
|
||||
|
||||
#endif
|
||||
+584
-321
File diff suppressed because it is too large
Load Diff
+77
-78
@@ -3,24 +3,24 @@
|
||||
#define BBGRAPHICS_H
|
||||
|
||||
#include "bbsys.hpp"
|
||||
#include "../gxruntime/gxgraphics.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
|
||||
extern gxGraphics *gx_graphics;
|
||||
extern gxCanvas *gx_canvas;
|
||||
extern gxScene *gx_scene;
|
||||
extern gxGraphics* gx_graphics;
|
||||
extern gxCanvas* gx_canvas;
|
||||
extern gxScene* gx_scene;
|
||||
|
||||
class bbImage;
|
||||
|
||||
//general graphics functions
|
||||
int bbCountGfxDrivers();
|
||||
BBStr * bbGfxDriverName( int n );
|
||||
BBStr * bbGfxDriverDesc( int n );
|
||||
void bbSetGfxDriver( int n );
|
||||
int bbGfxModeExists( int w,int h,int d );
|
||||
BBStr* bbGfxDriverName(int n);
|
||||
BBStr* bbGfxDriverDesc(int n);
|
||||
void bbSetGfxDriver(int n);
|
||||
int bbGfxModeExists(int w, int h, int d);
|
||||
int bbCountGfxModes();
|
||||
int bbGfxModeWidth( int n );
|
||||
int bbGfxModeHeight( int n );
|
||||
int bbGfxModeDepth( int n );
|
||||
int bbGfxModeWidth(int n);
|
||||
int bbGfxModeHeight(int n);
|
||||
int bbGfxModeDepth(int n);
|
||||
int bbGraphicsWidth();
|
||||
int bbGraphicsHeight();
|
||||
int bbGraphicsDepth();
|
||||
@@ -28,93 +28,92 @@ int bbAvailVidMem();
|
||||
int bbTotalVidMem();
|
||||
|
||||
//mode functions
|
||||
void bbGraphics( int w,int h,int d,int mode );
|
||||
gxCanvas * bbFrontBuffer();
|
||||
gxCanvas * bbBackBuffer();
|
||||
void bbGraphics(int w, int h, int d, int mode);
|
||||
gxCanvas* bbFrontBuffer();
|
||||
gxCanvas* bbBackBuffer();
|
||||
void bbEndGraphics();
|
||||
int bbGraphicsLost();
|
||||
int bbScanLine();
|
||||
void bbVWait( int n );
|
||||
void bbFlip( int vwait );
|
||||
void bbVWait(int n);
|
||||
void bbFlip(int vwait);
|
||||
|
||||
//graphics buffer functions
|
||||
void bbSetBuffer( gxCanvas *buff );
|
||||
gxCanvas * bbGraphicsBuffer();
|
||||
int bbLoadBuffer( gxCanvas *surf,BBStr *str );
|
||||
int bbSaveBuffer( gxCanvas *surf,BBStr *str );
|
||||
void bbSetBuffer(gxCanvas* buff);
|
||||
gxCanvas* bbGraphicsBuffer();
|
||||
int bbLoadBuffer(gxCanvas* surf, BBStr* str);
|
||||
int bbSaveBuffer(gxCanvas* surf, BBStr* str);
|
||||
|
||||
//fast read/write operations...
|
||||
void bbLockBuffer( gxCanvas *buff );
|
||||
void bbUnlockBuffer( gxCanvas *buff );
|
||||
int bbReadPixel( int x,int y,gxCanvas *buff );
|
||||
void bbWritePixel( int x,int y,int argb,gxCanvas *buff );
|
||||
int bbReadPixelFast( int x,int y,gxCanvas *buff );
|
||||
void bbWritePixelFast( int x,int y,int argb,gxCanvas *buff );
|
||||
|
||||
void bbLockBuffer(gxCanvas* buff);
|
||||
void bbUnlockBuffer(gxCanvas* buff);
|
||||
int bbReadPixel(int x, int y, gxCanvas* buff);
|
||||
void bbWritePixel(int x, int y, int argb, gxCanvas* buff);
|
||||
int bbReadPixelFast(int x, int y, gxCanvas* buff);
|
||||
void bbWritePixelFast(int x, int y, int argb, gxCanvas* buff);
|
||||
|
||||
//2d rendering functions
|
||||
void bbOrigin( int x,int y );
|
||||
void bbViewport( int x,int y,int w,int h );
|
||||
void bbColor( int r,int g,int b );
|
||||
void bbClsColor( int r,int g,int b );
|
||||
void bbOrigin(int x, int y);
|
||||
void bbViewport(int x, int y, int w, int h);
|
||||
void bbColor(int r, int g, int b);
|
||||
void bbClsColor(int r, int g, int b);
|
||||
void bbCls();
|
||||
void bbPlot( int x,int y );
|
||||
void bbLine( int x1,int y1,int x2,int y2 );
|
||||
void bbRect( int x,int y,int w,int h,int solid );
|
||||
void bbOval( int x,int y,int w,int h,int solid );
|
||||
void bbText( int x,int y,BBStr *str,int centre_x,int centre_y );
|
||||
void bbGetColor( int x,int y );
|
||||
void bbPlot(int x, int y);
|
||||
void bbLine(int x1, int y1, int x2, int y2);
|
||||
void bbRect(int x, int y, int w, int h, int solid);
|
||||
void bbOval(int x, int y, int w, int h, int solid);
|
||||
void bbText(int x, int y, BBStr* str, int centre_x, int centre_y);
|
||||
void bbGetColor(int x, int y);
|
||||
int bbColorRed();
|
||||
int bbColorGreen();
|
||||
int bbColorBlue();
|
||||
|
||||
//font functions
|
||||
gxFont * bbLoadFont( BBStr *name,int height,int bold,int italic,int underline );
|
||||
void bbFreeFont( gxFont *f );
|
||||
void bbSetFont( gxFont *f );
|
||||
gxFont* bbLoadFont(BBStr* name, int height, int bold, int italic, int underline);
|
||||
void bbFreeFont(gxFont* f);
|
||||
void bbSetFont(gxFont* f);
|
||||
int bbFontWidth();
|
||||
int bbFontHeight();
|
||||
int bbStringWidth( BBStr *str );
|
||||
int bbStringHeight( BBStr *str );
|
||||
int bbStringWidth(BBStr* str);
|
||||
int bbStringHeight(BBStr* str);
|
||||
|
||||
//image functions
|
||||
bbImage* bbLoadImage( BBStr *s );
|
||||
bbImage* bbCopyImage( bbImage *i );
|
||||
bbImage* bbCreateImage( int w,int h,int n );
|
||||
bbImage* bbLoadAnimImage( BBStr *s,int w,int h,int first,int cnt );
|
||||
void bbFreeImage( bbImage *i );
|
||||
int bbSaveImage( bbImage *i,BBStr *filename,int frame );
|
||||
void bbGrabImage( bbImage *i,int x,int y,int n );
|
||||
gxCanvas * bbImageBuffer( bbImage *i,int n );
|
||||
void bbDrawImage( bbImage *i,int x,int y,int frame );
|
||||
void bbDrawBlock( bbImage *i,int x,int y,int frame );
|
||||
void bbTileImage( bbImage *i,int x,int y,int frame );
|
||||
void bbTileBlock( bbImage *i,int x,int y,int frame );
|
||||
void bbDrawImageRect( bbImage *i,int x,int y,int r_x,int r_y,int r_w,int r_h,int frame );
|
||||
void bbDrawBlockRect( bbImage *i,int x,int y,int r_x,int r_y,int r_w,int r_h,int frame );
|
||||
void bbMaskImage( bbImage *i,int r,int g,int b );
|
||||
void bbHandleImage( bbImage *i,int x,int y );
|
||||
void bbScaleImage( bbImage *i,float w,float h );
|
||||
void bbResizeImage( bbImage *i,float w,float h );
|
||||
void bbRotateImage( bbImage *i,float angle );
|
||||
void bbTFormImage( bbImage *i,float a,float b,float c,float d );
|
||||
void bbTFormFilter( int enable );
|
||||
void bbAutoMidHandle( int enable );
|
||||
void bbMidHandle( bbImage *i );
|
||||
int bbImageWidth( bbImage *i );
|
||||
int bbImageHeight( bbImage *i );
|
||||
int bbImageXHandle( bbImage *i );
|
||||
int bbImageYHandle( bbImage *i );
|
||||
int bbImagesOverlap( bbImage *i1,int x1,int y1,bbImage *i2,int x2,int y2 );
|
||||
int bbImagesCollide( bbImage *i1,int x1,int y1,int f1,bbImage *i2,int x2,int y2,int f2 );
|
||||
int bbRectsOverlap( int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 );
|
||||
int bbImageRectOverlap( bbImage *i,int x,int y,int r_x,int r_y,int r_w,int r_h );
|
||||
int bbImageRectCollide( bbImage *i,int x,int y,int f,int r_x,int r_y,int r_w,int r_h );
|
||||
bbImage* bbLoadImage(BBStr* s);
|
||||
bbImage* bbCopyImage(bbImage* i);
|
||||
bbImage* bbCreateImage(int w, int h, int n);
|
||||
bbImage* bbLoadAnimImage(BBStr* s, int w, int h, int first, int cnt);
|
||||
void bbFreeImage(bbImage* i);
|
||||
int bbSaveImage(bbImage* i, BBStr* filename, int frame);
|
||||
void bbGrabImage(bbImage* i, int x, int y, int n);
|
||||
gxCanvas* bbImageBuffer(bbImage* i, int n);
|
||||
void bbDrawImage(bbImage* i, int x, int y, int frame);
|
||||
void bbDrawBlock(bbImage* i, int x, int y, int frame);
|
||||
void bbTileImage(bbImage* i, int x, int y, int frame);
|
||||
void bbTileBlock(bbImage* i, int x, int y, int frame);
|
||||
void bbDrawImageRect(bbImage* i, int x, int y, int r_x, int r_y, int r_w, int r_h, int frame);
|
||||
void bbDrawBlockRect(bbImage* i, int x, int y, int r_x, int r_y, int r_w, int r_h, int frame);
|
||||
void bbMaskImage(bbImage* i, int r, int g, int b);
|
||||
void bbHandleImage(bbImage* i, int x, int y);
|
||||
void bbScaleImage(bbImage* i, float w, float h);
|
||||
void bbResizeImage(bbImage* i, float w, float h);
|
||||
void bbRotateImage(bbImage* i, float angle);
|
||||
void bbTFormImage(bbImage* i, float a, float b, float c, float d);
|
||||
void bbTFormFilter(int enable);
|
||||
void bbAutoMidHandle(int enable);
|
||||
void bbMidHandle(bbImage* i);
|
||||
int bbImageWidth(bbImage* i);
|
||||
int bbImageHeight(bbImage* i);
|
||||
int bbImageXHandle(bbImage* i);
|
||||
int bbImageYHandle(bbImage* i);
|
||||
int bbImagesOverlap(bbImage* i1, int x1, int y1, bbImage* i2, int x2, int y2);
|
||||
int bbImagesCollide(bbImage* i1, int x1, int y1, int f1, bbImage* i2, int x2, int y2, int f2);
|
||||
int bbRectsOverlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2);
|
||||
int bbImageRectOverlap(bbImage* i, int x, int y, int r_x, int r_y, int r_w, int r_h);
|
||||
int bbImageRectCollide(bbImage* i, int x, int y, int f, int r_x, int r_y, int r_w, int r_h);
|
||||
|
||||
//simple print functions
|
||||
void bbWrite( BBStr *str );
|
||||
void bbPrint( BBStr *str );
|
||||
BBStr * bbInput( BBStr *prompt );
|
||||
void bbLocate( int x,int y );
|
||||
void bbWrite(BBStr* str);
|
||||
void bbPrint(BBStr* str);
|
||||
BBStr* bbInput(BBStr* prompt);
|
||||
void bbLocate(int x, int y);
|
||||
|
||||
#endif
|
||||
+233
-165
@@ -1,287 +1,355 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "bbsys.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
gxInput *gx_input;
|
||||
gxDevice *gx_mouse;
|
||||
gxDevice *gx_keyboard;
|
||||
gxInput* gx_input;
|
||||
gxDevice* gx_mouse;
|
||||
gxDevice* gx_keyboard;
|
||||
vector<gxDevice*> gx_joysticks;
|
||||
|
||||
static int mouse_x,mouse_y,mouse_z;
|
||||
static const float JLT=-1.0f/3.0f;
|
||||
static const float JHT=1.0f/3.0f;
|
||||
static int mouse_x, mouse_y, mouse_z;
|
||||
static const float JLT = -1.0f / 3.0f;
|
||||
static const float JHT = 1.0f / 3.0f;
|
||||
|
||||
bool input_create(){
|
||||
if( gx_input=gx_runtime->openInput( 0 ) ){
|
||||
if( gx_keyboard=gx_input->getKeyboard() ){
|
||||
if( gx_mouse=gx_input->getMouse() ){
|
||||
bool input_create()
|
||||
{
|
||||
if (gx_input = gx_runtime->openInput(0)) {
|
||||
if (gx_keyboard = gx_input->getKeyboard()) {
|
||||
if (gx_mouse = gx_input->getMouse()) {
|
||||
gx_joysticks.clear();
|
||||
for( int k=0;k<gx_input->numJoysticks();++k ){
|
||||
gx_joysticks.push_back( gx_input->getJoystick(k) );
|
||||
for (int k = 0; k < gx_input->numJoysticks(); ++k) {
|
||||
gx_joysticks.push_back(gx_input->getJoystick(k));
|
||||
}
|
||||
mouse_x=mouse_y=mouse_z=0;
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
gx_runtime->closeInput( gx_input );
|
||||
gx_input=0;
|
||||
gx_runtime->closeInput(gx_input);
|
||||
gx_input = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool input_destroy(){
|
||||
bool input_destroy()
|
||||
{
|
||||
gx_joysticks.clear();
|
||||
gx_runtime->closeInput( gx_input );
|
||||
gx_input=0;
|
||||
gx_runtime->closeInput(gx_input);
|
||||
gx_input = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int bbKeyDown( int n ){
|
||||
return gx_keyboard->keyDown( n );
|
||||
int bbKeyDown(int n)
|
||||
{
|
||||
return gx_keyboard->keyDown(n);
|
||||
}
|
||||
|
||||
int bbKeyHit( int n ){
|
||||
return gx_keyboard->keyHit( n );
|
||||
int bbKeyHit(int n)
|
||||
{
|
||||
return gx_keyboard->keyHit(n);
|
||||
}
|
||||
|
||||
int bbGetKey(){
|
||||
return gx_input->toAscii( gx_keyboard->getKey() );
|
||||
int bbGetKey()
|
||||
{
|
||||
return gx_input->toAscii(gx_keyboard->getKey());
|
||||
}
|
||||
|
||||
int bbWaitKey(){
|
||||
for(;;){
|
||||
if( !gx_runtime->idle() ) ThrowRuntimeException( 0 );
|
||||
if( int key=gx_keyboard->getKey( ) ){
|
||||
if( key=gx_input->toAscii( key ) ) return key;
|
||||
int bbWaitKey()
|
||||
{
|
||||
for (;;) {
|
||||
if (!gx_runtime->idle())
|
||||
ThrowRuntimeException(0);
|
||||
if (int key = gx_keyboard->getKey()) {
|
||||
if (key = gx_input->toAscii(key))
|
||||
return key;
|
||||
}
|
||||
gx_runtime->delay( 20 );
|
||||
gx_runtime->delay(20);
|
||||
}
|
||||
}
|
||||
|
||||
void bbFlushKeys(){
|
||||
void bbFlushKeys()
|
||||
{
|
||||
gx_keyboard->flush();
|
||||
}
|
||||
|
||||
int bbMouseDown( int n ){
|
||||
return gx_mouse->keyDown( n );
|
||||
int bbMouseDown(int n)
|
||||
{
|
||||
return gx_mouse->keyDown(n);
|
||||
}
|
||||
|
||||
int bbMouseHit( int n ){
|
||||
return gx_mouse->keyHit( n );
|
||||
int bbMouseHit(int n)
|
||||
{
|
||||
return gx_mouse->keyHit(n);
|
||||
}
|
||||
|
||||
int bbGetMouse(){
|
||||
int bbGetMouse()
|
||||
{
|
||||
return gx_mouse->getKey();
|
||||
}
|
||||
|
||||
int bbWaitMouse(){
|
||||
for(;;){
|
||||
if( !gx_runtime->idle() ) ThrowRuntimeException( 0 );
|
||||
if( int key=gx_mouse->getKey() ) return key;
|
||||
gx_runtime->delay( 20 );
|
||||
int bbWaitMouse()
|
||||
{
|
||||
for (;;) {
|
||||
if (!gx_runtime->idle())
|
||||
ThrowRuntimeException(0);
|
||||
if (int key = gx_mouse->getKey())
|
||||
return key;
|
||||
gx_runtime->delay(20);
|
||||
}
|
||||
}
|
||||
|
||||
int bbMouseWait(){
|
||||
int bbMouseWait()
|
||||
{
|
||||
return bbWaitMouse();
|
||||
}
|
||||
|
||||
int bbMouseX(){
|
||||
return gx_mouse->getAxisState( 0 );
|
||||
int bbMouseX()
|
||||
{
|
||||
return gx_mouse->getAxisState(0);
|
||||
}
|
||||
|
||||
int bbMouseY(){
|
||||
return gx_mouse->getAxisState( 1 );
|
||||
int bbMouseY()
|
||||
{
|
||||
return gx_mouse->getAxisState(1);
|
||||
}
|
||||
|
||||
int bbMouseZ(){
|
||||
return gx_mouse->getAxisState( 2 )/120;
|
||||
int bbMouseZ()
|
||||
{
|
||||
return gx_mouse->getAxisState(2) / 120;
|
||||
}
|
||||
|
||||
int bbMouseXSpeed(){
|
||||
int dx=bbMouseX()-mouse_x;
|
||||
mouse_x+=dx;
|
||||
int bbMouseXSpeed()
|
||||
{
|
||||
int dx = bbMouseX() - mouse_x;
|
||||
mouse_x += dx;
|
||||
return dx;
|
||||
}
|
||||
|
||||
int bbMouseYSpeed(){
|
||||
int dy=bbMouseY()-mouse_y;
|
||||
mouse_y+=dy;
|
||||
int bbMouseYSpeed()
|
||||
{
|
||||
int dy = bbMouseY() - mouse_y;
|
||||
mouse_y += dy;
|
||||
return dy;
|
||||
}
|
||||
|
||||
int bbMouseZSpeed(){
|
||||
int dz=bbMouseZ()-mouse_z;
|
||||
mouse_z+=dz;
|
||||
int bbMouseZSpeed()
|
||||
{
|
||||
int dz = bbMouseZ() - mouse_z;
|
||||
mouse_z += dz;
|
||||
return dz;
|
||||
}
|
||||
|
||||
void bbFlushMouse(){
|
||||
void bbFlushMouse()
|
||||
{
|
||||
gx_mouse->flush();
|
||||
}
|
||||
|
||||
void bbMoveMouse( int x,int y ){
|
||||
gx_input->moveMouse( mouse_x=x,mouse_y=y );
|
||||
void bbMoveMouse(int x, int y)
|
||||
{
|
||||
gx_input->moveMouse(mouse_x = x, mouse_y = y);
|
||||
}
|
||||
|
||||
int bbJoyType( int port ){
|
||||
return gx_input->getJoystickType( port );
|
||||
int bbJoyType(int port)
|
||||
{
|
||||
return gx_input->getJoystickType(port);
|
||||
}
|
||||
|
||||
int bbJoyDown( int n,int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
return gx_joysticks[port]->keyDown( n );
|
||||
int bbJoyDown(int n, int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->keyDown(n);
|
||||
}
|
||||
|
||||
int bbJoyHit( int n,int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
return gx_joysticks[port]->keyHit( n );
|
||||
int bbJoyHit(int n, int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->keyHit(n);
|
||||
}
|
||||
|
||||
int bbGetJoy( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
int bbGetJoy(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getKey();
|
||||
}
|
||||
|
||||
int bbWaitJoy( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
for(;;){
|
||||
if( !gx_runtime->idle() ) ThrowRuntimeException( 0 );
|
||||
if( int key=gx_joysticks[port]->getKey() ) return key;
|
||||
gx_runtime->delay( 20 );
|
||||
int bbWaitJoy(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
for (;;) {
|
||||
if (!gx_runtime->idle())
|
||||
ThrowRuntimeException(0);
|
||||
if (int key = gx_joysticks[port]->getKey())
|
||||
return key;
|
||||
gx_runtime->delay(20);
|
||||
}
|
||||
}
|
||||
|
||||
float bbJoyX( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float bbJoyX(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(0);
|
||||
}
|
||||
|
||||
float bbJoyY( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float bbJoyY(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(1);
|
||||
}
|
||||
|
||||
float bbJoyZ( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float bbJoyZ(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(2);
|
||||
}
|
||||
|
||||
float bbJoyU( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float bbJoyU(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(3);
|
||||
}
|
||||
|
||||
float bbJoyV( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float bbJoyV(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(4);
|
||||
}
|
||||
|
||||
float bbJoyPitch( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
return gx_joysticks[port]->getAxisState(5)*180;
|
||||
float bbJoyPitch(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(5) * 180;
|
||||
}
|
||||
|
||||
float bbJoyYaw( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
return gx_joysticks[port]->getAxisState(6)*180;
|
||||
float bbJoyYaw(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(6) * 180;
|
||||
}
|
||||
|
||||
float bbJoyRoll( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
return gx_joysticks[port]->getAxisState(7)*180;
|
||||
float bbJoyRoll(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(7) * 180;
|
||||
}
|
||||
|
||||
int bbJoyHat( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
int bbJoyHat(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
return gx_joysticks[port]->getAxisState(8);
|
||||
}
|
||||
|
||||
int bbJoyXDir( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float t=gx_joysticks[port]->getAxisState(0);
|
||||
return t<JLT ? -1 : ( t>JHT ? 1 : 0 );
|
||||
int bbJoyXDir(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
float t = gx_joysticks[port]->getAxisState(0);
|
||||
return t < JLT ? -1 : (t > JHT ? 1 : 0);
|
||||
}
|
||||
|
||||
int bbJoyYDir( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float t=gx_joysticks[port]->getAxisState(1);
|
||||
return t<JLT ? -1 : ( t>JHT ? 1 : 0 );
|
||||
int bbJoyYDir(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
float t = gx_joysticks[port]->getAxisState(1);
|
||||
return t < JLT ? -1 : (t > JHT ? 1 : 0);
|
||||
}
|
||||
|
||||
int bbJoyZDir( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float t=gx_joysticks[port]->getAxisState(2);
|
||||
return t<JLT ? -1 : ( t>JHT ? 1 : 0 );
|
||||
int bbJoyZDir(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
float t = gx_joysticks[port]->getAxisState(2);
|
||||
return t < JLT ? -1 : (t > JHT ? 1 : 0);
|
||||
}
|
||||
|
||||
int bbJoyUDir( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float t=gx_joysticks[port]->getAxisState(3);
|
||||
return t<JLT ? -1 : ( t>JHT ? 1 : 0 );
|
||||
int bbJoyUDir(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
float t = gx_joysticks[port]->getAxisState(3);
|
||||
return t < JLT ? -1 : (t > JHT ? 1 : 0);
|
||||
}
|
||||
|
||||
int bbJoyVDir( int port ){
|
||||
if( port<0 || port>=gx_joysticks.size() ) return 0;
|
||||
float t=gx_joysticks[port]->getAxisState(4);
|
||||
return t<JLT ? -1 : ( t>JHT ? 1 : 0 );
|
||||
int bbJoyVDir(int port)
|
||||
{
|
||||
if (port < 0 || port >= gx_joysticks.size())
|
||||
return 0;
|
||||
float t = gx_joysticks[port]->getAxisState(4);
|
||||
return t < JLT ? -1 : (t > JHT ? 1 : 0);
|
||||
}
|
||||
|
||||
void bbFlushJoy(){
|
||||
for( int k=0;k<gx_joysticks.size();++k ) gx_joysticks[k]->flush();
|
||||
void bbFlushJoy()
|
||||
{
|
||||
for (int k = 0; k < gx_joysticks.size(); ++k)
|
||||
gx_joysticks[k]->flush();
|
||||
}
|
||||
|
||||
void bbEnableDirectInput( int enable ){
|
||||
gx_runtime->enableDirectInput( !!enable );
|
||||
void bbEnableDirectInput(int enable)
|
||||
{
|
||||
gx_runtime->enableDirectInput(!!enable);
|
||||
}
|
||||
|
||||
int bbDirectInputEnabled(){
|
||||
int bbDirectInputEnabled()
|
||||
{
|
||||
return gx_runtime->directInputEnabled();
|
||||
}
|
||||
|
||||
void input_link( void (*rtSym)( const char *sym,void *pc ) ){
|
||||
rtSym( "%KeyDown%key",bbKeyDown );
|
||||
rtSym( "%KeyHit%key",bbKeyHit );
|
||||
rtSym( "%GetKey",bbGetKey );
|
||||
rtSym( "%WaitKey",bbWaitKey );
|
||||
rtSym( "FlushKeys",bbFlushKeys );
|
||||
void input_link(void (*rtSym)(const char* sym, void* pc))
|
||||
{
|
||||
rtSym("%KeyDown%key", bbKeyDown);
|
||||
rtSym("%KeyHit%key", bbKeyHit);
|
||||
rtSym("%GetKey", bbGetKey);
|
||||
rtSym("%WaitKey", bbWaitKey);
|
||||
rtSym("FlushKeys", bbFlushKeys);
|
||||
|
||||
rtSym( "%MouseDown%button",bbMouseDown );
|
||||
rtSym( "%MouseHit%button",bbMouseHit );
|
||||
rtSym( "%GetMouse",bbGetMouse );
|
||||
rtSym( "%WaitMouse",bbWaitMouse );
|
||||
rtSym( "%MouseWait",bbWaitMouse );
|
||||
rtSym( "%MouseX",bbMouseX );
|
||||
rtSym( "%MouseY",bbMouseY );
|
||||
rtSym( "%MouseZ",bbMouseZ );
|
||||
rtSym( "%MouseXSpeed",bbMouseXSpeed );
|
||||
rtSym( "%MouseYSpeed",bbMouseYSpeed );
|
||||
rtSym( "%MouseZSpeed",bbMouseZSpeed );
|
||||
rtSym( "FlushMouse",bbFlushMouse );
|
||||
rtSym( "MoveMouse%x%y",bbMoveMouse );
|
||||
rtSym("%MouseDown%button", bbMouseDown);
|
||||
rtSym("%MouseHit%button", bbMouseHit);
|
||||
rtSym("%GetMouse", bbGetMouse);
|
||||
rtSym("%WaitMouse", bbWaitMouse);
|
||||
rtSym("%MouseWait", bbWaitMouse);
|
||||
rtSym("%MouseX", bbMouseX);
|
||||
rtSym("%MouseY", bbMouseY);
|
||||
rtSym("%MouseZ", bbMouseZ);
|
||||
rtSym("%MouseXSpeed", bbMouseXSpeed);
|
||||
rtSym("%MouseYSpeed", bbMouseYSpeed);
|
||||
rtSym("%MouseZSpeed", bbMouseZSpeed);
|
||||
rtSym("FlushMouse", bbFlushMouse);
|
||||
rtSym("MoveMouse%x%y", bbMoveMouse);
|
||||
|
||||
rtSym( "%JoyType%port=0",bbJoyType );
|
||||
rtSym( "%JoyDown%button%port=0",bbJoyDown );
|
||||
rtSym( "%JoyHit%button%port=0",bbJoyHit );
|
||||
rtSym( "%GetJoy%port=0",bbGetJoy );
|
||||
rtSym( "%WaitJoy%port=0",bbWaitJoy );
|
||||
rtSym( "%JoyWait%port=0",bbWaitJoy );
|
||||
rtSym( "#JoyX%port=0",bbJoyX );
|
||||
rtSym( "#JoyY%port=0",bbJoyY );
|
||||
rtSym( "#JoyZ%port=0",bbJoyZ );
|
||||
rtSym( "#JoyU%port=0",bbJoyU );
|
||||
rtSym( "#JoyV%port=0",bbJoyV );
|
||||
rtSym( "#JoyPitch%port=0",bbJoyPitch );
|
||||
rtSym( "#JoyYaw%port=0",bbJoyYaw );
|
||||
rtSym( "#JoyRoll%port=0",bbJoyRoll );
|
||||
rtSym( "%JoyHat%port=0",bbJoyHat );
|
||||
rtSym( "%JoyXDir%port=0",bbJoyXDir );
|
||||
rtSym( "%JoyYDir%port=0",bbJoyYDir );
|
||||
rtSym( "%JoyZDir%port=0",bbJoyZDir );
|
||||
rtSym( "%JoyUDir%port=0",bbJoyUDir );
|
||||
rtSym( "%JoyVDir%port=0",bbJoyVDir );
|
||||
rtSym( "FlushJoy",bbFlushJoy );
|
||||
rtSym("%JoyType%port=0", bbJoyType);
|
||||
rtSym("%JoyDown%button%port=0", bbJoyDown);
|
||||
rtSym("%JoyHit%button%port=0", bbJoyHit);
|
||||
rtSym("%GetJoy%port=0", bbGetJoy);
|
||||
rtSym("%WaitJoy%port=0", bbWaitJoy);
|
||||
rtSym("%JoyWait%port=0", bbWaitJoy);
|
||||
rtSym("#JoyX%port=0", bbJoyX);
|
||||
rtSym("#JoyY%port=0", bbJoyY);
|
||||
rtSym("#JoyZ%port=0", bbJoyZ);
|
||||
rtSym("#JoyU%port=0", bbJoyU);
|
||||
rtSym("#JoyV%port=0", bbJoyV);
|
||||
rtSym("#JoyPitch%port=0", bbJoyPitch);
|
||||
rtSym("#JoyYaw%port=0", bbJoyYaw);
|
||||
rtSym("#JoyRoll%port=0", bbJoyRoll);
|
||||
rtSym("%JoyHat%port=0", bbJoyHat);
|
||||
rtSym("%JoyXDir%port=0", bbJoyXDir);
|
||||
rtSym("%JoyYDir%port=0", bbJoyYDir);
|
||||
rtSym("%JoyZDir%port=0", bbJoyZDir);
|
||||
rtSym("%JoyUDir%port=0", bbJoyUDir);
|
||||
rtSym("%JoyVDir%port=0", bbJoyVDir);
|
||||
rtSym("FlushJoy", bbFlushJoy);
|
||||
|
||||
rtSym( "EnableDirectInput%enable",bbEnableDirectInput );
|
||||
rtSym( "%DirectInputEnabled",bbDirectInputEnabled );
|
||||
rtSym("EnableDirectInput%enable", bbEnableDirectInput);
|
||||
rtSym("%DirectInputEnabled", bbDirectInputEnabled);
|
||||
}
|
||||
|
||||
+27
-27
@@ -5,51 +5,51 @@
|
||||
#include <vector>
|
||||
|
||||
#include "bbsys.hpp"
|
||||
#include "../gxruntime/gxinput.hpp"
|
||||
#include "gxinput.hpp"
|
||||
|
||||
extern gxInput *gx_input;
|
||||
extern gxDevice *gx_mouse;
|
||||
extern gxDevice *gx_keyboard;
|
||||
extern gxInput* gx_input;
|
||||
extern gxDevice* gx_mouse;
|
||||
extern gxDevice* gx_keyboard;
|
||||
extern std::vector<gxDevice*> gx_joysticks;
|
||||
|
||||
//keyboard
|
||||
int bbKeyDown( int n );
|
||||
int bbKeyHit( int n );
|
||||
int bbKeyDown(int n);
|
||||
int bbKeyHit(int n);
|
||||
int bbGetKey();
|
||||
int bbWaitKey();
|
||||
void bbFlushKeys();
|
||||
|
||||
//mouse
|
||||
int bbMouseDown( int n );
|
||||
int bbMouseHit( int n );
|
||||
int bbMouseDown(int n);
|
||||
int bbMouseHit(int n);
|
||||
int bbGetMouse();
|
||||
int bbWaitMouse();
|
||||
int bbMouseX();
|
||||
int bbMouseY();
|
||||
int bbMouseXSpeed();
|
||||
int bbMouseYSpeed();
|
||||
void bbMoveMouse( int x,int y );
|
||||
void bbMoveMouse(int x, int y);
|
||||
void bbFlushMouse();
|
||||
|
||||
//joysticks
|
||||
int bbJoyType( int port );
|
||||
int bbJoyDown( int n,int port );
|
||||
int bbJoyHit( int n,int port );
|
||||
int bbGetJoy( int port );
|
||||
int bbWaitJoy( int port );
|
||||
float bbJoyX( int port );
|
||||
float bbJoyY( int port );
|
||||
float bbJoyZ( int port );
|
||||
float bbJoyU( int port );
|
||||
float bbJoyV( int port );
|
||||
float bbJoyPitch( int port );
|
||||
float bbJoyYaw( int port );
|
||||
float bbJoyRoll( int port );
|
||||
int bbJoyXDir( int port );
|
||||
int bbJoyYDir( int port );
|
||||
int bbJoyZDir( int port );
|
||||
int bbJoyUDir( int port );
|
||||
int bbJoyVDir( int port );
|
||||
int bbJoyType(int port);
|
||||
int bbJoyDown(int n, int port);
|
||||
int bbJoyHit(int n, int port);
|
||||
int bbGetJoy(int port);
|
||||
int bbWaitJoy(int port);
|
||||
float bbJoyX(int port);
|
||||
float bbJoyY(int port);
|
||||
float bbJoyZ(int port);
|
||||
float bbJoyU(int port);
|
||||
float bbJoyV(int port);
|
||||
float bbJoyPitch(int port);
|
||||
float bbJoyYaw(int port);
|
||||
float bbJoyRoll(int port);
|
||||
int bbJoyXDir(int port);
|
||||
int bbJoyYDir(int port);
|
||||
int bbJoyZDir(int port);
|
||||
int bbJoyUDir(int port);
|
||||
int bbJoyVDir(int port);
|
||||
void bbFlushJoy();
|
||||
|
||||
#endif
|
||||
+103
-54
@@ -1,80 +1,129 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "bbmath.hpp"
|
||||
#include "std.hpp"
|
||||
|
||||
static int rnd_state;
|
||||
static const int RND_A=48271;
|
||||
static const int RND_M=2147483647;
|
||||
static const int RND_Q=44488;
|
||||
static const int RND_R=3399;
|
||||
static const int RND_A = 48271;
|
||||
static const int RND_M = 2147483647;
|
||||
static const int RND_Q = 44488;
|
||||
static const int RND_R = 3399;
|
||||
|
||||
static const float s_degreesToRadians=0.0174532925199432957692369076848861f;
|
||||
static const float s_radiansToDegrees=57.2957795130823208767981548141052f;
|
||||
static const float s_degreesToRadians = 0.0174532925199432957692369076848861f;
|
||||
static const float s_radiansToDegrees = 57.2957795130823208767981548141052f;
|
||||
|
||||
float bbSin( float n ){ return (float)sin(n*s_degreesToRadians); }
|
||||
float bbCos( float n ){ return (float)cos(n*s_degreesToRadians); }
|
||||
float bbTan( float n ){ return (float)tan(n*s_degreesToRadians); }
|
||||
float bbASin( float n ){ return (float)asin(n)*s_radiansToDegrees; }
|
||||
float bbACos( float n ){ return (float)acos(n)*s_radiansToDegrees; }
|
||||
float bbATan( float n ){ return (float)atan(n)*s_radiansToDegrees; }
|
||||
float bbATan2( float n,float t ){ return (float)atan2(n,t)*s_radiansToDegrees; }
|
||||
float bbSqr( float n ){ return (float)sqrt(n); }
|
||||
float bbFloor( float n ){ return (float)floor(n); }
|
||||
float bbCeil( float n ){ return (float)ceil(n); }
|
||||
float bbExp( float n ){ return (float)exp(n); }
|
||||
float bbLog( float n ){ return (float)log(n); }
|
||||
float bbLog10( float n ){ return (float)log10(n); }
|
||||
float bbSin(float n)
|
||||
{
|
||||
return (float)sin(n * s_degreesToRadians);
|
||||
}
|
||||
float bbCos(float n)
|
||||
{
|
||||
return (float)cos(n * s_degreesToRadians);
|
||||
}
|
||||
float bbTan(float n)
|
||||
{
|
||||
return (float)tan(n * s_degreesToRadians);
|
||||
}
|
||||
float bbASin(float n)
|
||||
{
|
||||
return (float)asin(n) * s_radiansToDegrees;
|
||||
}
|
||||
float bbACos(float n)
|
||||
{
|
||||
return (float)acos(n) * s_radiansToDegrees;
|
||||
}
|
||||
float bbATan(float n)
|
||||
{
|
||||
return (float)atan(n) * s_radiansToDegrees;
|
||||
}
|
||||
float bbATan2(float n, float t)
|
||||
{
|
||||
return (float)atan2(n, t) * s_radiansToDegrees;
|
||||
}
|
||||
float bbSqr(float n)
|
||||
{
|
||||
return (float)sqrt(n);
|
||||
}
|
||||
float bbFloor(float n)
|
||||
{
|
||||
return (float)floor(n);
|
||||
}
|
||||
float bbCeil(float n)
|
||||
{
|
||||
return (float)ceil(n);
|
||||
}
|
||||
float bbExp(float n)
|
||||
{
|
||||
return (float)exp(n);
|
||||
}
|
||||
float bbLog(float n)
|
||||
{
|
||||
return (float)log(n);
|
||||
}
|
||||
float bbLog10(float n)
|
||||
{
|
||||
return (float)log10(n);
|
||||
}
|
||||
|
||||
//return rand float from 0...1
|
||||
static inline float rnd(){
|
||||
rnd_state=RND_A*(rnd_state%RND_Q)-RND_R*(rnd_state/RND_Q);
|
||||
if( rnd_state<0 ) rnd_state+=RND_M;
|
||||
return (rnd_state&65535)/65536.0f+(.5f/65536.0f);
|
||||
static inline float rnd()
|
||||
{
|
||||
rnd_state = RND_A * (rnd_state % RND_Q) - RND_R * (rnd_state / RND_Q);
|
||||
if (rnd_state < 0)
|
||||
rnd_state += RND_M;
|
||||
return (rnd_state & 65535) / 65536.0f + (.5f / 65536.0f);
|
||||
}
|
||||
|
||||
float bbRnd( float from,float to ){
|
||||
return rnd()*(to-from)+from;
|
||||
float bbRnd(float from, float to)
|
||||
{
|
||||
return rnd() * (to - from) + from;
|
||||
}
|
||||
|
||||
int bbRand( int from,int to ){
|
||||
if( to<from ) std::swap( from,to );
|
||||
return int(rnd()*(to-from+1))+from;
|
||||
int bbRand(int from, int to)
|
||||
{
|
||||
if (to < from)
|
||||
std::swap(from, to);
|
||||
return int(rnd() * (to - from + 1)) + from;
|
||||
}
|
||||
|
||||
void bbSeedRnd( int seed ){
|
||||
seed&=0x7fffffff;
|
||||
rnd_state=seed ? seed : 1;
|
||||
void bbSeedRnd(int seed)
|
||||
{
|
||||
seed &= 0x7fffffff;
|
||||
rnd_state = seed ? seed : 1;
|
||||
}
|
||||
|
||||
int bbRndSeed(){
|
||||
int bbRndSeed()
|
||||
{
|
||||
return rnd_state;
|
||||
}
|
||||
|
||||
bool math_create(){
|
||||
bbSeedRnd( 0x1234 );
|
||||
bool math_create()
|
||||
{
|
||||
bbSeedRnd(0x1234);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool math_destroy(){
|
||||
bool math_destroy()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void math_link( void (*rtSym)( const char *sym,void *pc ) ){
|
||||
rtSym( "#Sin#degrees",bbSin );
|
||||
rtSym( "#Cos#degrees",bbCos );
|
||||
rtSym( "#Tan#degrees",bbTan );
|
||||
rtSym( "#ASin#float",bbASin );
|
||||
rtSym( "#ACos#float",bbACos );
|
||||
rtSym( "#ATan#float",bbATan );
|
||||
rtSym( "#ATan2#floata#floatb",bbATan2 );
|
||||
rtSym( "#Sqr#float",bbSqr );
|
||||
rtSym( "#Floor#float",bbFloor );
|
||||
rtSym( "#Ceil#float",bbCeil );
|
||||
rtSym( "#Exp#float",bbExp );
|
||||
rtSym( "#Log#float",bbLog );
|
||||
rtSym( "#Log10#float",bbLog10 );
|
||||
rtSym( "#Rnd#from#to=0",bbRnd );
|
||||
rtSym( "%Rand%from%to=1",bbRand );
|
||||
rtSym( "SeedRnd%seed",bbSeedRnd );
|
||||
rtSym( "%RndSeed",bbRndSeed );
|
||||
void math_link(void (*rtSym)(const char* sym, void* pc))
|
||||
{
|
||||
rtSym("#Sin#degrees", bbSin);
|
||||
rtSym("#Cos#degrees", bbCos);
|
||||
rtSym("#Tan#degrees", bbTan);
|
||||
rtSym("#ASin#float", bbASin);
|
||||
rtSym("#ACos#float", bbACos);
|
||||
rtSym("#ATan#float", bbATan);
|
||||
rtSym("#ATan2#floata#floatb", bbATan2);
|
||||
rtSym("#Sqr#float", bbSqr);
|
||||
rtSym("#Floor#float", bbFloor);
|
||||
rtSym("#Ceil#float", bbCeil);
|
||||
rtSym("#Exp#float", bbExp);
|
||||
rtSym("#Log#float", bbLog);
|
||||
rtSym("#Log10#float", bbLog10);
|
||||
rtSym("#Rnd#from#to=0", bbRnd);
|
||||
rtSym("%Rand%from%to=1", bbRand);
|
||||
rtSym("SeedRnd%seed", bbSeedRnd);
|
||||
rtSym("%RndSeed", bbRndSeed);
|
||||
}
|
||||
|
||||
+18
-18
@@ -2,23 +2,23 @@
|
||||
#ifndef BBMATH_H
|
||||
#define BBMATH_H
|
||||
|
||||
float bbSin( float n );
|
||||
float bbCos( float n );
|
||||
float bbTan( float n );
|
||||
float bbASin( float n );
|
||||
float bbACos( float n );
|
||||
float bbATan( float n );
|
||||
float bbHSin( float n );
|
||||
float bbHCos( float n );
|
||||
float bbHTan( float n );
|
||||
float bbATan2( float n,float t );
|
||||
float bbSqr( float n );
|
||||
float bbFloor( float n );
|
||||
float bbCeil( float n );
|
||||
float bbExp( float n );
|
||||
float bbLog( float n );
|
||||
float bbLog10( float n );
|
||||
float bbRnd( float from,float to );
|
||||
void bbSeedRnd( int seed );
|
||||
float bbSin(float n);
|
||||
float bbCos(float n);
|
||||
float bbTan(float n);
|
||||
float bbASin(float n);
|
||||
float bbACos(float n);
|
||||
float bbATan(float n);
|
||||
float bbHSin(float n);
|
||||
float bbHCos(float n);
|
||||
float bbHTan(float n);
|
||||
float bbATan2(float n, float t);
|
||||
float bbSqr(float n);
|
||||
float bbFloor(float n);
|
||||
float bbCeil(float n);
|
||||
float bbExp(float n);
|
||||
float bbLog(float n);
|
||||
float bbLog10(float n);
|
||||
float bbRnd(float from, float to);
|
||||
void bbSeedRnd(int seed);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user