This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/ww3d2/matrixmapper.cpp

262 lines
No EOL
15 KiB
C++

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWPhys *
* *
* $Archive:: /Commando/Code/ww3d2/matrixmapper.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 6/21/01 10:32a $*
* *
* $Revision:: 10 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* MatrixMapperClass::MatrixMapperClass -- Constructor *
* MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
* MatrixMapperClass::Update_View_To_Pixel_Transform -- recomputes ViewToPixel *
* MatrixMapperClass::Compute_Texture_Coordinate -- compute a single texture coord *
* MatrixMapperClass::isActive -- check if this mapper should be active *
* MatrixMapperClass::process -- process the given VertexPipe *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "matrixmapper.h"
#include "dx8wrapper.h"
/***********************************************************************************************
* MatrixMapperClass::MatrixMapperClass -- Constructor *
* *
* Initializes the member variables to defaults *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/13/99 gth : created *
*=============================================================================================*/
MatrixMapperClass::MatrixMapperClass(int stage) :
TextureMapperClass(stage),
Flags(0),
ViewToTexture(true),
ViewToPixel(true),
GradientUCoord(0.5f)
{
ViewSpaceProjectionNormal = Vector3(0.0f,0.0f,0.0f);
}
/***********************************************************************************************
* MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/20/2001 gth : created *
*=============================================================================================*/
void MatrixMapperClass::Set_Texture_Transform(const Matrix3D & view_to_texture,float texsize)
{
ViewToTexture = Matrix4(view_to_texture);
Update_View_To_Pixel_Transform(texsize);
}
/***********************************************************************************************
* MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 11/13/99 gth : Created. *
*=============================================================================================*/
void MatrixMapperClass::Set_Texture_Transform(const Matrix4 & view_to_texture,float texsize)
{
ViewToTexture=view_to_texture;
Update_View_To_Pixel_Transform(texsize);
}
/***********************************************************************************************
* MatrixMapperClass::Update_View_To_Pixel_Transform -- recomputes ViewToPixel *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 1/4/00 gth : Created. *
*=============================================================================================*/
void MatrixMapperClass::Update_View_To_Pixel_Transform(float tex_size)
{
/*
** Create a ViewToPixel matrix which also does all of the offseting and flipping that has
** to take place to get the actual texture coordinates.
**
** Here is a description of the math:
** If you transform eye-space points with the ViewToTexture matrix, you then need to compute:
** s = ((x/w) + 1.0f) * 0.5f * ((texwid-2)/texwid)
** t = (1.0f - (y/w)) * 0.5f * ((texwid-2)/texwid)
**
** Let K = 0.5 * ((texwid-2)/texwid), Then:
** ((x/w) + 1.0f) * K = (K*x + K*w) / w
** (1.0f - (y/w)) * K = (-K*y + K*w) / w
**
** This leads to the following matrix (The KOOK matrix!)
** | K 0 0 K |
** | 0 -K 0 K |
** | 0 0 1 0 |
** | 0 0 0 1 |
**
** The code below manually "optimally" pre-multiplies this matrix with the ViewToTexture matrix
**
** In addition, the z-coordinate is modified so that it goes from 0 to 1 rather than -1 to +1.
** It can also be flipped if the INVERT_DEPTH_GRADIENT flag is on.
*/
float k = 0.5 * (tex_size - 2.0f) / tex_size;
ViewToPixel[0][0] = k * ViewToTexture[0][0] + k * ViewToTexture[3][0];
ViewToPixel[0][1] = k * ViewToTexture[0][1] + k * ViewToTexture[3][1];
ViewToPixel[0][2] = k * ViewToTexture[0][2] + k * ViewToTexture[3][2];
ViewToPixel[0][3] = k * ViewToTexture[0][3] + k * ViewToTexture[3][3];
ViewToPixel[1][0] = -k * ViewToTexture[1][0] + k * ViewToTexture[3][0];
ViewToPixel[1][1] = -k * ViewToTexture[1][1] + k * ViewToTexture[3][1];
ViewToPixel[1][2] = -k * ViewToTexture[1][2] + k * ViewToTexture[3][2];
ViewToPixel[1][3] = -k * ViewToTexture[1][3] + k * ViewToTexture[3][3];
if (Get_Flag(INVERT_DEPTH_GRADIENT)) {
ViewToPixel[2][0] = -0.5f * ViewToTexture[2][0] + 0.5f * ViewToTexture[3][0];
ViewToPixel[2][1] = -0.5f * ViewToTexture[2][1] + 0.5f * ViewToTexture[3][1];
ViewToPixel[2][2] = -0.5f * ViewToTexture[2][2] + 0.5f * ViewToTexture[3][2];
ViewToPixel[2][3] = -0.5f * ViewToTexture[2][3] + 0.5f * ViewToTexture[3][3];
} else {
ViewToPixel[2][0] = 0.5f * ViewToTexture[2][0] + 0.5f * ViewToTexture[3][0];
ViewToPixel[2][1] = 0.5f * ViewToTexture[2][1] + 0.5f * ViewToTexture[3][1];
ViewToPixel[2][2] = 0.5f * ViewToTexture[2][2] + 0.5f * ViewToTexture[3][2];
ViewToPixel[2][3] = 0.5f * ViewToTexture[2][3] + 0.5f * ViewToTexture[3][3];
}
ViewToPixel[3] = ViewToTexture[3];
/*
** Store the view space negative z vector for lighting effects
*/
ViewSpaceProjectionNormal.X = -ViewToTexture[2][0];
ViewSpaceProjectionNormal.Y = -ViewToTexture[2][1];
ViewSpaceProjectionNormal.Z = -ViewToTexture[2][2];
ViewSpaceProjectionNormal.Normalize();
}
/***********************************************************************************************
* MatrixMapperClass::Compute_Texture_Coordinate -- compute a single texture coord *
* *
* INPUT: *
* point - 3D point to calculate the texture coordinate for *
* set_stq - pointer to texture coordinate, s,t will be stored in X,Y. q will be stored in Z *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 1/25/00 gth : Created. *
*=============================================================================================*/
void MatrixMapperClass::Compute_Texture_Coordinate(const Vector3 & point,Vector3 * set_stq)
{
set_stq->X = ViewToPixel[0][0]*point.X + ViewToPixel[0][1]*point.Y + ViewToPixel[0][2]*point.Z + ViewToPixel[0][3];
set_stq->Y = ViewToPixel[1][0]*point.X + ViewToPixel[1][1]*point.Y + ViewToPixel[1][2]*point.Z + ViewToPixel[1][3];
set_stq->Z = ViewToPixel[3][0]*point.X + ViewToPixel[3][1]*point.Y + ViewToPixel[3][2]*point.Z + ViewToPixel[3][3];
}
void MatrixMapperClass::Apply(int uv_array_index)
{
Matrix4 m;
switch (Type)
{
case ORTHO_PROJECTION:
/*
** Orthographic projection
*/
DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),ViewToPixel);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
break;
case PERSPECTIVE_PROJECTION:
/*
** Perspective projection
*/
m[0]=ViewToPixel[0];
m[1]=ViewToPixel[1];
m[2]=ViewToPixel[3];
DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_PROJECTED|D3DTTFF_COUNT3);
break;
case DEPTH_GRADIENT:
/*
** Depth gradient, Set up second stage texture coordinates to
** apply a depth gradient to the projection. Note that the
** depth values have been set up to vary from 0 to 1 in the
** Update_View_To_Pixel_Transform function.
*/
m[0].Set(0,0,0,GradientUCoord);
m[1]=ViewToPixel[2];
DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
break;
case NORMAL_GRADIENT:
/*
** Normal Gradient, Set up the second stage texture coordinates to
** apply a gradient based on the dot product of the vertex normal
** and the projection direction. (NOTE: this is basically texture-
** based diffuse lighting!)
*/
m[0].Set(0,0,0,GradientUCoord);
m[1].Set(ViewSpaceProjectionNormal.X,ViewSpaceProjectionNormal.Y,ViewSpaceProjectionNormal.Z, 0);
DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
DX8Wrapper::Set_DX8_Texture_Stage_State(uv_array_index,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
break;
}
}