mirror of
https://github.com/OpenTrespasser/JurassicParkTrespasser.git
synced 2024-12-20 07:31:56 +00:00
961 lines
27 KiB
C++
961 lines
27 KiB
C++
|
/***********************************************************************************************
|
|||
|
*
|
|||
|
* Copyright <EFBFBD> DreamWorks Interactive. 1996
|
|||
|
*
|
|||
|
* Contents:
|
|||
|
* Classes for fast bumpmapping.
|
|||
|
*
|
|||
|
* Notes:
|
|||
|
*
|
|||
|
* CBumpAnglePair describes a normal in terms of two polar coordinates. By definition
|
|||
|
* 'theta' describes the angle of the normal from the y-axis along the x/y plane, and
|
|||
|
* 'phi' describes the angle of the normal to that plane.
|
|||
|
*
|
|||
|
* Phi may be stored in two locations, PhiB and PhiL, in the CBumpAnglePair class; PhiB
|
|||
|
* represents the phi angle of made by the bumpmap, and PhiL represents the angle made
|
|||
|
* by the light. Only one representation of theta is required as the theta in the lookup
|
|||
|
* table represents the difference in the light's theta and the bumpmap's table.
|
|||
|
*
|
|||
|
* Bumpmapping requires the dot product between the light normal and the normal to a pixel
|
|||
|
* on the bumpmap's surface. The fast bumpmap replaces normals described as vectors (i.e.,
|
|||
|
* using 'x,' 'y,' and 'z' components) with normals described as angles. Note that normals
|
|||
|
* (by definition) have a unit length of one, so angles are just as accurate but require
|
|||
|
* less data (i.e., 'theta' and 'phi' values. This turns the 3D problem into a 2D problem.
|
|||
|
*
|
|||
|
* Theta can be any value between 0 and 2 x Pi. Phi can be any value from -Pi/2 to Pi/2,
|
|||
|
* however Phi for the bumpmap is clamped to the range 0 to Pi/2 for cache efficiency;
|
|||
|
* it is felt that most "real-life" bumpmaps won't have surface normals with a negative z
|
|||
|
* component.
|
|||
|
*
|
|||
|
* First a table is set up to return the arccos (i.e., dot product) value represented as
|
|||
|
* an intensity. The index into the table is given in the format phi light - theta -
|
|||
|
* phi bump. For more information refer to the 'FastBumpMath' and 'FastBumpTable' modules.
|
|||
|
* This table need be set up only once during program initialization.
|
|||
|
*
|
|||
|
* Secondly bumpmaps are loaded. Bumpmaps consist of combining a heightfield with
|
|||
|
* curvatures represented by vertex normals, and adding texture.
|
|||
|
*
|
|||
|
* Heightfields are converted to normals by selecting two points adjacent to a given pixel
|
|||
|
* and using these three points to define a plane. The x and y values are the x and y
|
|||
|
* positions of the pixels on the bitmap, while the z value is value (e.g., grayscale
|
|||
|
* intensity) of the pixels. The z value is scaled by some value called 'f_bumpiness' in
|
|||
|
* the function 'AddHeightField.'
|
|||
|
*
|
|||
|
* Curvature is then added by using a modified rasterizing routine to interpolate normals
|
|||
|
* across triangles on the bumpmap, and transforming bumpmap normals using these
|
|||
|
* interpolated normals. To allow for graceful handling of a situation where overlapping
|
|||
|
* triangles are trying to add curvature, a flag has been added to ensure curvature can
|
|||
|
* be applied only once at a given pixel.
|
|||
|
*
|
|||
|
* The resulting normal is then stored as two angles, theta and phi, in the bumpmap along
|
|||
|
* with the colour of the texture.
|
|||
|
*
|
|||
|
* Finally, bumpmaps are rendered through a template parameter in the 'LineLinearTex.hpp'
|
|||
|
* module. To render the bumpmap, the directional lighting normal for the polygon is
|
|||
|
* calculated and transformed to texture space. The lighting normal is then broken up into
|
|||
|
* its theta and phi values. The phi of the light is then combined with the address of the
|
|||
|
* conversion table to generate a pointer into the table. This pointer is a constant value
|
|||
|
* for the entire polygon.
|
|||
|
*
|
|||
|
* The theta of the light is then subtracted from the theta of the bumpmap. The resulting
|
|||
|
* theta value is combined with the phi of the bumpmap, and used as an index into the
|
|||
|
* section of the table described by the previously generated pointer. The value returned
|
|||
|
* from the table is an intensity, which is combined with the pixel's colour (and,
|
|||
|
* optionally, the fogging value at that point), and used as the clut index.
|
|||
|
*
|
|||
|
* Lights other than directional lights can also be implemented by using a secondary table
|
|||
|
* of only 32 bytes in size.
|
|||
|
*
|
|||
|
* To do:
|
|||
|
* Replace the code to test if curvature should be applied to a triangle in 'ApplyCurves'
|
|||
|
* with an appropriate function in the mesh.
|
|||
|
* Work directly with heightfield normals and curvature normals when building the bumpmap,
|
|||
|
* instead of converting heightfield normals to angles and back to normals when combining
|
|||
|
* the basic bumpmap with curvature. Alternatively, the angles generated by the
|
|||
|
* heightfield could be converted quickly to the 'CAngle' format and the rotations applied
|
|||
|
* directly.
|
|||
|
* Interpolate to generate values for the edges.
|
|||
|
* Delete the 'DrawBumpTest' function once the loader integrates bumpmapping.
|
|||
|
* Make pbumpCreateUniqueBumpap create a single texture with gaps, rather than a new texture
|
|||
|
* for each triangle. This allows triangles to share a single surface again.
|
|||
|
*
|
|||
|
* Optional to do:
|
|||
|
*
|
|||
|
* Add filters for preprocessing bumpmaps.
|
|||
|
* Use curve fitting for height-field to bumpmap conversion.
|
|||
|
*
|
|||
|
***********************************************************************************************
|
|||
|
*
|
|||
|
* $Log:: /JP2_PC/Source/Lib/Renderer/Primitives/FastBump.hpp $
|
|||
|
*
|
|||
|
* 46 98.08.26 6:56p Mmouni
|
|||
|
* Added declaration for FastBumpCleanup().
|
|||
|
*
|
|||
|
* 45 8/25/98 2:34p Rvande
|
|||
|
* removed redundant class scope
|
|||
|
*
|
|||
|
* 44 98.07.08 12:11p Mmouni
|
|||
|
* Moved CPixelFormatBumpMap here from the .cpp file.
|
|||
|
*
|
|||
|
* 43 98.05.21 4:39p Mmouni
|
|||
|
* Change iCURVE_BIT to 15 from 16 so that it could be represented in a word.
|
|||
|
*
|
|||
|
* 42 1/19/98 7:30p Pkeet
|
|||
|
* Added support for 16 bit bumpmaps by adding lower colour resolution and a smaller size for
|
|||
|
* 'CBumpAnglePair.'
|
|||
|
*
|
|||
|
* 41 97/11/24 16:58 Speter
|
|||
|
* Reduced bump resolution 1 bit per dimension, for 16-bit bump-maps. fGetPhi[B,L] now access
|
|||
|
* BumpTable conversion arrays.
|
|||
|
*
|
|||
|
* 40 97/09/18 20:54 Speter
|
|||
|
* Changed behaviour of SetBump(b_light_phi) flag. Separated fGetPhi() into B and L versions.
|
|||
|
*
|
|||
|
* 39 97/08/11 10:12p Pkeet
|
|||
|
* Added the 'dir3MakeNormalFast' member function to CBumpAnglePair.
|
|||
|
*
|
|||
|
* 38 97/08/11 17:59 Speter
|
|||
|
* Changed CBumpAnglePair uint32 conversion operator to simply return value; much more
|
|||
|
* manageable.
|
|||
|
*
|
|||
|
* 37 97/08/08 6:11p Pkeet
|
|||
|
* Gave the 'SetBump' member function an optional parameter to set the light phi.
|
|||
|
*
|
|||
|
* 36 97-05-06 15:53 Speter
|
|||
|
* Now store bump curves using optimised axis-swap bump transform
|
|||
|
*
|
|||
|
* 35 97/03/24 15:23 Speter
|
|||
|
* Now explicitly differentiate PHI_L from PHI_B in constants and usage (rather than just using
|
|||
|
* PHI), allowing them to vary arbitrarily.
|
|||
|
*
|
|||
|
* 34 97/02/19 10:38 Speter
|
|||
|
* Changed CBumpMap constructor which takes a solid colour to take a TPixel rather than CColour.
|
|||
|
*
|
|||
|
* 33 97/02/07 19:11 Speter
|
|||
|
* Replaced r3ObjToTexture with faster, better mx3ObjToTexture, propagated change.
|
|||
|
*
|
|||
|
* 32 97/02/03 3:50p Pkeet
|
|||
|
* Added 'ApplyCurves' test to do.
|
|||
|
*
|
|||
|
* 31 1/29/97 12:18p Pkeet
|
|||
|
* Added code for using object space for bumpmap normals. Added code for subdividing triangles
|
|||
|
* to use the face normals.
|
|||
|
*
|
|||
|
* 30 1/28/97 2:29p Pkeet
|
|||
|
* Reduced theta to 7 bits.
|
|||
|
*
|
|||
|
* 29 1/27/97 4:47p Pkeet
|
|||
|
* Temporarilty increased the theta range to eight bits.
|
|||
|
*
|
|||
|
* 28 97/01/10 17:30 Speter
|
|||
|
* Updated for new raster classes.
|
|||
|
*
|
|||
|
* 27 1/08/97 7:43p Pkeet
|
|||
|
* Removed a semicolon from a parameter in a CBump constructor.
|
|||
|
*
|
|||
|
* 26 97/01/07 12:04 Speter
|
|||
|
* Changed CMesh to use rptr<>.
|
|||
|
*
|
|||
|
* 25 96/12/31 17:02 Speter
|
|||
|
* Updated for rptr.
|
|||
|
*
|
|||
|
* 24 96/12/02 18:52 Speter
|
|||
|
* Added to do.
|
|||
|
*
|
|||
|
* 23 96/11/27 19:33 Speter
|
|||
|
* Fixed bump angle conversion so that phi spans the full range -pi/2 to pi/2.
|
|||
|
*
|
|||
|
* 22 96/11/20 11:53 Speter
|
|||
|
* Added constructor for CBumpAnglePair from CDir3<>.
|
|||
|
*
|
|||
|
* 21 96/11/11 18:51 Speter
|
|||
|
* Replaced misleading operator =(CDir3<>) with SetBump(CDir3<>) function. Added u4GetBump().
|
|||
|
* Fixed SetColour() to clear the colour field before oring it in.
|
|||
|
* Changed iCURVE_MASK to iMASK_CURVE to match other mask constants.
|
|||
|
*
|
|||
|
* 20 11/07/96 3:28p Pkeet
|
|||
|
* Added the 'r3ObjToTexture' function. Changed the default value for bumpiness.
|
|||
|
*
|
|||
|
* 19 11/05/96 7:04p Pkeet
|
|||
|
* Added a constructor that uses the width and height.
|
|||
|
*
|
|||
|
* 18 10/14/96 10:05a Pkeet
|
|||
|
* Added the 'uint32' conversion operator.
|
|||
|
*
|
|||
|
* 17 96/10/04 18:02 Speter
|
|||
|
* Added necessary include of Texture.hpp.
|
|||
|
*
|
|||
|
* 16 96/09/27 11:31 Speter
|
|||
|
* Oops. Changed <float> in geometry types to <>.
|
|||
|
*
|
|||
|
* 15 9/24/96 2:57p Pkeet
|
|||
|
* Added comments to meet coding standards.
|
|||
|
*
|
|||
|
* 14 9/18/96 5:11p Pkeet
|
|||
|
* Implemented the 'DrawBump' procedure.
|
|||
|
*
|
|||
|
* 13 96/09/16 11:41 Speter
|
|||
|
* Simplified CBumpMap class to be just a raster.
|
|||
|
*
|
|||
|
* 12 96/09/13 14:28 Speter
|
|||
|
* Removed some unneeded includes and extern statements.
|
|||
|
* Moved some inline code into .cpp file, so that FastBumpMath.hpp no longer needed.
|
|||
|
*
|
|||
|
*
|
|||
|
* 11 9/12/96 4:20p Pkeet
|
|||
|
* Added 'uint8* au1_table' parameter to 'pu1GetSubBumpTable' member function.
|
|||
|
*
|
|||
|
* 10 9/12/96 3:16p Pkeet
|
|||
|
* Reduced size of bumpmap to intensity table by half because bumpmap phi values can be positive
|
|||
|
* only.
|
|||
|
*
|
|||
|
* 9 9/11/96 3:02p Pkeet
|
|||
|
* Moved bumapping table and generation function to 'FastBumpTable.hpp' module.
|
|||
|
*
|
|||
|
* 8 9/11/96 11:37a Pkeet
|
|||
|
* Changed 'SetPhi' and 'GetPhi' member functions to use bitfields instead of shift-masks. This
|
|||
|
* is a temporary measure to get the code to work because previous code did not maintain the
|
|||
|
* sign bit.
|
|||
|
*
|
|||
|
* 7 9/06/96 6:01p Pkeet
|
|||
|
* Moved lookup functions to external assembly routines.
|
|||
|
*
|
|||
|
* 6 9/05/96 6:34p Pkeet
|
|||
|
* Changed bumpmap to use the 'CRasterSimple' class. Added lighting parameters to the
|
|||
|
* 'MakeBumpmap' Table function.
|
|||
|
*
|
|||
|
* 5 9/05/96 2:28p Pkeet
|
|||
|
* Added texturing to bumpmapping.
|
|||
|
*
|
|||
|
* 4 9/04/96 5:16p Pkeet
|
|||
|
* Added file-based bumpmaps.
|
|||
|
*
|
|||
|
* 3 8/30/96 2:57p Pkeet
|
|||
|
* Moved trigonometric functions to "FastBumpMath" module.
|
|||
|
*
|
|||
|
* 2 8/30/96 1:02p Pkeet
|
|||
|
* Added fast arcsin conversion for phi.
|
|||
|
*
|
|||
|
* 1 8/29/96 5:53p Pkeet
|
|||
|
* Initial implementation.
|
|||
|
*
|
|||
|
**********************************************************************************************/
|
|||
|
|
|||
|
#ifndef HEADER_LIB_RENDERER_PRIMITIVES_FASTBUMP_HPP
|
|||
|
#define HEADER_LIB_RENDERER_PRIMITIVES_FASTBUMP_HPP
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Includes.
|
|||
|
//
|
|||
|
#include "Lib/View/Raster.hpp"
|
|||
|
#include "Lib/Renderer/Texture.hpp"
|
|||
|
#include "Lib/Transform/Transform.hpp"
|
|||
|
#include "Lib/GeomDBase/Mesh.hpp"
|
|||
|
|
|||
|
//
|
|||
|
// Defines.
|
|||
|
//
|
|||
|
|
|||
|
// Bumpmap table sizes.
|
|||
|
#define iTHETA_BITS (6)
|
|||
|
#define iPHI_L_BITS (6)
|
|||
|
#define iPHI_B_BITS (4)
|
|||
|
|
|||
|
// Minimum and maximum angle values.
|
|||
|
#define iMIN_THETA (0)
|
|||
|
#define iMAX_THETA ((1 << iTHETA_BITS) - 1)
|
|||
|
#define iMAX_PHI_L ((1 << (iPHI_L_BITS - 1)) - 1)
|
|||
|
#define iMIN_PHI_L (-iMAX_PHI_L)
|
|||
|
#define iMAX_PHI_B ((1 << iPHI_B_BITS) - 1)
|
|||
|
#define iMIN_PHI_B (0)
|
|||
|
|
|||
|
// Shift values.
|
|||
|
#define iSHIFT_PHI_B (0)
|
|||
|
#define iSHIFT_THETA (iSHIFT_PHI_B + iPHI_B_BITS)
|
|||
|
#define iSHIFT_PHI_L (iSHIFT_THETA + iTHETA_BITS)
|
|||
|
|
|||
|
// Sign bit for PhiL.
|
|||
|
#define iSIGN_BIT_PHI_L (1 << (iSHIFT_PHI_L + iPHI_L_BITS - 1))
|
|||
|
|
|||
|
// Masks.
|
|||
|
#define iMASK_THETA (((1 << iTHETA_BITS) - 1) << iSHIFT_THETA)
|
|||
|
#define iMASK_PHI_B (((1 << iPHI_B_BITS) - 1) << iSHIFT_PHI_B)
|
|||
|
#define iMASK_PHI_L (((1 << iPHI_L_BITS) - 1) << iSHIFT_PHI_L)
|
|||
|
#define iMASK_ANGLETABLE_LOOKUP ((1 << (iTHETA_BITS + iPHI_B_BITS)) - 1)
|
|||
|
|
|||
|
|
|||
|
// Bumpmap to intensity lookup table size.
|
|||
|
#define iBUMP_TABLE_SIZE (1 << (iTHETA_BITS + iPHI_L_BITS + iPHI_B_BITS))
|
|||
|
|
|||
|
// Default bumpiness value for heightfield to bumpmap conversions.
|
|||
|
#define fDEFAULT_BUMPINESS (0.025f)
|
|||
|
|
|||
|
// Subdivides the bumps with the face normal if true.
|
|||
|
#define bSUBDIVIDE_BUMPS (0)
|
|||
|
|
|||
|
#if iBUMPMAP_RESOLUTION == 16
|
|||
|
|
|||
|
// NOTE: iCURVE_BIT is shared with the color.
|
|||
|
#define iCURVE_BIT (15)
|
|||
|
#define iMASK_COLOUR (0xFC00)
|
|||
|
#define iBUMPMAP_COLOURBITS (6)
|
|||
|
#define iSHIFT_COLOUR (iTHETA_BITS + iPHI_B_BITS)
|
|||
|
|
|||
|
typedef uint16 TBumpRes;
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
#define iCURVE_BIT (22)
|
|||
|
#define iMASK_COLOUR 0xFF000000
|
|||
|
#define iBUMPMAP_COLOURBITS (8)
|
|||
|
#define iSHIFT_COLOUR ((sizeof(int32) - sizeof(uint8)) * 8)
|
|||
|
|
|||
|
typedef uint32 TBumpRes;
|
|||
|
|
|||
|
#endif // iBUMPMAP_RESOLUTION
|
|||
|
|
|||
|
// Curvature added flag.
|
|||
|
#define iMASK_CURVE (1 << iCURVE_BIT)
|
|||
|
#define iMASK_BUMP (iMASK_CURVE - 1)
|
|||
|
|
|||
|
//
|
|||
|
// Class definitions.
|
|||
|
//
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
class CBumpAnglePair
|
|||
|
//
|
|||
|
// Class describes a bumpmap pixel containing an indexed colour value and polar coordinates.
|
|||
|
//
|
|||
|
// Prefix: bang
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
TBumpRes br; // Colour and angle information.
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
// Constructors.
|
|||
|
//
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
CBumpAnglePair
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Default constructor.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
br = 0;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
CBumpAnglePair
|
|||
|
(
|
|||
|
uint u_value
|
|||
|
)
|
|||
|
//
|
|||
|
// Default constructor with value.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
br = u_value;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
CBumpAnglePair
|
|||
|
(
|
|||
|
int i_phi,
|
|||
|
uint u_theta
|
|||
|
)
|
|||
|
//
|
|||
|
// Construct from an angle pair.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
br = 0;
|
|||
|
SetTheta(u_theta);
|
|||
|
SetPhiB(i_phi);
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
CBumpAnglePair
|
|||
|
(
|
|||
|
const CDir3<>& rdir3
|
|||
|
)
|
|||
|
//
|
|||
|
// Construct from a normal.
|
|||
|
//
|
|||
|
//**********************************
|
|||
|
{
|
|||
|
br = 0;
|
|||
|
SetBump(rdir3);
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
// Member functions to set or get states.
|
|||
|
//
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
operator TBumpRes const
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns the value.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return br;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void SetTheta
|
|||
|
(
|
|||
|
uint u_theta
|
|||
|
)
|
|||
|
//
|
|||
|
// Sets the theta value.
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
// Error checking is not required for theta's range because it will automatically
|
|||
|
// wrap around.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
// Set the bits representing theta to zero.
|
|||
|
br &= ~iMASK_THETA;
|
|||
|
|
|||
|
// Shift the bits representing the new theta into position.
|
|||
|
br |= (u_theta << iSHIFT_THETA) & iMASK_THETA;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void SetPhiB
|
|||
|
//
|
|||
|
(
|
|||
|
int i_phi
|
|||
|
)
|
|||
|
//
|
|||
|
// Sets the lower phi value. This function will clamp the phi value so that it can only be
|
|||
|
// positive.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
Assert(bWithin(i_phi, -iMAX_PHI_B, iMAX_PHI_B));
|
|||
|
|
|||
|
// Clamp phi to a positive value.
|
|||
|
SetMax(i_phi, 0);
|
|||
|
|
|||
|
// Set the bits representing the bumpmap's phi to zero.
|
|||
|
br &= ~iMASK_PHI_B;
|
|||
|
|
|||
|
// Shift the bits representing the new phi into position.
|
|||
|
br |= (i_phi << iSHIFT_PHI_B) & iMASK_PHI_B;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void SetPhiL
|
|||
|
(
|
|||
|
int i_phi
|
|||
|
)
|
|||
|
//
|
|||
|
// Sets the lower phi value.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
Assert(bWithin(i_phi, iMIN_PHI_L, iMAX_PHI_L));
|
|||
|
|
|||
|
// Set the values representing the light's phi to zero.
|
|||
|
br &= ~iMASK_PHI_L;
|
|||
|
|
|||
|
// Shift the light's phi value and or it in.
|
|||
|
br |= (i_phi << iSHIFT_PHI_L) & iMASK_PHI_L;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void SetBump
|
|||
|
(
|
|||
|
CBumpAnglePair bang
|
|||
|
)
|
|||
|
//
|
|||
|
// Copies just the bump info.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
br &= ~iMASK_BUMP;
|
|||
|
br |= bang.brGetBump();
|
|||
|
}
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
void SetBump
|
|||
|
(
|
|||
|
const CDir3<>& rdir3,
|
|||
|
bool b_set_light_phi = false // Whether to set as light angle; else bump angle.
|
|||
|
);
|
|||
|
//
|
|||
|
// Converts a normal into a pair of angles. Stores the phi value as either a light phi
|
|||
|
// or bump phi, depending on b_set_light_phi.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void SetColour
|
|||
|
(
|
|||
|
uint8 u1_colour // Colour represented by a palette index value.
|
|||
|
)
|
|||
|
//
|
|||
|
// Sets the index colour.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
br &= ~iMASK_COLOUR;
|
|||
|
br |= (uint32)u1_colour << iSHIFT_COLOUR;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void SetCurveFlag
|
|||
|
(
|
|||
|
bool b_curve = true
|
|||
|
)
|
|||
|
//
|
|||
|
// Sets a flag indicating that curvature has been applied to a pixel.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
br &= ~iMASK_CURVE;
|
|||
|
br |= (b_curve) ? (iMASK_CURVE) : (0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
// Member functions to get states.
|
|||
|
//
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
uint uGetTheta
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns the value of theta.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return (br & iMASK_THETA) >> iSHIFT_THETA;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
TBumpRes brIsolateTheta
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns the value of theta shifted to its representative position.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return br & iMASK_THETA;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
int iGetPhiB
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns the bumpmap's phi value.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return (br & iMASK_PHI_B) >> iSHIFT_PHI_B;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
int iGetPhiL
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns the light's phi value.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
int32 i4_PhiL; // Storage for return value.
|
|||
|
|
|||
|
// If phi is negative, make sure that the sign bit is carried.
|
|||
|
if (br & iSIGN_BIT_PHI_L)
|
|||
|
{
|
|||
|
i4_PhiL = -1;
|
|||
|
i4_PhiL &= ~iMASK_PHI_L;
|
|||
|
i4_PhiL |= br;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
i4_PhiL = br;
|
|||
|
}
|
|||
|
i4_PhiL >>= iSHIFT_PHI_L;
|
|||
|
return i4_PhiL;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
TBumpRes brGetBump
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns the total bump angle information.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return br & iMASK_BUMP;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
uint8 u1GetColour
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns the index colour value.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return br >> iSHIFT_COLOUR;
|
|||
|
}
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
bool bGetCurveFlag
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns 'true' if the curvature has already been added to the pixel, otherwise returns
|
|||
|
// 'false.'
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return (br & iMASK_CURVE) != 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
// Other member functions.
|
|||
|
//
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
CDir3<> dir3MakeNormal
|
|||
|
(
|
|||
|
);
|
|||
|
//
|
|||
|
// Returns the normal described by the angle pair.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
CDir3<> dir3MakeNormalFast
|
|||
|
(
|
|||
|
);
|
|||
|
//
|
|||
|
// Returns the normal described by the angle pair.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
float fGetPhiB
|
|||
|
(
|
|||
|
);
|
|||
|
//
|
|||
|
// Gets the phi bump angle in radians.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
float fGetPhiL
|
|||
|
(
|
|||
|
);
|
|||
|
//
|
|||
|
// Gets the phi light angle in radians.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
float fGetTheta
|
|||
|
(
|
|||
|
)
|
|||
|
//
|
|||
|
// Gets the theta angle in radians.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
return float(uGetTheta()) * float(d2_PI) / float(1 << iTHETA_BITS);
|
|||
|
}
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
uint8* pu1GetSubBumpTable
|
|||
|
(
|
|||
|
uint8* au1_table // Table containing intensity or arccos values.
|
|||
|
)
|
|||
|
//
|
|||
|
// Returns a pointer to the location in the bumpmap to intensity table base on phi.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
Assert(au1_table);
|
|||
|
|
|||
|
CBumpAnglePair bangp_index;
|
|||
|
|
|||
|
// Set the phi lighting value.
|
|||
|
bangp_index.SetPhiL(iGetPhiL());
|
|||
|
|
|||
|
// Return the position in the table referenced by the index value.
|
|||
|
return &au1_table[bangp_index.br];
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
class CBumpMap: public CRasterMemT<CBumpAnglePair>
|
|||
|
//
|
|||
|
// A raster containing a bumpmap.
|
|||
|
//
|
|||
|
// Prefix: bmap
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
private:
|
|||
|
|
|||
|
typedef CRasterMemT<CBumpAnglePair> TParent;
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
static CMatrix3<> mx3Reverse; // Reverse transform for the bumpmap.
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
// Constructor.
|
|||
|
//
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
CBumpMap
|
|||
|
(
|
|||
|
char* str_height_filename, // Bumpmap (heightfield) bitmap file name.
|
|||
|
char* str_texture_filename, // Texture bitmap file name.
|
|||
|
float f_bumpiness = fDEFAULT_BUMPINESS // Value to multiply height by to get vertical
|
|||
|
// value in pixels.
|
|||
|
);
|
|||
|
//
|
|||
|
// Constructs a bumpmap given filenames to a height map and texture map.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
CBumpMap
|
|||
|
(
|
|||
|
int i_width, // Height of bumpmap.
|
|||
|
int i_height, // Width of bumpmap.
|
|||
|
const CPal* ppal, // Pointer to a palette.
|
|||
|
TPixel pix_solid = 0 // Entry in palette to use.
|
|||
|
);
|
|||
|
//
|
|||
|
// Constructs a bumpmap of a solid colour given a width, a height and a palette.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
CBumpMap
|
|||
|
(
|
|||
|
rptr<CRaster> pras_heightmap, // Height field representing bumpmap.
|
|||
|
rptr<CRaster> pras_texture, // Bitmap representing texture.
|
|||
|
float f_bumpiness = fDEFAULT_BUMPINESS // Value to multiply height by to get
|
|||
|
// vertical value in pixels.
|
|||
|
);
|
|||
|
//
|
|||
|
// Constructs a bumpmap given rasters representing a height map and a texture map.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
// Member functions.
|
|||
|
//
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void DrawBump
|
|||
|
(
|
|||
|
CTexCoord tc_0, // Position and normal for vertex 0.
|
|||
|
CDir3<> dir3_normal_0,
|
|||
|
CTexCoord tc_1, // Position and normal for vertex 1.
|
|||
|
CDir3<> dir3_normal_1,
|
|||
|
CTexCoord tc_2, // Position and normal for vertex 2.
|
|||
|
CDir3<> dir3_normal_2,
|
|||
|
const CMatrix3<>& mx3_reverse // Reverse transform.
|
|||
|
);
|
|||
|
//
|
|||
|
// Draws a bump on a bumpmap surface by interpolating normals at each of the vertices.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void DrawBumps
|
|||
|
(
|
|||
|
CTexCoord tc_0, // Position and normal for vertex 0.
|
|||
|
CDir3<> dir3_normal_0,
|
|||
|
CTexCoord tc_1, // Position and normal for vertex 1.
|
|||
|
CDir3<> dir3_normal_1,
|
|||
|
CTexCoord tc_2, // Position and normal for vertex 2.
|
|||
|
CDir3<> dir3_normal_2,
|
|||
|
CDir3<> dir3_normal_face, // Normal for newly created vertex
|
|||
|
// (usually the face normal).
|
|||
|
const CMatrix3<>& mx3_reverse // Reverse transform.
|
|||
|
);
|
|||
|
//
|
|||
|
// Draws a bump on a bumpmap surface by splitting the triangle into three, and using the
|
|||
|
// face normal as the new vertex normals. In theory, this should provide a better curve
|
|||
|
// 'fit.'
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
protected:
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void DrawBumpTest();
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void AddHeightField(rptr<CRaster> pras_heightmap, float f_bumpiness = 0.1f);
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void AddTexture(rptr<CRaster> pras_texture);
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Bump curvature definitions.
|
|||
|
//
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
CMatrix3<> mx3ObjToTexture
|
|||
|
(
|
|||
|
const CVector3<>& v3_0,
|
|||
|
const CVector3<>& v3_1,
|
|||
|
const CVector3<>& v3_2,
|
|||
|
const CDir3<>& d3,
|
|||
|
const CTexCoord& tc_0,
|
|||
|
const CTexCoord& tc_1,
|
|||
|
const CTexCoord& tc_2
|
|||
|
);
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void SwapAxesVertical
|
|||
|
(
|
|||
|
CVector3<>& v3,
|
|||
|
const CDir3<>& d3_control
|
|||
|
);
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void SwapAxesVertical
|
|||
|
(
|
|||
|
CMatrix3<>& mx3,
|
|||
|
const CDir3<>& d3_control
|
|||
|
);
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
void ApplyCurves
|
|||
|
(
|
|||
|
rptr<CMesh> pmsh
|
|||
|
);
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
void FastBumpCleanup();
|
|||
|
//
|
|||
|
// Cleanup anything that has been allocated by bump map creation.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
//
|
|||
|
class CPixelFormatBumpmap: public CPixelFormat
|
|||
|
//
|
|||
|
// Modification of CPixelFormat palette which extracts colour index from CBumpAnglePair.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
public:
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
CPixelFormatBumpmap()
|
|||
|
: CPixelFormat(iBUMPMAP_RESOLUTION, 0, 0, 0, true)
|
|||
|
{
|
|||
|
// Make sure it's the same size as its base class, because we copy different version
|
|||
|
// of CPixelFormat around to each other.
|
|||
|
Assert(sizeof(*this) == sizeof(CPixelFormat));
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
//
|
|||
|
// Overrides.
|
|||
|
//
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
TPixel pixFromColour(CColour clr) const
|
|||
|
{
|
|||
|
// Do a palette search to find best match to clr.
|
|||
|
// Return a CBumpAnglePair with default angles.
|
|||
|
CBumpAnglePair bang;
|
|||
|
|
|||
|
Assert(ppalAttached);
|
|||
|
bang.SetColour(ppalAttached->u1MatchEntry(clr));
|
|||
|
|
|||
|
// Set a dummy bump value to avoid generating a value of 0.
|
|||
|
bang.SetTheta(1);
|
|||
|
return bang;
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
CColour clrFromPixel(TPixel pix) const
|
|||
|
{
|
|||
|
// Just extract colour from bump angle, and look up in palette.
|
|||
|
int i_index = ((CBumpAnglePair&)pix).u1GetColour();
|
|||
|
|
|||
|
Assert(ppalAttached);
|
|||
|
return ppalAttached->aclrPalette[i_index];
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
#endif
|