#ifndef Var1_Tringula_H
#define Var1_Tringula_H
#include <Glasses/ZNode.h>
#include <Stones/ZColor.h>
#include <Stones/TimeMakerClient.h>
#include <Eye/Ray.h>
#include <Opcode/Opcode.h>
#include <TRandom.h>
class ZHashList;
class ZVector;
class RectTerrain;
class TringTvor;
class TriMesh;
class ParaSurf;
class Extendio;
class Statico;
class Dynamico;
class Crawler;
class LandMark;
class Explosion;
class Tringula : public ZNode, public TimeMakerClient
{
MAC_RNR_FRIENDS(Tringula);
MAC_RNR_FRIENDS(TringuRep);
friend class TringuCam;
public:
enum PrivRayQN_e
{
PRQN_offset = RayNS::RQN_user_0,
PRQN_extendio_exploding,
PRQN_extendio_dying,
PRQN_extendio_sound
};
enum EdgeRule_e { ER_Stop, ER_Hold, ER_Bounce, ER_Wrap };
enum ColorSource_e
{
CS_XCoord, CS_YCoord, CS_ZCoord,
CS_XNorm, CS_YNorm, CS_ZNorm,
};
struct PickResult
{
Extendio *fExtendio;
Float_t fTime;
PickResult(Extendio* ext, Float_t t) : fExtendio(ext), fTime(t) {}
bool operator<(const PickResult& o) { return fTime < o.fTime; }
};
typedef list<PickResult> lPickResult_t;
typedef list<PickResult>::iterator lPickResult_i;
private:
void _init();
protected:
ZLink<ParaSurf> mParaSurf;
ZLink<TriMesh> mMesh;
ZColor mColor;
Float_t mMaxFlyerH;
Float_t mMaxCameraH;
ZLink<ZHashList> mStatos;
ZLink<ZHashList> mDynos;
ZLink<ZHashList> mFlyers;
ZLink<ZHashList> mLandMarks;
ZLink<ZHashList> mTubes;
ZLink<ZHashList> mExplodios;
ZLink<ZHashList> mExplosions;
GMutex mExplosionMutex;
lpZGlass_t mFreshExplodingExtendios;
lpZGlass_t mFinishedExtendioExplosions;
lpZGlass_t mFreshExplosions;
lpZGlass_t mFinishedExplosions;
Bool_t bRnrBBoxes;
EdgeRule_e mEdgeRule;
TRandom mRndGen;
ZLink<TriMesh> mDefStaMesh;
ZLink<TriMesh> mDefDynMesh;
ZLink<TriMesh> mDefFlyMesh;
ZLink<TriMesh> mDefChopMesh;
Opcode::BipartiteBoxPruner* mBoxPruner;
TimeStamp_t mStatosLTS;
TimeStamp_t mDynosLTS;
TimeStamp_t mFlyersLTS;
void handle_edge_crossing(Dynamico& D,
Opcode::Point& old_pos, Opcode::Point& pos,
Int_t plane, Float_t dist);
Bool_t terrain_height(const Opcode::Point& pos, Float_t& point_h, Float_t& terrain_h);
Bool_t place_on_terrain(Statico* S, TriMesh* M, Bool_t check_inside,
Float_t min_h_above=0);
Bool_t place_on_terrain(Dynamico* D, Float_t h_above);
void fill_pruning_list(AList* extendios, Int_t& n, const Opcode::AABB** boxes, void** user_data);
void fill_pruning_list(AList* extendios, Int_t& n, Int_t l);
void setup_box_pruner();
void setup_stato_pruner();
void setup_dyno_pruner();
void prepick_extendios(AList* extendios, const Opcode::Ray& ray, Float_t ray_length,
lPickResult_t& candidates);
void delete_lens_if_alive(ZGlass* lens);
public:
Tringula(const Text_t* n="Tringula", const Text_t* t=0) :
ZNode(n,t) { _init(); }
virtual ~Tringula();
virtual void AdEnlightenment();
Bool_t RayCollide(const Opcode::Ray& ray, Float_t ray_length,
Bool_t cull_p, Bool_t closest_p,
Opcode::CollisionFaces& col_faces);
Float_t RayCollideClosestHit(const Opcode::Ray& ray, Bool_t cull_p);
Extendio* PickExtendios(const Opcode::Ray& ray, Float_t ray_length,
Float_t* ext_distance = 0);
void ResetCollisionStuff();
Float_t PlaceAboveTerrain(ZTrans& trans, Float_t height=0, Float_t dh_fac=0);
Statico* NewStatico(const Text_t* sname=0);
Statico* RandomStatico(ZVector* mesh_list,
Bool_t check_inside=true,
Int_t max_tries =1000);
void RegisterCrawler(Crawler* d);
Crawler* NewDynamico(const Text_t* dname=0);
Crawler* RandomDynamico(ZVector* mesh_list,
Float_t v_min=-1, Float_t v_max=5,
Float_t w_max= 1);
Dynamico* RandomAirplane(Float_t v_min= 2, Float_t v_max=20,
Float_t w_max= 1,
Float_t h_min_fac=0.3,
Float_t h_max_fac=1);
Dynamico* RandomChopper (Float_t v_min= 2, Float_t v_max=20,
Float_t w_max= 1,
Float_t h_min_fac=0.1,
Float_t h_max_fac=0.5);
LandMark* AddLandMark(TriMesh* mesh, const Float_t* pos);
Bool_t CheckBoundaries(Dynamico* dyno, Float_t& safety);
void DoFullBoxPrunning(vector<Opcode::Segment>& its_lines,
Bool_t accumulate=false, Bool_t verbose=false);
void DoSplitBoxPrunning();
void ExtendioExploding(Extendio* ext);
void ExtendioExplosionFinished(Explosion* exp);
void ExplosionStarted(Explosion* exp);
void ExplosionFinished(Explosion* exp);
void LaserShot(Extendio* ext, const Opcode::Ray& ray, Float_t power);
virtual void TimeTick(Double_t t, Double_t dt);
void EmitExtendioExplodingRay(Extendio* ext, Explosion* exp);
void EmitExtendioDyingRay(Extendio* ext);
void EmitExtendioSoundRay(Extendio* ext, const TString& effect);
#include "Tringula.h7"
ClassDef(Tringula, 1);
};
#endif