| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005 |
- /*
- ** 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 : G *
- * *
- * $Archive:: /VSS_Sync/ww3d2/mapper.cpp $*
- * *
- * $Author:: Vss_sync $*
- * *
- * $Modtime:: 10/29/01 3:30p $*
- * *
- * $Revision:: 34 $*
- * *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "mapper.h"
- #include "ww3d.h"
- #include "ini.h"
- #include "chunkio.h"
- #include "w3derr.h"
- #include "meshmatdesc.h"
- #include "dx8wrapper.h"
- #include "wwdebug.h"
- #include "matinfo.h"
- #include "rendobj.h"
- #include "mesh.h"
- #include <random.h>
- Random4Class rand4;
- inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
- // HY 1/26/01
- // Rewritten to use DX 8 texture matrices
- TextureMapperClass::TextureMapperClass(unsigned int stage)
- {
- Stage = stage;
- if (Stage >= MeshMatDescClass::MAX_TEX_STAGES) Stage = MeshMatDescClass::MAX_TEX_STAGES - 1;
- }
- LinearOffsetTextureMapperClass::LinearOffsetTextureMapperClass(const Vector2 &offset_per_sec, const Vector2 &scale, unsigned int stage) :
- ScaleTextureMapperClass(scale, stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time())
- {
- CurrentUVOffset.X = 0.0f;
- CurrentUVOffset.Y = 0.0f;
- // HY 5/16/01
- // This is horrible disgusting legacy from the unmentionable API we used before
- // leaving it unchanged because the artists have worked around it
- UVOffsetDeltaPerMS = offset_per_sec * -0.001f;
- }
- LinearOffsetTextureMapperClass::LinearOffsetTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- ScaleTextureMapperClass(ini,section,stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time())
- {
- CurrentUVOffset.X = 0.0f;
- CurrentUVOffset.Y = 0.0f;
- float u_offset_per_sec = ini.Get_Float(section, "UPerSec", 0.0f);
- float v_offset_per_sec = ini.Get_Float(section, "VPerSec", 0.0f);
- UVOffsetDeltaPerMS = Vector2(u_offset_per_sec, v_offset_per_sec) * -0.001f;
- }
- LinearOffsetTextureMapperClass::LinearOffsetTextureMapperClass(const LinearOffsetTextureMapperClass & src) :
- ScaleTextureMapperClass(src),
- UVOffsetDeltaPerMS(src.UVOffsetDeltaPerMS),
- LastUsedSyncTime(WW3D::Get_Sync_Time())
- {
- CurrentUVOffset.X = 0.0f;
- CurrentUVOffset.Y = 0.0f;
- }
- void LinearOffsetTextureMapperClass::Apply(int uv_array_index)
- {
- unsigned int delta = WW3D::Get_Sync_Time() - LastUsedSyncTime;
- float del = (float)delta;
- float offset_u = CurrentUVOffset.X + UVOffsetDeltaPerMS.X * del;
- float offset_v = CurrentUVOffset.Y + UVOffsetDeltaPerMS.Y * del;
- // ensure both coordinates of offset are in [0, 1] range:
- offset_u = offset_u - WWMath::Floor(offset_u);
- offset_v = offset_v - WWMath::Floor(offset_v);
- // Set up the offset matrix
- Matrix3D m(true);
-
- // According to the docs this should work since its 2D
- // otherwise change to translate
- m[0].Z=offset_u;
- m[0].X=Scale.X;
- m[1].Z=offset_v;
- m[1].Y=Scale.Y;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- // Update state
- CurrentUVOffset.X = offset_u;
- CurrentUVOffset.Y = offset_v;
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- }
- // Scale mapper
- // HY 5/16/01
- ScaleTextureMapperClass::ScaleTextureMapperClass(const Vector2 &scale, unsigned int stage) :
- TextureMapperClass(stage),
- Scale(scale)
- {
- }
- ScaleTextureMapperClass::ScaleTextureMapperClass(unsigned int stage) :
- TextureMapperClass(stage),
- Scale(1.0f,1.0f)
- {
- }
- ScaleTextureMapperClass::ScaleTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- TextureMapperClass(stage)
- {
- Scale.U = ini.Get_Float(section, "UScale", 1.0f);
- Scale.V = ini.Get_Float(section, "VScale", 1.0f);
- }
- ScaleTextureMapperClass::ScaleTextureMapperClass(const ScaleTextureMapperClass & src) :
- TextureMapperClass(src),
- Scale(src.Scale)
- {
- }
- void ScaleTextureMapperClass::Apply(int uv_array_index)
- {
- // Set up the scale matrix
- Matrix3D m(true);
-
- m[0].X=Scale.U;
- m[1].Y=Scale.V;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- // Grid Mapper
- // HY 5/16/01
- GridTextureMapperClass::GridTextureMapperClass(float fps, unsigned int gridwidth_log2, unsigned int stage) :
- TextureMapperClass(stage)
- {
- LastFrame = 0;
- initialize(fps, gridwidth_log2);
- }
- GridTextureMapperClass::GridTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- TextureMapperClass(stage)
- {
- float fps = ini.Get_Float(section,"FPS", 1.0f);
- unsigned int gridwidth_log2 = ini.Get_Int(section,"Log2Width", 1);
- LastFrame=ini.Get_Int(section,"Last",0);
- initialize(fps, gridwidth_log2);
- }
- GridTextureMapperClass::GridTextureMapperClass(const GridTextureMapperClass & src) :
- TextureMapperClass(src),
- Sign(src.Sign),
- MSPerFrame(src.MSPerFrame),
- OOGridWidth(src.OOGridWidth),
- GridWidthLog2(src.GridWidthLog2),
- LastFrame(src.LastFrame)
- {
- Reset();
- }
- void GridTextureMapperClass::Apply(int uv_array_index)
- {
- update_temporal_state();
- float u_offset, v_offset;
- calculate_uv_offset(&u_offset, &v_offset);
- // Set up the offset matrix
- Matrix3D m(true);
-
- // According to the docs this should work since its 2D
- // otherwise change to translate
- m[0].Z = u_offset;
- m[1].Z = v_offset;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage), m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
- }
- void GridTextureMapperClass::Reset(void)
- {
- Remainder = 0;
- CurrentFrame = Sign == -1 ? (1 << (GridWidthLog2 + GridWidthLog2)) - 1 : 0;
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- }
- void GridTextureMapperClass::Set_Frame_Per_Second(float fps)
- {
- initialize(fps, GridWidthLog2);
- }
- void GridTextureMapperClass::initialize(float fps, unsigned int gridwidth_log2)
- {
- unsigned int grid_width = (1 << gridwidth_log2);
- if (LastFrame == 0) LastFrame = (grid_width * grid_width);
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- GridWidthLog2 = gridwidth_log2;
- OOGridWidth = 1.0f / (float)(grid_width);
- if (fps == 0.0f) {
- // Value of MSPerFrame does not matter as long as it is not 0 - sign will multiply results,
- // zeroing them out.
- Sign = 0;
- MSPerFrame = 1;
- CurrentFrame = 0;
- } else if (fps < 0.0f) {
- Sign = -1;
- MSPerFrame = (unsigned int)(1000.0f / fabs(fps));
- CurrentFrame = LastFrame - 1;
- } else {
- Sign = 1;
- MSPerFrame = (unsigned int)(1000.0f / fabs(fps));
- CurrentFrame = 0;
- }
- Remainder = 0;
- }
- void GridTextureMapperClass::update_temporal_state(void)
- {
- unsigned int now = WW3D::Get_Sync_Time();
- unsigned int delta = now - LastUsedSyncTime;
- Remainder += delta;
- LastUsedSyncTime = now;
- int new_frame = (int)CurrentFrame + ((int)(Remainder / MSPerFrame) * Sign);
- new_frame=new_frame % LastFrame;
- if (new_frame<0) {
- CurrentFrame=LastFrame+new_frame;
- } else {
- CurrentFrame=(unsigned int) new_frame;
- }
- Remainder = Remainder % MSPerFrame;
- }
- void GridTextureMapperClass::calculate_uv_offset(float * u_offset, float * v_offset)
- {
- unsigned int row_mask = ~(0xFFFFFFFF << GridWidthLog2);
- unsigned int col_mask = row_mask << GridWidthLog2;
- unsigned int x = CurrentFrame & row_mask;
- unsigned int y = (CurrentFrame & col_mask) >> GridWidthLog2;
- *u_offset = x * OOGridWidth;
- *v_offset = y * OOGridWidth;
- }
- // Rotate Mapper
- // HY 5/16/01
- RotateTextureMapperClass::RotateTextureMapperClass(float rad_per_sec, const Vector2 ¢er, unsigned int stage) :
- ScaleTextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- CurrentAngle(0.0f),
- RadiansPerMilliSec(rad_per_sec/1000.0f),
- Center(center)
- {
- }
- RotateTextureMapperClass::RotateTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- ScaleTextureMapperClass(ini,section,stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- CurrentAngle(0.0f)
- {
- RadiansPerMilliSec=2*WWMATH_PI*ini.Get_Float(section,"Speed",0.1f)/1000.0f;
- Center.U=ini.Get_Float(section,"UCenter",0.0f);
- Center.V=ini.Get_Float(section,"VCenter",0.0f);
- }
- RotateTextureMapperClass::RotateTextureMapperClass(const RotateTextureMapperClass & src) :
- ScaleTextureMapperClass(src),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- RadiansPerMilliSec(src.RadiansPerMilliSec),
- CurrentAngle(0.0f),
- Center(src.Center)
- {
- }
- void RotateTextureMapperClass::Apply(int uv_array_index)
- {
- unsigned int now = WW3D::Get_Sync_Time();
- unsigned int delta = now - LastUsedSyncTime;
- LastUsedSyncTime=now;
- CurrentAngle+=RadiansPerMilliSec * delta;
- CurrentAngle=fmodf(CurrentAngle,2*WWMATH_PI);
- if (CurrentAngle<0.0f) CurrentAngle+=2*WWMATH_PI;
- // Set up the rotation matrix
- float c,s;
- c=WWMath::Cos(CurrentAngle);
- s=WWMath::Sin(CurrentAngle);
- Matrix4 m(true);
- // subtract center
- // rotate
- // add center
- // then scale
- m[0].Set(Scale.X*c,-Scale.X*s,-Scale.X*(c*Center.U-s*Center.V-Center.U),0.0f);
- m[1].Set(Scale.Y*s,Scale.Y*c,-Scale.Y*(s*Center.U+c*Center.V-Center.V),0.0f);
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- // SineLinearOffset Mapper
- // HY 5/16/01
- SineLinearOffsetTextureMapperClass::SineLinearOffsetTextureMapperClass(const Vector3 &uafp, const Vector3 &vafp, unsigned int stage) :
- TextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- UAFP(uafp),
- VAFP(vafp),
- CurrentAngle(0.0f)
- {
- }
- SineLinearOffsetTextureMapperClass::SineLinearOffsetTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- TextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- CurrentAngle(0.0f)
- {
- UAFP.X = ini.Get_Float(section, "UAmp", 1.0f);
- UAFP.Y = ini.Get_Float(section, "UFreq", 1.0f);
- UAFP.Z = ini.Get_Float(section, "UPhase", 0.0f);
- VAFP.X = ini.Get_Float(section, "VAmp", 1.0f);
- VAFP.Y = ini.Get_Float(section, "VFreq", 1.0f);
- VAFP.Z = ini.Get_Float(section, "VPhase", 0.0f);
- }
- SineLinearOffsetTextureMapperClass::SineLinearOffsetTextureMapperClass(const SineLinearOffsetTextureMapperClass & src) :
- TextureMapperClass(src),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- UAFP(src.UAFP),
- VAFP(src.VAFP),
- CurrentAngle(0.0f)
- {
- }
- void SineLinearOffsetTextureMapperClass::Apply(int uv_array_index)
- {
- unsigned int now = WW3D::Get_Sync_Time();
- unsigned int delta = now - LastUsedSyncTime;
- LastUsedSyncTime=now;
- const float ms_to_radians=2*WWMATH_PI/1000.0f;
- CurrentAngle+=delta*ms_to_radians;
- float offset_u=UAFP.X*sin(UAFP.Y*CurrentAngle+UAFP.Z*WWMATH_PI);
- float offset_v=VAFP.X*sin(VAFP.Y*CurrentAngle+VAFP.Z*WWMATH_PI);
- // ensure both coordinates of offset are in [0, 1] range:
- offset_u = offset_u - WWMath::Floor(offset_u);
- offset_v = offset_v - WWMath::Floor(offset_v);
- // Set up the offset matrix
- Matrix3D m(true);
-
- // According to the docs this should work since its 2D
- // otherwise change to translate
- m[0].Z=offset_u;
- m[1].Z=offset_v;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- // StepLinearOffset Mapper
- // HY 5/16/01
- StepLinearOffsetTextureMapperClass::StepLinearOffsetTextureMapperClass(const Vector2 &step, float steps_per_sec, unsigned int stage) :
- TextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Step(step),
- StepsPerMilliSec(steps_per_sec/1000.0f),
- CurrentStep(0.0f,0.0f),
- Remainder(0)
- {
- }
- StepLinearOffsetTextureMapperClass::StepLinearOffsetTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- TextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- CurrentStep(0.0f,0.0f),
- Remainder(0)
- {
- Step.U = ini.Get_Float(section, "UStep", 0.0f);
- Step.V = ini.Get_Float(section, "VStep", 0.0f);
- StepsPerMilliSec = ini.Get_Float(section, "SPS", 0.0f)/1000.0f;
- }
- StepLinearOffsetTextureMapperClass::StepLinearOffsetTextureMapperClass(const StepLinearOffsetTextureMapperClass & src) :
- TextureMapperClass(src),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Step(src.Step),
- StepsPerMilliSec(src.StepsPerMilliSec),
- CurrentStep(0.0f,0.0f),
- Remainder(0)
- {
- }
- void StepLinearOffsetTextureMapperClass::Apply(int uv_array_index)
- {
- unsigned int now = WW3D::Get_Sync_Time();
- unsigned int delta = now - LastUsedSyncTime;
- LastUsedSyncTime=now;
- Remainder+=delta;
- int num_steps=(int) (StepsPerMilliSec*Remainder);
- if (num_steps!=0)
- {
- CurrentStep+=Step*num_steps;
- Remainder-=num_steps/(float)StepsPerMilliSec;
- }
-
- // ensure both coordinates of offset are in [0, 1] range:
- CurrentStep.U -= WWMath::Floor(CurrentStep.U);
- CurrentStep.V -= WWMath::Floor(CurrentStep.V);
- // Set up the offset matrix
- Matrix3D m(true);
-
- // According to the docs this should work since its 2D
- // otherwise change to translate
- m[0].Z=CurrentStep.U;
- m[1].Z=CurrentStep.V;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- void StepLinearOffsetTextureMapperClass::Reset(void)
- {
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- CurrentStep.Set(0.0f,0.0f);
- Remainder=0;
- }
- // ZigZagLinearOffset Mapper
- // HY 5/16/01
- ZigZagLinearOffsetTextureMapperClass::ZigZagLinearOffsetTextureMapperClass(const Vector2 &speed, float period, unsigned int stage) :
- TextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Speed(speed/1000.0f),
- Period(period*1000.0f),
- Remainder(0)
- {
- // since we're zigzagging, a negative period is the same as a positive one
- if (Period<0.0f) Period=-Period;
- Half_Period=0.5f*Period;
- }
- ZigZagLinearOffsetTextureMapperClass::ZigZagLinearOffsetTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- TextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Remainder(0)
- {
- Speed.U = ini.Get_Float(section, "UPerSec", 0.0f)/1000.0f;
- Speed.V = ini.Get_Float(section, "VPerSec", 0.0f)/1000.0f;
- Period = ini.Get_Float(section, "Period", 0.0f)*1000.0f;
- if (Period<0.0f) Period=-Period;
- Half_Period=0.5f*Period;
- }
- ZigZagLinearOffsetTextureMapperClass::ZigZagLinearOffsetTextureMapperClass(const ZigZagLinearOffsetTextureMapperClass & src) :
- TextureMapperClass(src),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Speed(src.Speed),
- Period(src.Period),
- Half_Period(src.Half_Period),
- Remainder(0)
- {
- }
- void ZigZagLinearOffsetTextureMapperClass::Apply(int uv_array_index)
- {
- unsigned int now = WW3D::Get_Sync_Time();
- unsigned int delta = now - LastUsedSyncTime;
- LastUsedSyncTime=now;
- Remainder+=delta;
- float offset_u=0.0f;
- float offset_v=0.0f;
- if (Period>0.0f)
- {
- // figure out the fractional number of periods
- int num_periods=(int) (Remainder/Period);
- Remainder-=num_periods*Period;
- float time=0.0f;
- if (Remainder>Half_Period) {
- time=Period-Remainder;
- } else {
- time=Remainder;
- }
- offset_u=Speed.U * time;
- offset_v=Speed.V * time;
- }
- // ensure both coordinates of offset are in [0, 1] range:
- offset_u = offset_u - WWMath::Floor(offset_u);
- offset_v = offset_v - WWMath::Floor(offset_v);
- // Set up the offset matrix
- Matrix3D m(true);
-
- // According to the docs this should work since its 2D
- // otherwise change to translate
- m[0].Z=offset_u;
- m[1].Z=offset_v;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- void ZigZagLinearOffsetTextureMapperClass::Reset(void)
- {
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- Remainder=0;
- }
- // ----------------------------------------------------------------------------
- //
- // Environment mapper calculates the texture coordinates based on
- // transformed normals
- //
- // ----------------------------------------------------------------------------
- void ClassicEnvironmentMapperClass::Apply(int uv_array_index)
- {
- // The canonical environment map
- // scale the normal by (.5,.5) and add (.5,.5) to move it to (0,1) range
- // and ignore the Z component
- Matrix3D matenv( 0.5f, 0.0f, 0.0f, 0.5f,
- 0.0f, 0.5f, 0.0f, 0.5f,
- 0.0f, 0.0f, 1.0f, 0.0f );
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),matenv);
- // Get camera normals
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
- // Tell rasterizer to expect 2D matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
-
- }
- void EnvironmentMapperClass::Apply(int uv_array_index)
- {
- // The canonical environment map
- // scale the normal by (.25,.25) and add (.5,.5) to move it to (0,1) range
- // the additional half is to fudge the 1+z normalization factor
- // and ignore the Z component
- Matrix3D matenv( 0.25f, 0.0f, 0.0f, 0.5f,
- 0.0f, 0.25f, 0.0f, 0.5f,
- 0.0f, 0.0f, 1.0f, 0.0f );
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),matenv);
- // Get camera reflection vector
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
- // Tell rasterizer to expect 2D matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
-
- }
- EdgeMapperClass::EdgeMapperClass(unsigned int stage) :
- TextureMapperClass(stage),
- VSpeed(0.0f),
- UseReflect(false),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- VOffset(0.0f)
- {
- }
- EdgeMapperClass::EdgeMapperClass(const INIClass &ini, const char *section, unsigned int stage) :
- TextureMapperClass(stage),
- VSpeed(0.0f),
- UseReflect(false),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- VOffset(0.0f)
- {
- VSpeed=ini.Get_Float(section, "VPerSec", 0.0f);
- VOffset=ini.Get_Float(section, "VStart", 0.0f);
- UseReflect=ini.Get_Bool(section, "UseReflect", false);
- }
- EdgeMapperClass::EdgeMapperClass(const EdgeMapperClass & src):
- TextureMapperClass(src.Stage),
- VSpeed(src.VSpeed),
- UseReflect(src.UseReflect),
- VOffset(src.VOffset),
- LastUsedSyncTime(WW3D::Get_Sync_Time())
- {
- }
- void EdgeMapperClass::Apply(int uv_array_index)
- {
- unsigned int now=WW3D::Get_Sync_Time();
- float delta=(now-LastUsedSyncTime)*0.001f;
- LastUsedSyncTime=now;
- VOffset+=delta*VSpeed;
- VOffset-=WWMath::Floor(VOffset);
- // takes the Z component and
- // uses it to index the texture
- Matrix3D matenv( 0.0f, 0.0f, 0.5f, 0.5f,
- 0.0f, 0.0f, 0.0f, VOffset,
- 0.0f, 0.0f, 1.0f, 0.0f );
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),matenv);
- // Get camera reflection vector
- if (UseReflect)
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
- else
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
- // Tell rasterizer to expect 2D matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
-
- }
- void EdgeMapperClass::Reset(void)
- {
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- VOffset = 0.0f;
- }
- void WSClassicEnvironmentMapperClass::Apply(int uv_array_index)
- {
- // The canonical environment map
- // scale the normal by (.5,.5) and add (.5,.5) to move it to (0,1) range
- // and ignore the Z component
- Matrix3D matenv( 0.5f, 0.0f, 0.0f, 0.5f,
- 0.0f, 0.5f, 0.0f, 0.5f,
- 0.0f, 0.0f, 1.0f, 0.0f );
- // multiply by inverse of view transform
- Matrix4 mat;
- DX8Wrapper::Get_Transform(D3DTS_VIEW,mat);
- Matrix3D mat2(mat[0].X,mat[1].X,mat[2].X,0.0f,
- mat[0].Y,mat[1].Y,mat[2].Y,0.0f,
- mat[0].Z,mat[1].Z,mat[2].Z,0.0f);
- matenv=matenv*mat2;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),matenv);
- // Get camera normals
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
- // Tell rasterizer to expect 2D matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
-
- }
- void WSEnvironmentMapperClass::Apply(int uv_array_index)
- {
- // The canonical environment map
- // scale the normal by (.25,.25) and add (.5,.5) to move it to (0,1) range
- // the additional half is to fudge the 1+z normalization factor
- // and ignore the Z component
- Matrix3D matenv( 0.25f, 0.0f, 0.0f, 0.5f,
- 0.0f, 0.25f, 0.0f, 0.5f,
- 0.0f, 0.0f, 1.0f, 0.0f );
- // multiply by inverse of view transform
- Matrix4 mat;
- DX8Wrapper::Get_Transform(D3DTS_VIEW,mat);
- Matrix3D mat2(mat[0].X,mat[1].X,mat[2].X,0.0f,
- mat[0].Y,mat[1].Y,mat[2].Y,0.0f,
- mat[0].Z,mat[1].Z,mat[2].Z,0.0f);
- matenv=matenv*mat2;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),matenv);
- // Get camera reflection
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
- // Tell rasterizer to expect 2D matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
-
- }
- void ScreenMapperClass::Apply(int uv_array_index)
- {
- unsigned int delta = WW3D::Get_Sync_Time() - LastUsedSyncTime;
- float del = (float)delta;
- float offset_u = CurrentUVOffset.X + UVOffsetDeltaPerMS.X * del;
- float offset_v = CurrentUVOffset.Y + UVOffsetDeltaPerMS.Y * del;
- // ensure both coordinates of offset are in [0, 1] range:
- offset_u = offset_u - WWMath::Floor(offset_u);
- offset_v = offset_v - WWMath::Floor(offset_v);
- // multiply by projection matrix
- // followed by scale and translation
- Matrix4 mat;
- DX8Wrapper::Get_Transform(D3DTS_PROJECTION,mat);
- mat[0]*=Scale.X; // entire row since we're pre-multiplying
- mat[1]*=Scale.Y;
- Vector4 last(mat[3]); // this gets the w
- last*=offset_u; // multiply by w because the projected flag will divide by w
- mat[0]+=last;
- last=mat[3];
- last*=offset_v;
- mat[1]+=last;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),mat);
- // Get camera space position
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
- // Tell rasterizer what to expect
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_PROJECTED | D3DTTFF_COUNT3);
- // Update state
- CurrentUVOffset.X = offset_u;
- CurrentUVOffset.Y = offset_v;
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- }
- void GridClassicEnvironmentMapperClass::Apply(int uv_array_index)
- {
- update_temporal_state();
- float u_offset, v_offset;
- calculate_uv_offset(&u_offset, &v_offset);
- float del = 0.5f * OOGridWidth;
- // Set up the offset matrix
- Matrix3D tform( del, 0.0f, 0.0f, u_offset + del,
- 0.0f, del, 0.0f, v_offset + del,
- 0.0f, 0.0f, 1.0f, 0.0f );
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),tform);
- // Get camera normals
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
- // Tell rasterizer to expect 2D matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- void GridEnvironmentMapperClass::Apply(int uv_array_index)
- {
- update_temporal_state();
- float u_offset, v_offset;
- calculate_uv_offset(&u_offset, &v_offset);
- // Set up the offset matrix
- Matrix3D m(true);
-
- // According to the docs this should work since its 2D
- // otherwise change to translate
- m[0].Z = u_offset;
- m[1].Z = v_offset;
-
- float del=0.5f * OOGridWidth;
- // Set up the offset matrix
- Matrix3D tform( del, 0.0f, 0.0f, u_offset + del,
- 0.0f, del, 0.0f, v_offset + del,
- 0.0f, 0.0f, 1.0f, 0.0f );
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),tform);
- // Get camera space reflection
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
- // Tell rasterizer to expect 2D matrices
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- RandomTextureMapperClass::RandomTextureMapperClass(float fps, unsigned int stage):
- TextureMapperClass(stage),
- FPMS(fps/1000.0f),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Speed(0.0f,0.0f),
- Remainder(0)
- {
- randomize();
- }
- RandomTextureMapperClass::RandomTextureMapperClass(const INIClass &ini, const char *section, unsigned int stage):
- TextureMapperClass(stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Remainder(0)
- {
- FPMS = ini.Get_Float(section, "FPS", 0.0f)/1000.0f;
- Speed.U = ini.Get_Float(section, "UPerSec", 0.0f)/1000.0f;
- Speed.V = ini.Get_Float(section, "VPerSec", 0.0f)/1000.0f;
- randomize();
- }
- RandomTextureMapperClass::RandomTextureMapperClass(const RandomTextureMapperClass & src):
- TextureMapperClass(src),
- FPMS(src.FPMS),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- Speed(src.Speed),
- Remainder(0)
- {
- randomize();
- }
- void RandomTextureMapperClass::randomize(void)
- {
- CurrentAngle=2*WWMATH_PI*rand4.Get_Float();
- Center.U=rand4.Get_Float();
- Center.V=rand4.Get_Float();
- }
- void RandomTextureMapperClass::Apply(int uv_array_index)
- {
- unsigned int now = WW3D::Get_Sync_Time();
- unsigned int delta=now-LastUsedSyncTime;
- LastUsedSyncTime=now;
- Remainder+=delta;
-
- if (FPMS!=0.0f) {
- int num_frames=(int) (Remainder*FPMS);
- if (num_frames!=0) {
- randomize();
- Remainder-=num_frames/FPMS;
- }
- }
- // Set up the random matrix
- Matrix3D m(true);
- m.Rotate_Z(CurrentAngle);
- float uoff=Center.U + Remainder*Speed.U;
- float voff=Center.V + Remainder*Speed.V;
- uoff=fmodf(uoff,1.0f);
- voff=fmodf(voff,1.0f);
- m[0].Z=uoff;
- m[1].Z=voff;
- DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE) (D3DTS_TEXTURE0+Stage),m);
- // Disable Texgen
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | uv_array_index);
- // Tell rasterizer to expect 2D texture coordinates
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
- }
- void RandomTextureMapperClass::Reset(void)
- {
- LastUsedSyncTime = WW3D::Get_Sync_Time();
- Remainder=0;
- }
- // BumpEnv Mapper
- // GTH 8/22/01
- BumpEnvTextureMapperClass::BumpEnvTextureMapperClass(float rad_per_sec, float scale_factor, const Vector2 & offset_per_sec, const Vector2 &scale, unsigned int stage) :
- LinearOffsetTextureMapperClass(offset_per_sec,scale, stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- CurrentAngle(0.0f),
- RadiansPerSecond(rad_per_sec),
- ScaleFactor(scale_factor)
- {
- }
- BumpEnvTextureMapperClass::BumpEnvTextureMapperClass(INIClass &ini, char *section, unsigned int stage) :
- LinearOffsetTextureMapperClass(ini,section,stage),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- CurrentAngle(0.0f)
- {
- RadiansPerSecond = 2*WWMATH_PI*ini.Get_Float(section,"BumpRotation",0.0f);
- ScaleFactor = ini.Get_Float(section,"BumpScale",1.0f);
- }
- BumpEnvTextureMapperClass::BumpEnvTextureMapperClass(const BumpEnvTextureMapperClass & src) :
- LinearOffsetTextureMapperClass(src),
- LastUsedSyncTime(WW3D::Get_Sync_Time()),
- CurrentAngle(0.0f),
- RadiansPerSecond(src.RadiansPerSecond),
- ScaleFactor(src.ScaleFactor)
- {
- }
- void BumpEnvTextureMapperClass::Apply(int uv_array_index)
- {
- LinearOffsetTextureMapperClass::Apply(uv_array_index);
- unsigned int now = WW3D::Get_Sync_Time();
- unsigned int delta = now - LastUsedSyncTime;
- LastUsedSyncTime=now;
- CurrentAngle+=RadiansPerSecond * delta * 0.001f;
- CurrentAngle=fmodf(CurrentAngle,2*WWMATH_PI);
- // Compute the sine and cosine for the bump matrix
- float c,s;
- c=ScaleFactor * WWMath::Fast_Cos(CurrentAngle);
- s=ScaleFactor * WWMath::Fast_Sin(CurrentAngle);
- // Set the Bump Environment Matrix
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_BUMPENVMAT00, F2DW(c));
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_BUMPENVMAT01, F2DW(-s));
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_BUMPENVMAT10, F2DW(s));
- DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_BUMPENVMAT11, F2DW(c));
- }
- /*
- ** Utility functions
- */
- void Reset_All_Texture_Mappers(RenderObjClass *robj, bool make_unique)
- {
- if (robj->Class_ID()==RenderObjClass::CLASSID_MESH) {
- MeshClass *mesh=(MeshClass*) robj;
- MaterialInfoClass *minfo = robj->Get_Material_Info();
- if (minfo && minfo->Has_Time_Variant_Texture_Mappers()) {
- if (make_unique) {
- mesh->Make_Unique();
- minfo->Make_Vertex_Materials_Unique();
- }
- minfo->Reset_Texture_Mappers();
- minfo->Release_Ref();
- }
- } else {
- int num_obj = robj->Get_Num_Sub_Objects();
- RenderObjClass *sub_obj;
- for (int i = 0; i < num_obj; i++) {
- sub_obj = robj->Get_Sub_Object(i);
- if (sub_obj) {
- Reset_All_Texture_Mappers(sub_obj, make_unique);
- sub_obj->Release_Ref();
- }
- }
- }
- }
|