/* Starshatter OpenSource Distribution Copyright (c) 1997-2004, Destroyer Studios LLC. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name "Destroyer Studios" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SUBSYSTEM: nGenEx.lib FILE: Solid.h AUTHOR: John DiCamillo OVERVIEW ======== Classes for rendering solid meshes of polygons */ #ifndef Solid_h #define Solid_h #include "Polygon.h" #include "Graphic.h" #include "Video.h" #include "List.h" // +--------------------------------------------------------------------+ class Solid; class Model; class ModelFile; class Surface; class Segment; class Shadow; class Light; class OPCODE_data; // for collision detection // +--------------------------------------------------------------------+ class Solid : public Graphic { public: static const char* TYPENAME() { return "Solid"; } enum { NAMELEN = 64 }; static bool IsCollisionEnabled(); static void EnableCollision(bool enable); Solid(); virtual ~Solid(); // operations virtual void Render(Video* video, DWORD flags); virtual void SelectDetail(Projector* p); virtual void ProjectScreenRect(Projector* p); virtual void Update(); // accessors / mutators Model* GetModel() const { return model; } void GetAllTextures(List& textures); virtual bool IsDynamic() const; virtual void SetDynamic(bool d); virtual void SetLuminous(bool l); virtual void SetOrientation(const Matrix& o); virtual void SetOrientation(const Solid& match); const Matrix& Orientation() const { return orientation; } float Roll() const { return roll; } float Pitch() const { return pitch; } float Yaw() const { return yaw; } virtual bool IsSolid() const { return true; } // stencil shadows virtual void CreateShadows(int nlights=1); virtual void UpdateShadows(List& lights); List& GetShadows() { return shadows; } bool Load(const char* mag_file, double scale=1.0); bool Load(ModelFile* loader, double scale=1.0); void UseModel(Model* model); void ClearModel(); bool Rescale(double scale); // collision detection virtual int CollidesWith(Graphic& o); virtual int CheckRayIntersection(Point pt, Point vpn, double len, Point& ipt, bool treat_translucent_polys_as_solid=true); virtual Poly* GetIntersectionPoly() const { return intersection_poly; } // buffer management virtual void DeletePrivateData(); virtual void InvalidateSurfaceData(); virtual void InvalidateSegmentData(); protected: Model* model; bool own_model; float roll, pitch, yaw; Matrix orientation; Poly* intersection_poly; List shadows; }; // +--------------------------------------------------------------------+ class Model { friend class Solid; friend class ModelFile; public: static const char* TYPENAME() { return "Model"; } enum { MAX_VERTS = 64000, MAX_POLYS = 16000 }; Model(); Model(const Model& m); ~Model(); Model& operator = (const Model& m); int operator == (const Model& that) const { return this == &that; } bool Load(const char* mag_file, double scale=1.0); bool Load(ModelFile* loader, double scale=1.0); const char* Name() const { return name; } int NumVerts() const { return nverts; } int NumSurfaces() const { return surfaces.size(); } int NumMaterials() const { return materials.size(); } int NumPolys() const { return npolys; } int NumSegments() const; double Radius() const { return radius; } bool IsDynamic() const { return dynamic; } void SetDynamic(bool d) { dynamic = d; } bool IsLuminous() const { return luminous; } void SetLuminous(bool l) { luminous = l; } List& GetSurfaces() { return surfaces; } List& GetMaterials() { return materials; } const Material* FindMaterial(const char* mtl_name) const; const Material* ReplaceMaterial(const Material* mtl); void GetAllTextures(List& textures); Poly* AddPolys(int nsurf, int npolys, int nverts); void ExplodeMesh(); void OptimizeMesh(); void OptimizeMaterials(); void ScaleBy(double factor); void Normalize(); void SelectPolys(List&, Material* mtl); void SelectPolys(List&, Vec3 loc); void AddSurface(Surface* s); void ComputeTangents(); // buffer management void DeletePrivateData(); private: bool LoadMag5(BYTE* block, int len, double scale); bool LoadMag6(BYTE* block, int len, double scale); char name[Solid::NAMELEN]; List surfaces; List materials; int nverts; int npolys; float radius; float extents[6]; bool luminous; bool dynamic; }; // +--------------------------------------------------------------------+ class Surface { friend class Solid; friend class Model; public: static const char* TYPENAME() { return "Surface"; } enum { HIDDEN=1, LOCKED=2, SIMPLE=4, MAX_VERTS=64000, MAX_POLYS=16000 }; Surface(); ~Surface(); int operator == (const Surface& s) const { return this == &s; } const char* Name() const { return name; } int NumVerts() const { return vertex_set ? vertex_set->nverts : 0; } int NumSegments() const { return segments.size(); } int NumPolys() const { return npolys; } int NumIndices() const { return nindices; } bool IsHidden() const { return state & HIDDEN ? true : false; } bool IsLocked() const { return state & LOCKED ? true : false; } bool IsSimplified() const { return state & SIMPLE ? true : false; } Model* GetModel() const { return model; } List& GetSegments() { return segments; } const Point& GetOffset() const { return offset; } const Matrix& GetOrientation() const { return orientation; } double Radius() const { return radius; } VertexSet* GetVertexSet() const { return vertex_set; } Vec3* GetVLoc() const { return vloc; } Poly* GetPolys() const { return polys; } void SetName(const char* n); void SetHidden(bool b); void SetLocked(bool b); void SetSimplified(bool b); void CreateVerts(int nverts); void CreatePolys(int npolys); void AddIndices(int n) { nindices += n; } Poly* AddPolys(int npolys, int nverts); VideoPrivateData* GetVideoPrivateData() const { return video_data; } void SetVideoPrivateData(VideoPrivateData* vpd) { video_data = vpd; } void ScaleBy(double factor); void BuildHull(); void Normalize(); void SelectPolys(List&, Material* mtl); void SelectPolys(List&, Vec3 loc); void InitializeCollisionHull(); void ComputeTangents(); void CalcGradients(Poly& p, Vec3& tangent, Vec3& binormal); void Copy(Surface& s, Model* m); void OptimizeMesh(); void ExplodeMesh(); private: char name[Solid::NAMELEN]; Model* model; VertexSet* vertex_set; // for rendering Vec3* vloc; // for shadow hull float radius; int nhull; int npolys; int nindices; int state; Poly* polys; List segments; Point offset; Matrix orientation; public: OPCODE_data* opcode; private: VideoPrivateData* video_data; }; // +--------------------------------------------------------------------+ class Segment { public: static const char* TYPENAME() { return "Segment"; } Segment(); Segment(int n, Poly* p, Material* mtl, Model* mod=0); ~Segment(); bool IsSolid() const { return material ? material->IsSolid() : true; } bool IsTranslucent() const { return material ? material->IsTranslucent(): false; } bool IsGlowing() const { return material ? material->IsGlowing() : false; } VideoPrivateData* GetVideoPrivateData() const { return video_data; } void SetVideoPrivateData(VideoPrivateData* vpd) { video_data = vpd; } int npolys; Poly* polys; Material* material; Model* model; VideoPrivateData* video_data; }; // +--------------------------------------------------------------------+ class ModelFile { public: ModelFile(const char* fname); virtual ~ModelFile(); virtual bool Load(Model* m, double scale=1.0); virtual bool Save(Model* m); protected: char filename[256]; Model* model; // internal accessors: char* pname; int* pnverts; int* pnpolys; float* pradius; }; // +--------------------------------------------------------------------+ #endif Solid_h