Cafu Engine
MapBezierPatch.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_MAP_BEZIER_PATCH_HPP_INCLUDED
8 #define CAFU_MAP_BEZIER_PATCH_HPP_INCLUDED
9 
10 #include "MapPrimitive.hpp"
11 #include "SurfaceInfo.hpp"
12 
13 #include "MaterialSystem/Mesh.hpp"
14 #include "SceneGraph/BezierPatchNode.hpp"
15 #include "SceneGraph/LightMapMan.hpp"
16 
17 
18 class EditorMaterialI;
19 class EditorMatManT;
20 namespace MatSys { class RenderMaterialT; }
21 namespace cf { namespace ClipSys { class CollisionModelStaticT; } }
22 
23 
24 /// This class represents a bezier patch.
25 ///
26 /// Implementation notes:
27 ///
28 /// Patches consist of several distinct parts: The control-vertices (with position and texture-coordinates each),
29 /// a mesh for rendering, and auxiliary data that allows the user to scale, shift and rotate the texture-coordinates in a GUI dialog.
30 /// The auxiliary data consists of a duplicate of the control-vertices (texture-coords only, no positions), used as "reference",
31 /// plus a transformation matrix. The result of the transformation being applied to the reference tex-coords is always kept identical
32 /// to the tex-coords of the control-vertices.
33 ///
34 /// Several dependency relationships exist between these components:
35 /// 1. The control-vertices are the authoritative master data. Only those are ever loaded from and saved to disk.
36 /// 2. If the positions of the control-vertices change, the render mesh (positions, normals, tangets, binormals, ...) must be updated.
37 /// 3. If the tex-coords of the control-vertices change,
38 /// a) the render mesh (its tex-coords) must be updated, and
39 /// b) also the auxiliary data must be reset: The transformation must be set to identity and the reference tex-coords must be
40 /// set equal to those of the control-vertices, so that the auxiliary data describes the same tex-coords as the control-vertices.
41 /// 4. If the transformation matrix of the auxiliary data changes (as a result of user interactivity),
42 /// the tex-coords of the control-vertices must be set to the transformed reference tex-coords of the auxiliary data.
43 /// Doing so should recurse into the render mesh (case 3a), but not into the auxiliary data (case 3b).
45 {
46  public:
47 
48  // Endcap positions.
49  enum EndCapPosE
50  {
51  TOP_RIGHT=0,
52  TOP_LEFT,
53  BOTTOM_RIGHT,
54  BOTTOM_LEFT
55  };
56 
57 
58  /// The default constructor. It creates an "empty" bezier patch.
59  MapBezierPatchT(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, int SubdivsHorz_=-1, int SubdivsVert_=-1);
60 
61  /// The copy constructor for copying a bezier patch.
62  /// @param BP The bezier patch to copy-construct this bezier patch from.
64 
65  /// The destructor.
67 
68  // Create bezier patches in different forms.
69  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);
70  static MapBezierPatchT* CreatePatchCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1);
71  static MapBezierPatchT* CreateSquareCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1);
72  static MapBezierPatchT* CreateQuarterCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1);
73  static MapBezierPatchT* CreateHalfCylinder(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1);
74  static MapBezierPatchT* CreateEdgePipe(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1);
75  static MapBezierPatchT* CreateCone(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, unsigned long height, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1);
76  static MapBezierPatchT* CreateSphere(EditorMaterialI* Material_, cf::SceneGraph::LightMapManT& LMM_, const Vector3fT& min, const Vector3fT& max, int SubdivsHorz_=-1, int SubdivsVert_=-1);
77 
78  // Endcaps for bezier patches.
79  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);
80  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);
81 
82 
83  // Implementations and overrides for base class methods.
84  MapBezierPatchT* Clone() const override;
85 
86 
87  // MapElementT functions
88  BoundingBox3fT GetBB() const;
89  bool TraceRay(const Vector3fT& RayOrigin, const Vector3fT& RayDir, float& Fraction, unsigned long& FaceNr) const;
90  bool TracePixel(const wxPoint& Pixel, int Radius, const ViewWindow2DT& ViewWin) const;
91 
92  // Implement the MapElementT transformation methods.
93  TrafoMementoT* GetTrafoState() const override;
94  void RestoreTrafoState(const TrafoMementoT* TM) override;
95  void TrafoMove(const Vector3fT& Delta, bool LockTexCoords) override;
96  void TrafoRotate(const Vector3fT& RefPoint, const cf::math::AnglesfT& Angles, bool LockTexCoords) override;
97  void TrafoScale(const Vector3fT& RefPoint, const Vector3fT& Scale, bool LockTexCoords) override;
98  void TrafoMirror(unsigned int NormalAxis, float Dist, bool LockTexCoords) override;
99  void Transform(const Matrix4x4fT& Matrix, bool LockTexCoords) override;
100 
101  void Load_D3_map(TextParserT& TP, unsigned long patchDef, EditorMatManT& MatMan);
102  void Load_cmap(TextParserT& TP, MapDocumentT& MapDoc, bool IgnoreGroups) override;
103  void Save_cmap(std::ostream& OutFile, unsigned long PatchNr, const MapDocumentT& MapDoc) const;
104 
105  bool IsTranslucent() const;
106  void Render2D(Renderer2DT& Renderer) const;
107  void Render3D(Renderer3DT& Renderer) const;
108 
109  void SetMaterial(EditorMaterialI* Mat);
110  EditorMaterialI* GetMaterial() const { return Material; }
111 
112  // patch manipulation
113  const Vector3fT& GetCvPos(unsigned long x, unsigned long y) const { return cv_Pos[y*cv_Width + x]; }
114 
115  void SetCvPos(unsigned long x, unsigned long y, const Vector3fT& Pos)
116  {
117  cv_Pos[y*cv_Width + x]=Pos;
118 
119  NeedsUpdate=true;
120  }
121 
122 
123  const Vector3fT& GetCvUV(unsigned long x, unsigned long y) const { return cv_UVs[y*cv_Width + x]; }
124 
125  void SetCvUV(unsigned long x, unsigned long y, const Vector3fT& uv)
126  {
127  cv_UVs[y*cv_Width + x]=uv;
128 
129  NeedsUpdate=true;
130  }
131 
132 
133  int GetSubdivsHorz() const { return SubdivsHorz; }
134 
135  void SetSubdivsHorz(int subdivs)
136  {
137  SubdivsHorz=subdivs;
138 
139  NeedsUpdate=true;
140  }
141 
142 
143  int GetSubdivsVert() const { return SubdivsVert; }
144 
145  void SetSubdivsVert(int subdivs)
146  {
147  SubdivsVert=subdivs;
148 
149  NeedsUpdate=true;
150  }
151 
152  void InvertPatch();
153 
154  /// Set a new SurfaceInfoT.
155  void SetSurfaceInfo(const SurfaceInfoT& SI);
156 
157  /// Returns the surface info that is associated with this patch.
158  const SurfaceInfoT& GetSurfaceInfo() const { return SurfaceInfo; }
159 
160 
161  void SetSize(unsigned long width, unsigned long height);
162 
163  // Get the number of control vertices in width or height of the bezier patch.
164  unsigned long GetWidth() const { return cv_Width; }
165  unsigned long GetHeight() const { return cv_Height; }
166  // Get the number of vertices in width or height of the rendermesh representation of the bezier patch.
167  unsigned long GetRenderWidth() const { UpdateRenderMesh(); return BPRenderMesh->Meshes.Size()+1; }
168  unsigned long GetRenderHeight() const { UpdateRenderMesh(); assert(BPRenderMesh->Meshes.Size()>0); return BPRenderMesh->Meshes[0]->Vertices.Size()/2; }
169 
170  // Get the origin of vertice x/y from the rendermesh
171  Vector3fT GetRenderVertexPos(unsigned long x, unsigned long y) const;
172 
173  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.
174 
175  // The TypeSys related declarations for this class.
176  virtual const cf::TypeSys::TypeInfoT* GetType() const { return &TypeInfo; }
177  static void* CreateInstance(const cf::TypeSys::CreateParamsT& Params);
178  static const cf::TypeSys::TypeInfoT TypeInfo;
179 
180 
181  private:
182 
183  void operator = (const MapBezierPatchT&); ///< Use of the Assignment Operator is not allowed.
184 
185  bool ReconstructMatFit();
186  bool ReconstructPlaneProj(bool AltOrigin);
187 
188  /// If `SurfaceInfo.TexCoordGenMode == Custom`, this method tries to reconstruct a
189  /// `SurfaceInfo` in `MatFit` or `PlaneProj` mode.
190  bool ReconstructSI();
191 
192  void UpdateRenderMesh() const;
193  void UpdateTextureSpace(); ///< Updates the UV coordinates of the patch according to the projection and orientation values from SurfaceInfoT.
194 
195  // Note: The members starting with cv_ could be replaced by a BezierPatchNodeT object, that contains the same variables.
196  ArrayT<Vector3fT> cv_Pos; ///< The positions of the control vertices.
197  ArrayT<Vector3fT> cv_UVs; ///< The texture-coordinates of the control vertices.
198  unsigned long cv_Width; ///< The size of the control vertices array in x-direction.
199  unsigned long cv_Height; ///< The size of the control vertices array in y-direction.
200  int SubdivsHorz; ///< The explicit number of subdivisions in horizontal direction for rendering (and clipping?) this patch, or -1 for automatic choice.
201  int SubdivsVert; ///< The explicit number of subdivisions in vertical direction for rendering (and clipping?) this patch, or -1 for automatic choice.
202 
203  mutable bool NeedsUpdate;
204 
205  SurfaceInfoT SurfaceInfo;
207  mutable cf::SceneGraph::BezierPatchNodeT* BPRenderMesh;
208  mutable cf::ClipSys::CollisionModelStaticT* CollModel; ///< For implementing the TraceRay() method.
209  EditorMaterialI* Material;
210 };
211 
212 #endif
This class provides auxiliary means for rendering a 3D view.
Definition: Renderer3D.hpp:30
This class implements the rendering into a 2D view.
Definition: Renderer2D.hpp:22
This class manages lightmaps, e.g. by "allocating" rectangular areas in larger bitmaps.
Definition: LightMapMan.hpp:25
This class represents a surface render material.
Definition: RenderMaterial.hpp:25
This class represents a CaWE "map" document.
Definition: MapDocument.hpp:45
void Transform(const Matrix4x4fT &Matrix, bool LockTexCoords) override
Why does this method not replace all the other Trafo*() methods? This method is the most generic...
Definition: MapBezierPatch.cpp:979
This class holds all information that is needed in order to compute the UV texture-space coordinates ...
Definition: SurfaceInfo.hpp:51
unsigned long Size() const
Get size of array.
Definition: Array.hpp:138
void TrafoRotate(const Vector3fT &RefPoint, const cf::math::AnglesfT &Angles, bool LockTexCoords) override
Rotates this element about the given reference point (in world-space).
Definition: MapBezierPatch.cpp:933
This class adds no functionality of its own, but only exists for proper type separation.
Definition: MapPrimitive.hpp:21
BoundingBox3fT GetBB() const
Returns the spatial bounding-box of this map element.
Definition: MapBezierPatch.cpp:593
const SurfaceInfoT & GetSurfaceInfo() const
Returns the surface info that is associated with this patch.
Definition: MapBezierPatch.hpp:158
Definition: BezierPatchNode.hpp:32
This class manages the editor materials for a game configuration.
Definition: EditorMaterialManager.hpp:20
void TrafoMove(const Vector3fT &Delta, bool LockTexCoords) override
Translates this element by the given vector (in world-space).
Definition: MapBezierPatch.cpp:923
This class represents a polymorphic 3-dimensional vector.
Definition: Misc.hpp:11
bool TraceRay(const Vector3fT &RayOrigin, const Vector3fT &RayDir, float &Fraction, unsigned long &FaceNr) const
Traces a ray against this map element, and returns whether it was hit.
Definition: MapBezierPatch.cpp:606
An instance of this class encapsulates the transform-related state of a MapElementT.
Definition: MapElement.hpp:39
void TrafoScale(const Vector3fT &RefPoint, const Vector3fT &Scale, bool LockTexCoords) override
Scales this element about the given reference point (in world-space).
Definition: MapBezierPatch.cpp:951
TrafoMementoT * GetTrafoState() const override
Returns a memento that encapsulates the transform-related state of this element.
Definition: MapBezierPatch.cpp:899
This class represents a bezier patch.
Definition: MapBezierPatch.hpp:44
bool IsTranslucent() const
Returns whether this map element is (entirely or partially) translucent.
Definition: MapBezierPatch.cpp:680
void SetSurfaceInfo(const SurfaceInfoT &SI)
Set a new SurfaceInfoT.
Definition: MapBezierPatch.cpp:809
Definition: EditorMaterial.hpp:21
This class represents a static collision model.
Definition: CollisionModel_static.hpp:25
Definition: ChildFrameViewWin2D.hpp:24
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"...
Definition: MapBezierPatch.cpp:736
void TrafoMirror(unsigned int NormalAxis, float Dist, bool LockTexCoords) override
Mirrors this element along the given mirror plane (in world-space).
Definition: MapBezierPatch.cpp:961
bool TracePixel(const wxPoint &Pixel, int Radius, const ViewWindow2DT &ViewWin) const
This method determines if this map element is intersected/affected by the specified disc in ViewWin...
Definition: MapBezierPatch.cpp:627
void RestoreTrafoState(const TrafoMementoT *TM) override
Restores the transform-related state of this element from the given memento.
Definition: MapBezierPatch.cpp:905
MapBezierPatchT * Clone() const override
The virtual copy constructor.
Definition: MapBezierPatch.cpp:587
~MapBezierPatchT()
The destructor.
Definition: MapBezierPatch.cpp:100
Definition: Renderer.hpp:16
Definition: TypeSys.hpp:52
This class keeps type information (about an entity class that occurs in the game).
Definition: TypeSys.hpp:79
MapBezierPatchT(EditorMaterialI *Material_, cf::SceneGraph::LightMapManT &LMM_, int SubdivsHorz_=-1, int SubdivsVert_=-1)
The default constructor. It creates an "empty" bezier patch.
Definition: MapBezierPatch.cpp:62
This is a class for parsing text.
Definition: TextParser.hpp:21