summaryrefslogtreecommitdiffhomepage
path: root/Stars45/Solid.h
diff options
context:
space:
mode:
Diffstat (limited to 'Stars45/Solid.h')
-rw-r--r--Stars45/Solid.h337
1 files changed, 337 insertions, 0 deletions
diff --git a/Stars45/Solid.h b/Stars45/Solid.h
new file mode 100644
index 0000000..ef745ca
--- /dev/null
+++ b/Stars45/Solid.h
@@ -0,0 +1,337 @@
+/* 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<Bitmap>& 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<Light>& lights);
+ List<Shadow>& 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<Shadow> 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<Surface>& GetSurfaces() { return surfaces; }
+ List<Material>& GetMaterials() { return materials; }
+ const Material* FindMaterial(const char* mtl_name) const;
+ const Material* ReplaceMaterial(const Material* mtl);
+ void GetAllTextures(List<Bitmap>& textures);
+
+ Poly* AddPolys(int nsurf, int npolys, int nverts);
+ void ExplodeMesh();
+ void OptimizeMesh();
+ void OptimizeMaterials();
+ void ScaleBy(double factor);
+
+ void Normalize();
+ void SelectPolys(List<Poly>&, Material* mtl);
+ void SelectPolys(List<Poly>&, 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<Surface> surfaces;
+ List<Material> 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<Segment>& 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<Poly>&, Material* mtl);
+ void SelectPolys(List<Poly>&, 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<Segment> 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
+