130 lines
2.7 KiB
C++
130 lines
2.7 KiB
C++
|
|
#include "std.h"
|
|
#include "model.h"
|
|
|
|
extern gxScene *gx_scene;
|
|
|
|
class Model::MeshQueue{
|
|
union{
|
|
gxMesh *mesh;
|
|
MeshQueue *next;
|
|
};
|
|
int fv,vc,ft,tc;
|
|
Brush brush;
|
|
int q_type;
|
|
// bool opaque;
|
|
|
|
static MeshQueue *pool;
|
|
|
|
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;
|
|
}
|
|
|
|
int getQueueType()const{
|
|
return q_type;
|
|
}
|
|
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;
|
|
}
|
|
MeshQueue *t=pool;
|
|
pool=t->next;
|
|
return t;
|
|
}
|
|
void operator delete( void *q ){
|
|
MeshQueue *t=(MeshQueue*)q;
|
|
t->next=pool;
|
|
pool=t;
|
|
}
|
|
};
|
|
|
|
Model::MeshQueue *Model::MeshQueue::pool;
|
|
|
|
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){
|
|
}
|
|
|
|
void Model::capture(){
|
|
Object::capture();
|
|
captured_alpha=brush.getAlpha();
|
|
}
|
|
|
|
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;
|
|
}
|
|
return tweened_alpha>0;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
if( w_brush ) render_brush=brush;
|
|
|
|
if( alpha!=render_brush.getAlpha() ){
|
|
render_brush.setAlpha( alpha );
|
|
}else if( !w_brush ){
|
|
return true;
|
|
}
|
|
|
|
setRenderBrush( render_brush );
|
|
w_brush=false;
|
|
return true;
|
|
}
|
|
|
|
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,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();
|
|
q->render();
|
|
delete q;
|
|
}
|
|
}
|