| 1 | /* |
|---|
| 2 | ================================================================================= |
|---|
| 3 | This file is part of Cafu, the open-source game engine and graphics engine |
|---|
| 4 | for multiplayer, cross-platform, real-time 3D action. |
|---|
| 5 | Copyright (C) 2002-2012 Carsten Fuchs Software. |
|---|
| 6 | |
|---|
| 7 | Cafu is free software: you can redistribute it and/or modify it under the terms |
|---|
| 8 | of the GNU General Public License as published by the Free Software Foundation, |
|---|
| 9 | either version 3 of the License, or (at your option) any later version. |
|---|
| 10 | |
|---|
| 11 | Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|---|
| 12 | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|---|
| 13 | PURPOSE. See the GNU General Public License for more details. |
|---|
| 14 | |
|---|
| 15 | You should have received a copy of the GNU General Public License |
|---|
| 16 | along with Cafu. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | |
|---|
| 18 | For support and more information about Cafu, visit us at <http://www.cafu.de>. |
|---|
| 19 | ================================================================================= |
|---|
| 20 | */ |
|---|
| 21 | |
|---|
| 22 | #ifndef CAFU_MAP_BEZIER_PATCH_HPP_INCLUDED |
|---|
| 23 | #define CAFU_MAP_BEZIER_PATCH_HPP_INCLUDED |
|---|
| 24 | |
|---|
| 25 | #include "MapPrimitive.hpp" |
|---|
| 26 | #include "SurfaceInfo.hpp" |
|---|
| 27 | |
|---|
| 28 | #include "MaterialSystem/Mesh.hpp" |
|---|
| 29 | #include "SceneGraph/BezierPatchNode.hpp" |
|---|
| 30 | #include "SceneGraph/LightMapMan.hpp" |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | class EditorMaterialI; |
|---|
| 34 | class EditorMatManT; |
|---|
| 35 | namespace MatSys { class RenderMaterialT; } |
|---|
| 36 | namespace cf { namespace ClipSys { class CollisionModelStaticT; } } |
|---|
| 37 | |
|---|
| 38 | |
|---|
| 39 | /// This class represents a bezier patch. |
|---|
| 40 | /// |
|---|
| 41 | /// Implementation notes: |
|---|
| 42 | /// |
|---|
| 43 | /// Patches consist of several distinct parts: The control-vertices (with position and texture-coordinates each), |
|---|
| 44 | /// a mesh for rendering, and auxiliary data that allows the user to scale, shift and rotate the texture-coordinates in a GUI dialog. |
|---|
| 45 | /// The auxiliary data consists of a duplicate of the control-vertices (texture-coords only, no positions), used as "reference", |
|---|
| 46 | /// plus a transformation matrix. The result of the transformation being applied to the reference tex-coords is always kept identical |
|---|
| 47 | /// to the tex-coords of the control-vertices. |
|---|
| 48 | /// |
|---|
| 49 | /// Several dependency relationships exist between these components: |
|---|
| 50 | /// 1. The control-vertices are the authoritative master data. Only those are ever loaded from and saved to disk. |
|---|
| 51 | /// 2. If the positions of the control-vertices change, the render mesh (positions, normals, tangets, binormals, ...) must be updated. |
|---|
| 52 | /// 3. If the tex-coords of the control-vertices change, |
|---|
| 53 | /// a) the render mesh (its tex-coords) must be updated, and |
|---|
| 54 | /// b) also the auxiliary data must be reset: The transformation must be set to identity and the reference tex-coords must be |
|---|
| 55 | /// set equal to those of the control-vertices, so that the auxiliary data describes the same tex-coords as the control-vertices. |
|---|
| 56 | /// 4. If the transformation matrix of the auxiliary data changes (as a result of user interactivity), |
|---|
| 57 | /// the tex-coords of the control-vertices must be set to the transformed reference tex-coords of the auxiliary data. |
|---|
| 58 | /// Doing so should recurse into the render mesh (case 3a), but not into the auxiliary data (case 3b). |
|---|
| 59 | class MapBezierPatchT : public MapPrimitiveT |
|---|
| 60 | { |
|---|
| 61 | public: |
|---|
| 62 | |
|---|
| 63 | // Endcap positions. |
|---|
| 64 | enum EndCapPosE |
|---|
| 65 | { |
|---|
| 66 | TOP_RIGHT=0, |
|---|
| 67 | TOP_LEFT, |
|---|
| 68 | BOTTOM_RIGHT, |
|---|
| 69 | BOTTOM_LEFT |
|---|
| 70 | }; |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | /// The default constructor. It creates an "empty" bezier patch. |
|---|
| 74 | MapBezierPatchT(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 75 | |
|---|
| 76 | /// The copy constructor for copying a bezier patch. |
|---|
| 77 | /// @param BP The bezier patch to copy-construct this bezier patch from. |
|---|
| 78 | MapBezierPatchT(const MapBezierPatchT& BP); |
|---|
| 79 | |
|---|
| 80 | /// The destructor. |
|---|
| 81 | ~MapBezierPatchT(); |
|---|
| 82 | |
|---|
| 83 | // Create bezier patches in different forms. |
|---|
| 84 | static MapBezierPatchT* CreateSimplePatch(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long width, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 85 | static MapBezierPatchT* CreatePatchCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 86 | static MapBezierPatchT* CreateSquareCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 87 | static MapBezierPatchT* CreateQuarterCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 88 | static MapBezierPatchT* CreateHalfCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 89 | static MapBezierPatchT* CreateEdgePipe(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 90 | static MapBezierPatchT* CreateCone(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 91 | static MapBezierPatchT* CreateSphere(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1); |
|---|
| 92 | |
|---|
| 93 | // Endcaps for bezier patches. |
|---|
| 94 | static MapBezierPatchT* CreateQuarterDisc(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1, EndCapPosE pos=TOP_RIGHT, bool Inverted=false); |
|---|
| 95 | static MapBezierPatchT* CreateConcaveEndcap(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1, EndCapPosE pos=TOP_RIGHT); |
|---|
| 96 | |
|---|
| 97 | |
|---|
| 98 | // Implementations and overrides for base class methods. |
|---|
| 99 | MapBezierPatchT* Clone() const; |
|---|
| 100 | void Assign(const MapElementT* Elem); |
|---|
| 101 | |
|---|
| 102 | |
|---|
| 103 | // MapElementT functions |
|---|
| 104 | BoundingBox3fT GetBB() const; |
|---|
| 105 | bool TraceRay(const Vector3fT& RayOrigin, const Vector3fT& RayDir, float& Fraction, unsigned long& FaceNr) const; |
|---|
| 106 | bool TracePixel(const wxPoint& Pixel, int Radius, const ViewWindow2DT& ViewWin) const; |
|---|
| 107 | |
|---|
| 108 | // Implement the MapElementT transformation methods. |
|---|
| 109 | void TrafoMove(const Vector3fT& Delta); |
|---|
| 110 | void TrafoRotate(const Vector3fT& RefPoint, const cf::math::AnglesfT& Angles); |
|---|
| 111 | void TrafoScale(const Vector3fT& RefPoint, const Vector3fT& Scale); |
|---|
| 112 | void TrafoMirror(unsigned int NormalAxis, float Dist); |
|---|
| 113 | void Transform(const MatrixT& Matrix); |
|---|
| 114 | |
|---|
| 115 | void Load_D3_map(TextParserT& TP, unsigned long patchDef, EditorMatManT& MatMan); |
|---|
| 116 | void Load_cmap(TextParserT& TP, MapDocumentT& MapDoc); |
|---|
| 117 | void Save_cmap(std::ostream& OutFile, unsigned long PatchNr, const MapDocumentT& MapDoc) const; |
|---|
| 118 | |
|---|
| 119 | bool IsTranslucent() const; |
|---|
| 120 | void Render2D(Renderer2DT& Renderer) const; |
|---|
| 121 | void Render3D(Renderer3DT& Renderer) const; |
|---|
| 122 | |
|---|
| 123 | void SetMaterial(EditorMaterialI* Mat); |
|---|
| 124 | EditorMaterialI* GetMaterial() const { return Material; } |
|---|
| 125 | |
|---|
| 126 | // patch manipulation |
|---|
| 127 | const Vector3fT& GetCvPos(unsigned long x, unsigned long y) const { return cv_Pos[y*cv_Width + x]; } |
|---|
| 128 | |
|---|
| 129 | void SetCvPos(unsigned long x, unsigned long y, const Vector3fT& Pos) |
|---|
| 130 | { |
|---|
| 131 | cv_Pos[y*cv_Width + x]=Pos; |
|---|
| 132 | |
|---|
| 133 | NeedsUpdate=true; |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | const Vector3fT& GetCvUV(unsigned long x, unsigned long y) const { return cv_UVs[y*cv_Width + x]; } |
|---|
| 138 | |
|---|
| 139 | void SetCvUV(unsigned long x, unsigned long y, const Vector3fT& uv) |
|---|
| 140 | { |
|---|
| 141 | cv_UVs[y*cv_Width + x]=uv; |
|---|
| 142 | |
|---|
| 143 | NeedsUpdate=true; |
|---|
| 144 | } |
|---|
| 145 | |
|---|
| 146 | |
|---|
| 147 | int GetSubdivsHorz() const { return SubdivsHorz; } |
|---|
| 148 | |
|---|
| 149 | void SetSubdivsHorz(int subdivs) |
|---|
| 150 | { |
|---|
| 151 | SubdivsHorz=subdivs; |
|---|
| 152 | |
|---|
| 153 | NeedsUpdate=true; |
|---|
| 154 | } |
|---|
| 155 | |
|---|
| 156 | |
|---|
| 157 | int GetSubdivsVert() const { return SubdivsVert; } |
|---|
| 158 | |
|---|
| 159 | void SetSubdivsVert(int subdivs) |
|---|
| 160 | { |
|---|
| 161 | SubdivsVert=subdivs; |
|---|
| 162 | |
|---|
| 163 | NeedsUpdate=true; |
|---|
| 164 | } |
|---|
| 165 | |
|---|
| 166 | void InvertPatch(); |
|---|
| 167 | |
|---|
| 168 | /// Set a new SurfaceInfoT. |
|---|
| 169 | void SetSurfaceInfo(const SurfaceInfoT& SI); |
|---|
| 170 | |
|---|
| 171 | /// Returns the surface info that is associated with this patch. |
|---|
| 172 | const SurfaceInfoT& GetSurfaceInfo() const { return SurfaceInfo; } |
|---|
| 173 | |
|---|
| 174 | |
|---|
| 175 | void SetSize(unsigned long width, unsigned long height); |
|---|
| 176 | |
|---|
| 177 | // Get the number of control vertices in width or height of the bezier patch. |
|---|
| 178 | unsigned long GetWidth() const { return cv_Width; } |
|---|
| 179 | unsigned long GetHeight() const { return cv_Height; } |
|---|
| 180 | // Get the number of vertices in width or height of the rendermesh representation of the bezier patch. |
|---|
| 181 | unsigned long GetRenderWidth() const { UpdateRenderMesh(); return BPRenderMesh->Meshes.Size()+1; } |
|---|
| 182 | unsigned long GetRenderHeight() const { UpdateRenderMesh(); assert(BPRenderMesh->Meshes.Size()>0); return BPRenderMesh->Meshes[0]->Vertices.Size()/2; } |
|---|
| 183 | |
|---|
| 184 | // Get the origin of vertice x/y from the rendermesh |
|---|
| 185 | Vector3fT GetRenderVertexPos(unsigned long x, unsigned long y) const; |
|---|
| 186 | |
|---|
| 187 | void Render3D_Basic(MatSys::RenderMaterialT* RenderMat, const wxColour& MeshColor, const int MeshAlpha) const; ///< A helper method for Render3D(), but also useful e.g. for preview renderings by the "New Bezier Patch" tool. |
|---|
| 188 | |
|---|
| 189 | // The TypeSys related declarations for this class. |
|---|
| 190 | virtual const cf::TypeSys::TypeInfoT* GetType() const { return &TypeInfo; } |
|---|
| 191 | static void* CreateInstance(const cf::TypeSys::CreateParamsT& Params); |
|---|
| 192 | static const cf::TypeSys::TypeInfoT TypeInfo; |
|---|
| 193 | |
|---|
| 194 | |
|---|
| 195 | private: |
|---|
| 196 | |
|---|
| 197 | void operator = (const MapBezierPatchT&); ///< Use of the Assignment Operator is not allowed. |
|---|
| 198 | |
|---|
| 199 | void UpdateRenderMesh() const; |
|---|
| 200 | void UpdateTextureSpace(); ///< Updates the UV coordinates of the patch according to the projection and orientation values from SurfaceInfoT. |
|---|
| 201 | |
|---|
| 202 | // Note: The members starting with cv_ could be replaced by a BezierPatchNodeT object, that contains the same variables. |
|---|
| 203 | ArrayT<Vector3fT> cv_Pos; ///< The positions of the control vertices. |
|---|
| 204 | ArrayT<Vector3fT> cv_UVs; ///< The texture-coordinates of the control vertices. |
|---|
| 205 | unsigned long cv_Width; ///< The size of the control vertices array in x-direction. |
|---|
| 206 | unsigned long cv_Height; ///< The size of the control vertices array in y-direction. |
|---|
| 207 | int SubdivsHorz; ///< The explicit number of subdivisions in horizontal direction for rendering (and clipping?) this patch, or -1 for automatic choice. |
|---|
| 208 | int SubdivsVert; ///< The explicit number of subdivisions in vertical direction for rendering (and clipping?) this patch, or -1 for automatic choice. |
|---|
| 209 | |
|---|
| 210 | mutable bool NeedsUpdate; |
|---|
| 211 | |
|---|
| 212 | SurfaceInfoT SurfaceInfo; |
|---|
| 213 | cf::SceneGraph::LightMapManT& LMM; |
|---|
| 214 | mutable cf::SceneGraph::BezierPatchNodeT* BPRenderMesh; |
|---|
| 215 | mutable cf::ClipSys::CollisionModelStaticT* CollModel; ///< For implementing the TraceRay() method. |
|---|
| 216 | EditorMaterialI* Material; |
|---|
| 217 | }; |
|---|
| 218 | |
|---|
| 219 | #endif |
|---|