//////////////////////////////////////////////////////////////////////////
//! file = "amma/Surf3d/DispMap/DisplacementImage.hh"
//! lib = DispMap
//! date = "5/11/99"
//! userlevel = Advanced
//! docentry = "3D Surface.Displacement Mapping"
//! rcsid = "$Id: DisplacementImage.hh,v 1.35 2001/02/15 16:43:39 eep1rs Exp $"
//! author = "James Smith"
#ifndef DISPLACEMENTIMAGE_HH
#define DISPLACEMENTIMAGE_HH
// AMMA includes
#include "amma/DoubleIm.hh"
#include "amma/Vector3d.hh"
#include "amma/GUI/CanvasF.hh"
#include "amma/Polygon2.hh"
#include "amma/CTriSet.hh"
#include "amma/TriEdgeSet.hh"
#include "amma/DetailLayer.hh"
#include "amma/PointMapper.hh"
// Definitions for edge-crossing
#define EDGE_01 0x01
#define EDGE_12 0x02
#define EDGE_20 0x04
//: A displacement map image
// This class represents a displacement map. It is basically a DoubleImage,
// but adds a few extra functions for creating displacement maps.
//! example = gendispmap.cc
class DisplacementImageC : public DoubleImageC {
public:
enum DrawMode {
DRAW_WALK,
DRAW_REMAP
};
//: Drawing Modes
//
//- DRAW_WALK is an algorithm that uses a walking method to draw edge triangles.
//- DRAW_REMAP attempts to remap edge triangles in order to draw them.
//
DisplacementImageC() {}
//: Default constructor
DisplacementImageC(SizeT iRows, SizeT iCols);
//: Construct a DisplacementImageC with the specified dimensions.
DisplacementImageC(const ImageC& oRealImage);
//: Construct a DisplacementImageC from a ImageC
void SetOptions(BooleanT bShowFolds, BooleanT bColourTriangles, BooleanT bNoEdges, BooleanT bNoEnclosed);
//: Sets drawing options for the Displacement Image
void SetCanvas(GUICanvasC* pCanvas) {m_pCanvas = pCanvas;}
//: Sets the canvas to draw graphical output into
void MapDetailLayerPoints(DetailLayerC& dlDetailLayer);
//: Maps the points in the detail layer onto the displacement map.
void MapDetailLayer(DetailLayerC& dlDetailLayer, DrawMode eMode = DRAW_WALK);
//: Maps all of the detail layer onto the displacement map.
// The mapping will use the specified edge-drawing elgorithm. The default is DRAW_WALK.
void GetDistance(DetailPointC& dpPoint, const CTriSetC& triControl) const;
//: Get the distance of a point
// The distance member of dpPoint is filled in with the value obtained from the displacement image.
// Texture coordinates are obtained from triControl.
//!bug: Not so much a bug, but there may be rounding errors in this function, giving broken results.
void PrepareForSave(void);
//: Fixes ranges ready for saving to image.
// CALL THIS BEFORE SAVING! Otherwise, the ranges will be broken.
// This may (and should) be removed in a future version.
private:
// Type Definitions
typedef DoubleT TriangleDistances[3];
DoubleT SetDisplacement(IndexT iRow, IndexT iCol, DoubleT dDisplacement);
//: Sets the displacement of the pixel at (iRow, iCol) to .
// Returns the value that the pixel is set to.
void MapSingleTriangle(CTriSetC& triControlMesh, TriEdgeSetC& esTriEdgeSet, PointMapperC& pmMapper, const DetailPointC& dpVertex0, const DetailPointC& dpVertex1, const DetailPointC& dpVertex2, DrawMode eMode = DRAW_WALK);
//: Maps a single triangle to the displacement map.
void DrawEdgeTriangle(CTriSetC& triControlMesh, TriEdgeSetC& esTriEdgeSet, PointMapperC& pmMapper, const DetailPointC& dpVertex0, const DetailPointC& dpVertex1, const DetailPointC& dpVertex2, DrawMode eMode = DRAW_WALK);
//: Draw an edge triangle.
// Fills a triangle that overlaps edges - this is just a wrapper around the next two functions
void WalkDrawEdgeTriangle(CTriSetC& triControlMesh, TriEdgeSetC& esTriEdgeSet, PointMapperC& pmMapper, const DetailPointC& dpVertex0, const DetailPointC& dpVertex1, const DetailPointC& dpVertex2);
//: Implementation of the DRAW_WALK edge drawing mode
// Fills a triangle that overlaps edges by an edge-walking process
void RemapDrawEdgeTriangle(CTriSetC& triControlMesh, TriEdgeSetC& esTriEdgeSet, PointMapperC& pmMapper, const DetailPointC& dpVertex0, const DetailPointC& dpVertex1, const DetailPointC& dpVertex2);
//: Implementation of the DRAW_REMAP edge drawing mode
// Fills a triangle that overlaps edges by a remapping process
IntT DrawMappedTriangle(CTriSetC& triControlMesh, const DetailPointC& dpVertex0, const DetailPointC& dpVertex1, const DetailPointC& dpVertex2, BooleanT bClip = false);
//: Draw a mapped triangle into the image
// All DetailPoints must map to the same triangle.
// if bClip is true, the drawing is clipped to edges of the appropriate control triangle
// It returns an integer value that encodes the edges that have been crossed
void Draw2DTriangle(Polygon2dC& plyTriangle, TriangleDistances tdDistances, Polygon2dC* plyClipper);
//: Draw a clipped triangle.
// If plyClipper is NULL, the triangle is not clipped.
Polygon2dC CreatePolygon(Point2dListC& pntList, TriangleDistances tdDistances = NULL);
//: Creates a polygon from a list of points.
// This function ensures that the points are in the right order.
BooleanT IsPointInTriangle(Point2dC pntPoint, Polygon2dC plyTriangle);
//: Test if the point is inside the polygon.
// The polygon must have three vertices which are in an anticlockwise order.
// Drawing options
BooleanT m_bShowFolds;
BooleanT m_bColourTriangles;
BooleanT m_bNoEdges;
BooleanT m_bNoEnclosed;
// Canvas pointer
GUICanvasC* m_pCanvas;
// Temporary colour variable
IntT m_iColour;
};
#endif