Batch #14874 by ragnarok-clanker: no function's compiled code changes; checked with 651 compiled unit(s), including every includer of Source/Client/Mode/CGameMode.h, Source/Client/Mode/CLoginMode.h, Source/Client/Mode/CMode.h, Source/Contents/Actors/GameActor.h, Source/Contents/Actors/GrannyGameActor.h, Source/Contents/Actors/Npc.h, Source/Contents/Actors/Pc.h, Source/Contents/Actors/RenderObject.h, Source/Contents/Camera/Camera.h, Source/Contents/EffectResourceSwitcher.h, Source/Contents/Effects/AMachineEffect.h, Source/Contents/Effects/AcidifiedThrow.h, Source/Contents/Effects/AnimatedEmitterEffect.h, Source/Contents/Effects/AstralStrikeEffect.h, Source/Contents/Effects/AxeBoomerang.h, Source/Contents/Effects/Bash.h, Source/Contents/Effects/BezierArcThrowEffect.h, Source/Contents/Effects/BindTrapEffect.h, Source/Contents/Effects/BlastForge.h, Source/Contents/Effects/CaneOfEvilEyeEffect.h, Source/Contents/Effects/CartCannon.h, Source/Contents/Effects/CellRangeEffect.h, Source/Contents/Effects/ChangeSizeEffect.h, Source/Contents/Effects/CharacterParticleBundle.h, Source/Contents/Effects/ChargingPierceEffect.h, Source/Contents/Effects/CherryBlossomEffect.h, Source/Contents/Effects/ClimaxEffect.h, Source/Contents/Effects/CloudEffect.h, Source/Contents/Effects/CloudKillEffect.h, Source/Contents/Effects/CommonFloorEffect.h, Source/Contents/Effects/Competentia.h, Source/Contents/Effects/CresciveBolt.h, Source/Contents/Effects/EZ2STREffect.h, Source/Contents/Effects/EZ2STREffectEx.h, Source/Contents/Effects/Effect.h, Source/Contents/Effects/ElectricEffect.h, Source/Contents/Effects/EmitterEffect.h, Source/Contents/Effects/EnergyOrbEffect.h, Source/Contents/Effects/EvilLandEffect.h, Source/Contents/Effects/EvilsPawEffect.h, Source/Contents/Effects/FlowerCastingEffect.h, Source/Contents/Effects/FortuneKissEffect.h, Source/Contents/Effects/FriggSongEffect.h, Source/Contents/Effects/FuumaShouakuEffect.h, Source/Contents/Effects/GlassWallEffect.h, Source/Contents/Effects/GravityControlEffect.h, Source/Contents/Effects/HealEffect.h, Source/Contents/Effects/HealSpEffect.h, Source/Contents/Effects/HitLineEffect.h, Source/Contents/Effects/JupitelThunderStormEffect.h, Source/Contents/Effects/Level150Effect.h, Source/Contents/Effects/Level99Effect.h, Source/Contents/Effects/Level99Orb1Effect.h, Source/Contents/Effects/Level99Orb2Effect.h, Source/Contents/Effects/LightSphereEffect.h, Source/Contents/Effects/MagicFloorEffect.h, Source/Contents/Effects/MagnumBreak.h, Source/Contents/Effects/MapChainEffect.h, Source/Contents/Effects/MapMagicZoneEffect.h, Source/Contents/Effects/MappillarEffect.h, Source/Contents/Effects/MonsterSkillEffects.h, Source/Contents/Effects/NyanggrassEffect.h, Source/Contents/Effects/Particle.h, Source/Contents/Effects/PokJukEffect.h, Source/Contents/Effects/PowderingEffect.h, Source/Contents/Effects/RagEffect.h, Source/Contents/Effects/RainbowEffect.h, Source/Contents/Effects/RectUpEffect.h, Source/Contents/Effects/RedLineEffect.h, Source/Contents/Effects/RichManKim.h, Source/Contents/Effects/RotateBgEffect.h, Source/Contents/Effects/RotateItemEffect.h, Source/Contents/Effects/RotateLineEffect.h, Source/Contents/Effects/SaintCastingEffect.h, Source/Contents/Effects/ScatterEffect.h, Source/Contents/Effects/ShadowExceedEffect.h, Source/Contents/Effects/SkillEffects.h, Source/Contents/Effects/SmokeEffect.h, Source/Contents/Effects/SoulCollectEffect.h, Source/Contents/Effects/SoulUnityEffect.h, Source/Contents/Effects/SphereWind2Effect.h, Source/Contents/Effects/SphereWindEffect.h, Source/Contents/Effects/SpriteEffect.h, Source/Contents/Effects/SquareRangeEffect.h, Source/Contents/Effects/StarEffect.h, Source/Contents/Effects/StarEmperorEffect.h, Source/Contents/Effects/StealEffect.h, Source/Contents/Effects/StormCannonEffect.h, Source/Contents/Effects/StormGustEffect.h, Source/Contents/Effects/StormKickEffect.h, Source/Contents/Effects/SunStanceEffect.h, Source/Contents/Effects/TalismanMarkEffect.h, Source/Contents/Effects/TetraBallEffect.h, Source/Contents/Effects/ThrowEffects.h, Source/Contents/Effects/TriangleShotArrow.h, Source/Contents/Effects/ViolentQuakeEffect.h, Source/Contents/Effects/WindEffect.h, Source/Contents/Ground/GroundGeometry.h, Source/Contents/Messenger/MessengerWindows.h, Source/Contents/SignBoard/SignBoard.h, Source/Contents/Skills/SkillInfo.h, Source/Resource/EmblemResource.h, Source/Resource/GifResource.h, Source/Resource/Resource.h, Source/UI/Acceptance/UIAutoMessageWnd.h, Source/UI/Acceptance/UIJoinPartyAcceptWnd.h, Source/UI/AdventureGuide/UIAdventureGuide.h, Source/UI/Buttons/UIBitmapButton2.h, Source/UI/Buttons/UIBmpRadioBtn.h, Source/UI/Buttons/UIButton.h, Source/UI/Buttons/UICashEmotionSprBtn.h, Source/UI/Buttons/UICheckBox.h, Source/UI/Buttons/UIDescriptRace.h, Source/UI/Buttons/UIItemMoveInfo.h, Source/UI/Buttons/UIItemTagButton.h, Source/UI/Buttons/UIJobSlotButton.h, Source/UI/Buttons/UINaviLinkButton.h, Source/UI/Buttons/UIRadioBtn.h, Source/UI/Buttons/UIRadioButton.h, Source/UI/Buttons/UIReplayButton.h, Source/UI/Buttons/UISlotBmpButton.h, Source/UI/Buttons/UISpriteButton.h, Source/UI/Buttons/UITVBitmapButton.h, Source/UI/Buttons/UITVTextButton.h, Source/UI/Buttons/UITagButton.h, Source/UI/Buttons/UITextButton.h, Source/UI/Buttons/UITextureButton.h, Source/UI/CashEmotion/UICashEmotionListWnd.h, Source/UI/CashEmotion/UICashEmotionMiniWnd.h, Source/UI/CashEmotion/UICashEmotionPack.h, Source/UI/CashEmotion/UICashEmotionPiece.h, Source/UI/CashShop/UICashShopWnd.h, Source/UI/Chat/UIChatRoomMakeWnd.h, Source/UI/Chat/UIChatRoomTitle.h, Source/UI/Chat/UINewChatWnd.h, Source/UI/Chat/UISubChatHisWnd.h, Source/UI/Chat/UISubChatMiniWnd.h, Source/UI/Chat/UIWhisperWnd.h, Source/UI/Clan/UIClanWnd.h, Source/UI/Dialogs/UIBookWnd.h, Source/UI/Dialogs/UIChooseWarpWnd.h, Source/UI/Dialogs/UIChooseWnd.h, Source/UI/Dialogs/UIDisconnectedServerMsgWnd.h, Source/UI/Dialogs/UIEditctrlWnd.h, Source/UI/Dialogs/UIEmailAddressWnd.h, Source/UI/Dialogs/UIGraffiStrboxWnd.h, Source/UI/Dialogs/UILoadingWnd.h, Source/UI/Dialogs/UIMemorialDunWnd.h, Source/UI/Dialogs/UIMenuWnd.h, Source/UI/Dialogs/UIMiniMapWnd.h, Source/UI/Dialogs/UIMinimapZoomWnd.h, Source/UI/Dialogs/UINoticeConfirmWnd.h, Source/UI/Dialogs/UINotifyLevelUpWnd.h, Source/UI/Dialogs/UINotifyQuestWnd.h, Source/UI/Dialogs/UINpcEditDialogWnd.h, Source/UI/Dialogs/UIPasswordWnd.h, Source/UI/Dialogs/UIPetTamingDeceiveWnd.h, Source/UI/Dialogs/UIProhibitListWnd.h, Source/UI/Dialogs/UIQuitWnd.h, Source/UI/Dialogs/UIRestartWnd.h, Source/UI/Dialogs/UISayDialogWnd.h, Source/UI/Dialogs/UISelectCartWnd.h, Source/UI/Dialogs/UITipOfTheDayWnd.h, Source/UI/Dialogs/UITipboxWnd.h, Source/UI/Dialogs/UIToolTipWnd.h, Source/UI/Dialogs/UIWaitDBSaveWnd.h, Source/UI/Dialogs/UIWaitWnd.h, Source/UI/Edit/UICandidateWnd.h, Source/UI/Edit/UIEditBoxEx.h, Source/UI/Edit/UIEditCtrl.h, Source/UI/Edit/UIEditCtrl_Currency.h, Source/UI/Emotion/UIEmotionWnd.h, Source/UI/Enchant/EnchantUI.h, Source/UI/EntryQueue/UIEntryQueueWnd.h, Source/UI/Exchange/UIExchangeUI.h, Source/UI/FrameSkin.h, Source/UI/GameSettings/GameSettingsUI.h, Source/UI/Gauges/UIPcGage.h, Source/UI/Guild/UIAgitWnd.h, Source/UI/Guild/UIGuildHelperWnd.h, Source/UI/Guild/UIGuildWnd.h, Source/UI/Guild/UIGuild_Storage_Log.h, Source/UI/Item/UIEquipmentPropertiesWnd.h, Source/UI/Item/UIItemBaseWnd.h, Source/UI/Item/UIItemPurchaseWnd.h, Source/UI/Item/UIItemSellWnd.h, Source/UI/Item/UIItemSellWnd2.h, Source/UI/Item/UIItemShopWnd.h, Source/UI/Item/UIItemShopWnd2.h, Source/UI/Item/UIItemStoreFindWnd.h, Source/UI/Item/UIItemStoreSubWnd.h, Source/UI/Item/UIItemStoreWnd.h, Source/UI/Item/UIItemWnd.h, Source/UI/Item/UIMerchantItemLogWnd.h, Source/UI/Item/UIParaItemShopWnd.h, Source/UI/Items/MergeItemWnd.h, Source/UI/Items/UICardItemIllustWnd.h, Source/UI/Items/UIEquipWnd.h, Source/UI/Items/UIExchangeWnd.h, Source/UI/Items/UIGameItem.h, Source/UI/Items/UIIllustWnd.h, Source/UI/Items/UIItemCollectionWnd.h, Source/UI/Items/UIItemIdentifyWnd.h, Source/UI/Items/UIItemParamChangeDisplayWnd.h, Source/UI/Items/UIItemRepairWnd.h, Source/UI/Items/UIMakeTargetListWnd.h, Source/UI/Items/UIMakeTargetProcessWnd.h, Source/UI/Items/UIMakeTargetResultWnd.h, Source/UI/Items/UINotifyItemObtainWnd.h, Source/UI/Items/UISwapEquipmentWnd.h, Source/UI/Items/UIWeaponRefineWnd.h, Source/UI/Lists/TableBox.h, Source/UI/Lists/UIChatHisBox.h, Source/UI/Lists/UIComboBox.h, Source/UI/Lists/UIComboBoxDefWnd.h, Source/UI/Lists/UIComboBoxEx.h, Source/UI/Lists/UIComboBoxV2Wnd.h, Source/UI/Lists/UIComboBoxWnd.h, Source/UI/Lists/UIImgMenu.h, Source/UI/Lists/UIItemStoreComboBox.h, Source/UI/Lists/UIListBox.h, Source/UI/Lists/UIListBoxEx.h, Source/UI/Lists/UIListBoxID.h, Source/UI/Lists/UIListBoxNavi.h, Source/UI/Lists/UIListBoxNaviSearch.h, Source/UI/Lists/UIListBoxTemplate.h, Source/UI/Lists/UIMemberListBox.h, Source/UI/Lists/UIPackageBoxNameList.h, Source/UI/Lists/UIReplayListBox.h, Source/UI/Lists/UIScrollBar.h, Source/UI/Lists/UITabControl.h, Source/UI/Lists/UITagListBox.h, Source/UI/Lists/UIThumb.h, Source/UI/Lists/UITreeView.h, Source/UI/Lists/UIVScrollBar.h, Source/UI/Menu/UIMenuIconWnd.h, Source/UI/Navigation/UINavigationV4Wnd.h, Source/UI/Navigation/UIPrivateAirplaneWnd.h, Source/UI/Party/UIAdvenPartyBoardWnd.h, Source/UI/Party/UIApplyForPartyWnd.h, Source/UI/Party/UIMiniPartyWnd.h, Source/UI/Party/UIPartyInfoWnd.h, Source/UI/Party/UIPartySettingWnd.h, Source/UI/Party/UIRegisterPartyWnd.h, Source/UI/Party/UIRequestJoinPartyWnd.h, Source/UI/ProbabilityTable/UIProbabilityTable.h, Source/UI/Quest/UIOngoingQuestInfo.h, Source/UI/Quest/UIQuestDisplay.h, Source/UI/Quest/UIRecommendedQuestInfo.h, Source/UI/Quest/UIRenewQuestUI.h, Source/UI/Quest/UIRenewQuestWnd.h, Source/UI/Rodex/UIRodexComposeWnd.h, Source/UI/Rodex/UIRodexInboxWnd.h, Source/UI/RuneSystem/UIRuneSystemWindows.h, Source/UI/RuneSystem/UIRuneSystemWnd.h, Source/UI/SelectPackageItemBox/SelectPackageItemBox.h, Source/UI/Shop/UIMerchantItemMyShopWnd.h, Source/UI/Shop/UIMerchantItemPurchaseMSGWnd.h, Source/UI/Shop/UIMerchantItemPurchaseWnd.h, Source/UI/Shop/UIMerchantItemShopWnd.h, Source/UI/Shop/UIMerchantItemWnd.h, Source/UI/Shop/UIMerchantMirrorItemWnd.h, Source/UI/Shop/UIMerchantShopMakeWnd.h, Source/UI/Shop/UIMerchantShopTitle.h, Source/UI/Shop/UINoticeMessageBox_LockSellItem.h, Source/UI/Shop/UInCash_CallWnd.h, Source/UI/Shortcuts/UIQuickSlotWnd.h, Source/UI/Shortcuts/UIShortCutWnd.h, Source/UI/Skill/UISkillDescribeWnd.h, Source/UI/Skill/UISkillListWnd.h, Source/UI/Skill/UISkillNameChangeWnd.h, Source/UI/SkillDelayInfo/SkillDelayInfo.h, Source/UI/Status/UIStatusWnd.h, Source/UI/StylingShop/UIStylingShopWnd.h, Source/UI/Text/UIAchWnd.h, Source/UI/Text/UIBalloonText.h, Source/UI/Text/UINameBalloonText.h, Source/UI/Text/UIStaticText.h, Source/UI/Text/UIStaticTextControl.h, Source/UI/Text/UIStaticText_LF.h, Source/UI/Text/UIString.h, Source/UI/Text/UITagTextViewer.h, Source/UI/Text/UITextViewer.h, Source/UI/Text/UITextViewerControl.h, Source/UI/Text/UITransBalloonText.h, Source/UI/UIBarGraph.h, Source/UI/UIBartermarketWnd.h, Source/UI/UIBasicCtrl.h, Source/UI/UIBroadcastBalloon.h, Source/UI/UICaptchaPreviewWnd.h, Source/UI/UICaptchaRegisterWnd.h, Source/UI/UIChangeMaterialWnd.h, Source/UI/UICheckAttendanceWnd.h, Source/UI/UIGradeEnchantWnd.h, Source/UI/UIHotkeyGuideWnd.h, Source/UI/UIIngredientInfoWnd.h, Source/UI/UIItemReformWnd.h, Source/UI/UILapineScrollBar.h, Source/UI/UILapineUpgradeBoxWnd.h, Source/UI/UIMacroBlackListCheckWnd.h, Source/UI/UIMacroDetectorWnd.h, Source/UI/UIMacroReport.h, Source/UI/UIMacroUserInfoWnd.h, Source/UI/UIPreviewEquipWnd.h, Source/UI/UIRefiningWnd.h, Source/UI/UIReputeWnd.h, Source/UI/UIRoundBoxTooltipWnd.h, Source/UI/UIScrollWnd.h, Source/UI/UISlotBitmap.h, Source/UI/UIStaticBitmap.h, Source/UI/UIStaticItem.h, Source/UI/Window/UIAccountLimitedToolWnd.h, Source/UI/Window/UIBalloonOpenBtn.h, Source/UI/Window/UIBank_NewWnd.h, Source/UI/Window/UIBasicInfoWnd.h, Source/UI/Window/UIBattleMsgOptionWnd.h, Source/UI/Window/UIBitmapTab.h, Source/UI/Window/UIChangeNameWnd.h, Source/UI/Window/UIChatRoomWnd.h, Source/UI/Window/UICntWnd.h, Source/UI/Window/UICollectionSystemWnd.h, Source/UI/Window/UIControl.h, Source/UI/Window/UIDebuffRemoveWnd.h, Source/UI/Window/UIEmblemWnd.h, Source/UI/Window/UIEscOptionWnd.h, Source/UI/Window/UIFrameWnd.h, Source/UI/Window/UIHomunInfoWnd.h, Source/UI/Window/UIHotKeyWnd.h, Source/UI/Window/UIJobListWnd.h, Source/UI/Window/UILoginOTPWnd.h, Source/UI/Window/UILoginWnd.h, Source/UI/Window/UIMakeCharWnd.h, Source/UI/Window/UIMerInfoWnd.h, Source/UI/Window/UIMessageBox.h, Source/UI/Window/UIMessageBoxAutoreturn.h, Source/UI/Window/UIMileageWnd.h, Source/UI/Window/UIMiniBtnWnd.h, Source/UI/Window/UIMonsterDisplayWnd.h, Source/UI/Window/UIMonsterInfoWnd.h, Source/UI/Window/UINavigationHelpWnd.h, Source/UI/Window/UINavigationWnd.h, Source/UI/Window/UINewMakeCharWnd.h, Source/UI/Window/UINewSelectCharWnd.h, Source/UI/Window/UINewSkillListWnd.h, Source/UI/Window/UINoteWnd.h, Source/UI/Window/UINoticeWnd.h, Source/UI/Window/UIOpenMailBoxWnd.h, Source/UI/Window/UIOpenRoulletteWnd.h, Source/UI/Window/UIPartyBookingHelpWnd.h, Source/UI/Window/UIPetEvolutionWnd.h, Source/UI/Window/UIPetInfoWnd.h, Source/UI/Window/UIRebirthWnd.h, Source/UI/Window/UIReplayControlWnd.h, Source/UI/Window/UIReplayRECControlWnd.h, Source/UI/Window/UIResizer.h, Source/UI/Window/UIRoMapWnd.h, Source/UI/Window/UIRodexContentsWnd.h, Source/UI/Window/UIRoulletteWnd.h, Source/UI/Window/UISecondCostumeWnd.h, Source/UI/Window/UISeekPartyListWnd.h, Source/UI/Window/UISeekPartyMBWnd.h, Source/UI/Window/UISeekPartyWnd.h, Source/UI/Window/UISelCharForUServerWnd.h, Source/UI/Window/UISelectReplayDataWnd.h, Source/UI/Window/UISelectServerWnd.h, Source/UI/Window/UISerachStoreInfoWnd.h, Source/UI/Window/UIShowWarpWnd.h, Source/UI/Window/UITab.h, Source/UI/Window/UITalkboxTrapInputWnd.h, Source/UI/Window/UITransMenuWnd.h, Source/UI/Window/UIVideoWnd.h, Source/UI/Window/UIViewCameraInfoWnd.h, Source/UI/Window/UIWindow.h, Source/UI/Window/UIWordDisplayWnd.h.
402 lines
14 KiB
C++
402 lines
14 KiB
C++
#include "Contents/Ground/GroundGeometry.h"
|
|
#include "Render/Textures/Texture.h"
|
|
#include "Render/Textures/TextureCache.h"
|
|
#include "Resource/World/GroundResource.h"
|
|
|
|
#include "Utility/Math/AffineMatrix.h"
|
|
#include "Utility/Math/ScalarConversion.h"
|
|
#include <bit>
|
|
#include <cstring>
|
|
|
|
namespace {
|
|
struct NormalVector {
|
|
// INLINED
|
|
NormalVector() : values{0.0f, 0.0f, 0.0f} {
|
|
}
|
|
|
|
float values[3];
|
|
};
|
|
|
|
struct CellNormals {
|
|
NormalVector faces[2];
|
|
NormalVector side2;
|
|
NormalVector side1;
|
|
};
|
|
|
|
// INLINED
|
|
float InverseLength(float squared) {
|
|
const float length = SquareRoot(squared);
|
|
return 1.0f / length;
|
|
}
|
|
|
|
// INLINED
|
|
void NormalizeGroundNormal(float* vector, bool yFirst) {
|
|
const float first = yFirst ? vector[1] * vector[1] + vector[0] * vector[0] : vector[0] * vector[0] + vector[1] * vector[1];
|
|
const float inverse = InverseLength(first + vector[2] * vector[2]);
|
|
vector[0] = inverse * vector[0];
|
|
vector[1] = inverse * vector[1];
|
|
vector[2] = inverse * vector[2];
|
|
}
|
|
|
|
// INLINED
|
|
void Add(float* result, const float* value) {
|
|
result[0] = result[0] + value[0];
|
|
result[1] = result[1] + value[1];
|
|
result[2] = result[2] + value[2];
|
|
}
|
|
|
|
// INLINED
|
|
__forceinline std::uint32_t
|
|
LitColor(const float* normal, bool normalize, bool side, const float* direction, const float* diffuse, const float* ambient, const GroundQuad* source) {
|
|
float vector[3] = {normal[0], normal[1], normal[2]};
|
|
|
|
if (normalize) {
|
|
NormalizeGroundNormal(vector, false);
|
|
}
|
|
|
|
const float dot = side ? (direction[1] * vector[1] + vector[0] * direction[0]) + direction[2] * vector[2]
|
|
: (vector[1] * direction[1] + vector[0] * direction[0]) + vector[2] * direction[2];
|
|
const float amount = dot > 0.0f ? dot : 0.0f;
|
|
const std::uint32_t color = source ? source->color : 0xFFFFFFFFu;
|
|
std::uint32_t result = 0xFF000000u;
|
|
|
|
for (unsigned channel = 0; channel < 3; ++channel) {
|
|
const float illumination = amount * diffuse[channel] + ambient[channel];
|
|
const float light = illumination < 1.0f ? illumination : 1.0f;
|
|
const unsigned shift = 16 - channel * 8;
|
|
const float scaled = static_cast<float>((color >> shift) & 255u) * light;
|
|
const unsigned value = static_cast<unsigned>(TruncateToInt(scaled)) & 255u;
|
|
result |= value << shift;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
// INLINED
|
|
GroundBase::GroundBase()
|
|
: terrain(nullptr), cellSize(10.0f), waterLevel(0.0f), waterAnimation(3), waterPitch(50), waterPhase(2), waterType(0), waterHeight(1.0f),
|
|
unknown_0050(0), unknown_0054(0), loaded(0) {
|
|
}
|
|
|
|
// INLINED
|
|
GroundBase::~GroundBase() = default;
|
|
|
|
// OFFSET: 0x00ABD640
|
|
// FUNCTION: fn_17546
|
|
GroundGeometry::GroundGeometry() : waterColumns(1), waterRows(1), waterPartitioned(false) {
|
|
}
|
|
|
|
// INLINED
|
|
GroundGeometry::~GroundGeometry() = default;
|
|
|
|
// OFFSET: 0x00AC3010
|
|
// FUNCTION: fn_17595
|
|
void GroundGeometry::ClearGeometry() {
|
|
this->tiles.clear();
|
|
this->lighting.clear();
|
|
this->cells.clear();
|
|
}
|
|
|
|
// OFFSET: 0x00AC0200
|
|
// FUNCTION: fn_17563
|
|
void GroundGeometry::Reset(int columns, int rows) {
|
|
this->ClearGeometry();
|
|
this->width = columns;
|
|
this->height = rows;
|
|
this->cells.resize(static_cast<unsigned>(columns) * static_cast<unsigned>(rows));
|
|
this->lighting.resize(4u * static_cast<unsigned>(columns) * static_cast<unsigned>(rows), {1.0f, 1.0f, 1.0f});
|
|
this->unknown_005C = 0;
|
|
this->unknown_0058 = 0;
|
|
}
|
|
|
|
// OFFSET: 0x00AC0350
|
|
// FUNCTION: fn_17564
|
|
void GroundBase::Reset(int, int) {
|
|
}
|
|
|
|
// OFFSET: 0x00ABDEF0
|
|
// FUNCTION: fn_17556
|
|
void GroundGeometry::Build(CGndRes& resource, const float* lightDirection, const float* diffuse, const float* ambient) {
|
|
this->loaded = resource.loaded;
|
|
this->Reset(resource.width, resource.height);
|
|
CellNormals* normals = new CellNormals[resource.width * resource.height];
|
|
this->cellSize = resource.cellSize;
|
|
this->lightmapSet.Build(resource);
|
|
this->tiles.clear();
|
|
this->tiles.resize(static_cast<unsigned>(resource.tileCount));
|
|
|
|
for (int row = 0; row < this->height; ++row) {
|
|
for (int column = 0; column < this->width; ++column) {
|
|
const unsigned index = static_cast<unsigned>(row) * static_cast<unsigned>(this->width) + static_cast<unsigned>(column);
|
|
GroundCell& cell = this->cells[index];
|
|
const unsigned char* record = resource.cells + 28u * index;
|
|
std::memcpy(cell.heights, record, sizeof(cell.heights));
|
|
const float left = static_cast<float>(column - this->width / 2) * this->cellSize;
|
|
const float right = static_cast<float>(column - this->width / 2 + 1) * this->cellSize;
|
|
const float top = static_cast<float>(row - this->height / 2) * this->cellSize;
|
|
const float bottom = static_cast<float>(row - this->height / 2 + 1) * this->cellSize;
|
|
const float corners[4][3] = {{left, 0, top}, {right, 0, top}, {left, 0, bottom}, {right, 0, bottom}};
|
|
std::memcpy(cell.corners, corners, sizeof(corners));
|
|
int tileIndices[3];
|
|
std::memcpy(tileIndices, record + 16, sizeof(tileIndices));
|
|
|
|
for (unsigned face = 0; face < 3; ++face) {
|
|
if ((face == 1 && row >= this->height - 1) || (face == 2 && column >= this->width - 1)) {
|
|
continue;
|
|
}
|
|
|
|
const int tileIndex = tileIndices[face];
|
|
|
|
if (tileIndex < 0 || tileIndex >= resource.tileCount) {
|
|
continue;
|
|
}
|
|
|
|
GroundQuad& tile = this->tiles[tileIndex];
|
|
const unsigned char* tileBytes = resource.tiles + 40u * static_cast<unsigned>(tileIndex);
|
|
std::memcpy(&tile.color, tileBytes + 36, sizeof(tile.color));
|
|
std::int16_t textureIndex;
|
|
std::uint16_t lightmapIndex;
|
|
std::memcpy(&textureIndex, tileBytes + 32, sizeof(textureIndex));
|
|
std::memcpy(&lightmapIndex, tileBytes + 34, sizeof(lightmapIndex));
|
|
tile.texture = g_texMgr.Load(resource.textureNames[textureIndex], 0, false, true, false);
|
|
float positions[4][3];
|
|
|
|
if (face == 0) {
|
|
for (unsigned corner = 0; corner < 4; ++corner) {
|
|
positions[corner][0] = cell.corners[corner][0];
|
|
positions[corner][1] = cell.heights[corner];
|
|
positions[corner][2] = cell.corners[corner][2];
|
|
}
|
|
} else if (face == 1) {
|
|
float next[4];
|
|
std::memcpy(next, resource.cells + 28u * (index + this->width), sizeof(next));
|
|
const float values[4][3] = {{left, cell.heights[2], bottom}, {right, cell.heights[3], bottom}, {left, next[0], bottom}, {right, next[1], bottom}};
|
|
std::memcpy(positions, values, sizeof(positions));
|
|
normals[index].side2.values[2] = next[0] <= cell.heights[2] ? 1.0f : -1.0f;
|
|
} else {
|
|
float next[4];
|
|
std::memcpy(next, resource.cells + 28u * (index + 1), sizeof(next));
|
|
const float values[4][3] = {{right, cell.heights[3], bottom}, {right, cell.heights[1], top}, {right, next[2], bottom}, {right, next[0], top}};
|
|
std::memcpy(positions, values, sizeof(positions));
|
|
normals[index].side1.values[0] = next[0] <= cell.heights[2] ? 1.0f : -1.0f;
|
|
}
|
|
|
|
const float scaleU = static_cast<float>(tile.texture->ImageWidth()) / static_cast<float>(tile.texture->TextureWidth());
|
|
const float scaleV = static_cast<float>(tile.texture->ImageHeight()) / static_cast<float>(tile.texture->TextureHeight());
|
|
GroundLightmap& lightmap = this->lightmapSet.lightmaps[lightmapIndex];
|
|
|
|
tile.lightmap = &lightmap;
|
|
tile.lightmapTexture = lightmap.texture;
|
|
|
|
for (unsigned corner = 0; corner < 4; ++corner) {
|
|
std::memcpy(tile.vertices[corner], positions[corner], sizeof(positions[corner]));
|
|
float u;
|
|
float v;
|
|
std::memcpy(&u, tileBytes + corner * 4, sizeof(u));
|
|
std::memcpy(&v, tileBytes + 16 + corner * 4, sizeof(v));
|
|
tile.vertices[corner][4] = scaleU * u;
|
|
tile.vertices[corner][5] = scaleV * v;
|
|
tile.vertices[corner][6] = lightmap.uv[corner][0];
|
|
tile.vertices[corner][7] = lightmap.uv[corner][1];
|
|
}
|
|
|
|
if (face == 0) {
|
|
for (unsigned channel = 0; channel < 3; ++channel) {
|
|
const unsigned value = 2u * lightmap.color[channel];
|
|
cell.color[channel] = static_cast<unsigned char>(value > 255 ? 255 : value);
|
|
}
|
|
|
|
float* first = normals[index].faces[0].values;
|
|
float* second = normals[index].faces[1].values;
|
|
const float ab = cell.heights[2] - cell.heights[0];
|
|
const float ac = cell.heights[2] - cell.heights[1];
|
|
|
|
first[0] = ac * (this->cellSize - 0.0f) - (this->cellSize - 0.0f) * ab;
|
|
first[1] = (this->cellSize - 0.0f) * 0.0f - (this->cellSize - 0.0f) * (0.0f - this->cellSize);
|
|
first[2] = ab * (0.0f - this->cellSize) - ac * 0.0f;
|
|
NormalizeGroundNormal(first, true);
|
|
const float db = cell.heights[3] - cell.heights[1];
|
|
const float dc = cell.heights[3] - cell.heights[2];
|
|
const float dz = this->cellSize - 0.0f;
|
|
const float dx = this->cellSize - 0.0f;
|
|
const float zero = this->cellSize - this->cellSize;
|
|
|
|
second[0] = db * zero - dx * dc;
|
|
second[1] = dz * dx - zero * zero;
|
|
second[2] = zero * dc - dz * db;
|
|
NormalizeGroundNormal(second, true);
|
|
cell.top = &tile;
|
|
} else if (face == 1) {
|
|
cell.side2 = &tile;
|
|
} else {
|
|
cell.frame = 0xFFFFFFFFu;
|
|
cell.side1 = &tile;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int row = 0; row < this->height; ++row) {
|
|
for (int column = 0; column < this->width; ++column) {
|
|
const unsigned index = static_cast<unsigned>(row) * static_cast<unsigned>(this->width) + static_cast<unsigned>(column);
|
|
GroundCell& cell = this->cells[index];
|
|
const auto neighbor = [&](int x, int y) -> const GroundCell* {
|
|
return x >= 0 && x < this->width && y >= 0 && y < this->height
|
|
? &this->cells[static_cast<unsigned>(y) * static_cast<unsigned>(this->width) + static_cast<unsigned>(x)]
|
|
: nullptr;
|
|
};
|
|
const GroundCell* north = neighbor(column, row - 1);
|
|
const GroundCell* west = neighbor(column - 1, row);
|
|
const GroundCell* northwest = neighbor(column - 1, row - 1);
|
|
const GroundCell* northeast = neighbor(column + 1, row - 1);
|
|
const GroundCell* east = neighbor(column + 1, row);
|
|
const GroundCell* south = neighbor(column, row + 1);
|
|
const GroundCell* southwest = neighbor(column - 1, row + 1);
|
|
const GroundCell* southeast = neighbor(column + 1, row + 1);
|
|
float smooth[4][3]{};
|
|
const auto add = [&](unsigned corner, const GroundCell* source, unsigned first, unsigned count) {
|
|
const auto sourceIndex = static_cast<unsigned>(source - this->cells.data());
|
|
|
|
for (unsigned normal = first; normal < first + count; ++normal) {
|
|
Add(smooth[corner], normals[sourceIndex].faces[normal].values);
|
|
}
|
|
};
|
|
add(0, &cell, 0, 1);
|
|
|
|
if (north && north->heights[2] == cell.heights[0]) {
|
|
add(0, north, 0, 2);
|
|
}
|
|
|
|
if (west && west->heights[1] == cell.heights[0]) {
|
|
add(0, west, 0, 2);
|
|
}
|
|
|
|
if (northwest && northwest->heights[3] == cell.heights[0]) {
|
|
add(0, northwest, 1, 1);
|
|
}
|
|
|
|
add(1, &cell, 0, 2);
|
|
|
|
if (east && east->heights[0] == cell.heights[1]) {
|
|
add(1, east, 0, 1);
|
|
}
|
|
|
|
if (north && north->heights[3] == cell.heights[1]) {
|
|
add(1, north, 1, 1);
|
|
}
|
|
|
|
if (northeast && northeast->heights[2] == cell.heights[1]) {
|
|
add(1, northeast, 0, 2);
|
|
}
|
|
|
|
add(2, &cell, 0, 2);
|
|
|
|
if (west && west->heights[3] == cell.heights[2]) {
|
|
add(2, west, 1, 1);
|
|
}
|
|
|
|
if (south && south->heights[0] == cell.heights[2]) {
|
|
add(2, south, 0, 1);
|
|
}
|
|
|
|
if (southwest && southwest->heights[1] == cell.heights[2]) {
|
|
add(2, southwest, 0, 2);
|
|
}
|
|
|
|
add(3, &cell, 0, 1);
|
|
|
|
if (east && east->heights[2] == cell.heights[3]) {
|
|
add(3, east, 0, 2);
|
|
}
|
|
|
|
if (south && south->heights[1] == cell.heights[3]) {
|
|
add(3, south, 0, 2);
|
|
}
|
|
|
|
if (southeast && southeast->heights[0] == cell.heights[3]) {
|
|
add(3, southeast, 0, 1);
|
|
}
|
|
|
|
if (cell.top) {
|
|
const GroundCell* sources[4] = {&cell, east, south, southeast};
|
|
|
|
for (unsigned corner = 0; corner < 4; ++corner) {
|
|
const GroundQuad* source = sources[corner] ? sources[corner]->top : nullptr;
|
|
const auto color = LitColor(smooth[corner], true, false, lightDirection, diffuse, ambient, source);
|
|
cell.top->vertices[corner][3] = std::bit_cast<float>(color);
|
|
}
|
|
}
|
|
|
|
if (cell.side2) {
|
|
for (unsigned corner = 0; corner < 4; ++corner) {
|
|
const GroundCell* source = (corner & 1) ? southeast : south;
|
|
const auto color = LitColor(normals[index].side2.values, false, true, lightDirection, diffuse, ambient, source ? source->top : nullptr);
|
|
cell.side2->vertices[corner][3] = std::bit_cast<float>(color);
|
|
}
|
|
}
|
|
|
|
if (cell.side1) {
|
|
for (unsigned corner = 0; corner < 4; ++corner) {
|
|
const GroundCell* source = (corner & 1) ? east : southeast;
|
|
const auto color = LitColor(normals[index].side1.values, false, true, lightDirection, diffuse, ambient, source ? source->top : nullptr);
|
|
cell.side1->vertices[corner][3] = std::bit_cast<float>(color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] normals;
|
|
}
|
|
|
|
// OFFSET: 0x00ABFB00
|
|
// FUNCTION: fn_17557
|
|
void GroundBase::Build(CGndRes&, const float*, const float*, const float*) {
|
|
}
|
|
|
|
// OFFSET: 0x00AC0990
|
|
// FUNCTION: fn_17566
|
|
void GroundGeometry::RenderLod(int) {
|
|
}
|
|
|
|
// OFFSET: 0x00AC09A0
|
|
// FUNCTION: fn_17567
|
|
void GroundBase::RenderLod(int) {
|
|
}
|
|
|
|
// OFFSET: 0x00AC1510
|
|
// FUNCTION: fn_17582
|
|
void GroundBase::UpdateWater() {
|
|
}
|
|
|
|
// OFFSET: 0x00AC1520
|
|
// FUNCTION: fn_17583
|
|
bool GroundGeometry::IsNewVer() {
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x00AC3080
|
|
// FUNCTION: fn_17598
|
|
void GroundBase::SetGndRiseAmount(float, int, int) {
|
|
}
|
|
|
|
// OFFSET: 0x00AC1530
|
|
// FUNCTION: fn_17584
|
|
bool GroundBase::IsNewVer() {
|
|
return false;
|
|
}
|
|
|
|
// OFFSET: 0x00AC3030
|
|
// FUNCTION: fn_17596
|
|
void GroundBase::ClearGeometry() {
|
|
}
|
|
|
|
// OFFSET: 0x00AC3370
|
|
// FUNCTION: fn_17601
|
|
void GroundBase::ImportWater(const CGndRes&) {
|
|
}
|
|
|
|
// OFFSET: 0x00AC38A0
|
|
// FUNCTION: fn_17605
|
|
void GroundBase::DrawTerrainOverlay(const float*, int, int, std::uint32_t, CTexture*) const {
|
|
}
|