mirror of
https://github.com/whoahq/whoa.git
synced 2026-03-18 13:41:06 +03:00
Compare commits
32 Commits
48ea761994
...
73984bdb99
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73984bdb99 | ||
|
|
fa98bbc1f0 | ||
|
|
af4b798942 | ||
|
|
9b18f2f3bd | ||
|
|
6cb5310430 | ||
|
|
cb8291af1a | ||
|
|
58c8975769 | ||
|
|
817cec99fe | ||
|
|
6675586a29 | ||
|
|
06186d1251 | ||
|
|
e5cc9de486 | ||
|
|
7682dba2c9 | ||
|
|
c6e18336de | ||
|
|
e7bd5968cf | ||
|
|
a51e9ba082 | ||
|
|
619bcca778 | ||
|
|
4782c554fc | ||
|
|
8c518f7e6d | ||
|
|
f8f00b599e | ||
|
|
703dc26df7 | ||
|
|
09c016c935 | ||
|
|
2145348935 | ||
|
|
50685c7cc0 | ||
|
|
b3c07f0607 | ||
|
|
6bcaec1fe7 | ||
|
|
4628b7d831 | ||
|
|
7d491570e4 | ||
|
|
2711c752ba | ||
|
|
0e6f65f32e | ||
|
|
86084516cd | ||
|
|
71a31e19bd | ||
|
|
d77b1dfd67 |
@ -1 +1 @@
|
||||
Subproject commit 1c9e7831c874068e7c939a7dea8790eef6513d78
|
||||
Subproject commit 1e5366bbc6935e3363abf5921f0be12f902e790a
|
||||
@ -1129,7 +1129,7 @@ void CGlueMgr::StatusDialogClick() {
|
||||
}
|
||||
|
||||
case IDLE_REALM_LIST:
|
||||
case IDLE_5:
|
||||
case IDLE_CREATE_CHARACTER:
|
||||
case IDLE_DELETE_CHARACTER:
|
||||
case IDLE_ENTER_WORLD: {
|
||||
ClientServices::Connection()->Cancel(2);
|
||||
|
||||
@ -20,7 +20,7 @@ class CGlueMgr {
|
||||
IDLE_ACCOUNT_LOGIN = 2,
|
||||
IDLE_CHARACTER_LIST = 3,
|
||||
IDLE_REALM_LIST = 4,
|
||||
IDLE_5 = 5,
|
||||
IDLE_CREATE_CHARACTER = 5,
|
||||
IDLE_DELETE_CHARACTER = 6,
|
||||
IDLE_7 = 7,
|
||||
IDLE_8 = 8,
|
||||
|
||||
@ -924,6 +924,10 @@ CGxPool* CGxDevice::PoolCreate(EGxPoolTarget target, EGxPoolUsage usage, uint32_
|
||||
return pool;
|
||||
}
|
||||
|
||||
void CGxDevice::RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex) {
|
||||
gxTex = this->m_textureTarget[buffer].m_texture;
|
||||
}
|
||||
|
||||
void CGxDevice::RsGet(EGxRenderState which, int32_t& value) {
|
||||
value = static_cast<int32_t>(this->m_appRenderStates[which].m_value);
|
||||
}
|
||||
|
||||
@ -38,6 +38,13 @@ struct ShaderConstants {
|
||||
|
||||
class CGxDevice {
|
||||
public:
|
||||
// Structs
|
||||
struct TextureTarget {
|
||||
CGxTex* m_texture;
|
||||
uint32_t m_plane;
|
||||
void* m_apiSpecific;
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static uint32_t s_alphaRef[];
|
||||
static C3Vector s_pointScaleIdentity;
|
||||
@ -101,12 +108,12 @@ class CGxDevice {
|
||||
uint32_t m_appMasterEnables = 0;
|
||||
uint32_t m_hwMasterEnables = 0;
|
||||
TSList<CGxPool, TSGetLink<CGxPool>> m_poolList;
|
||||
CGxBuf* m_bufLocked[GxPoolTargets_Last];
|
||||
CGxBuf* m_bufLocked[GxPoolTargets_Last] = {};
|
||||
CGxPool* m_vertexPool = nullptr;
|
||||
CGxPool* m_indexPool = nullptr;
|
||||
CGxBuf* m_streamBufs[GxPoolTargets_Last];
|
||||
CGxBuf* m_streamBufs[GxPoolTargets_Last] = {};
|
||||
CGxVertexAttrib m_primVertexFormatAttrib[GxVertexBufferFormats_Last];
|
||||
CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last];
|
||||
CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last] = {};
|
||||
uint32_t m_primVertexMask = 0;
|
||||
uint32_t m_primVertexDirty = 0;
|
||||
EGxVertexBufferFormat m_primVertexFormat = GxVertexBufferFormats_Last;
|
||||
@ -116,6 +123,9 @@ class CGxDevice {
|
||||
int32_t m_primIndexDirty = 0;
|
||||
TSFixedArray<CGxAppRenderState> m_appRenderStates;
|
||||
TSFixedArray<CGxStateBom> m_hwRenderStates;
|
||||
// TODO
|
||||
TextureTarget m_textureTarget[GxBuffers_Last] = {};
|
||||
// TODO
|
||||
uint32_t m_baseMipLevel = 0; // TODO placeholder
|
||||
|
||||
// Virtual member functions
|
||||
@ -173,6 +183,7 @@ class CGxDevice {
|
||||
void PrimVertexFormat(CGxBuf*, CGxVertexAttrib*, uint32_t);
|
||||
void PrimVertexMask(uint32_t);
|
||||
void PrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
|
||||
void RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex);
|
||||
void RsGet(EGxRenderState, int32_t&);
|
||||
void RsSet(EGxRenderState, int32_t);
|
||||
void RsSet(EGxRenderState, void*);
|
||||
|
||||
6
src/gx/RenderTarget.cpp
Normal file
6
src/gx/RenderTarget.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "gx/RenderTarget.hpp"
|
||||
#include "gx/Device.hpp"
|
||||
|
||||
void GxRenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex) {
|
||||
g_theGxDevicePtr->RenderTargetGet(buffer, gxTex);
|
||||
}
|
||||
10
src/gx/RenderTarget.hpp
Normal file
10
src/gx/RenderTarget.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef GX_RENDER_TARGET_HPP
|
||||
#define GX_RENDER_TARGET_HPP
|
||||
|
||||
#include "gx/Types.hpp"
|
||||
|
||||
class CGxTex;
|
||||
|
||||
void GxRenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex);
|
||||
|
||||
#endif
|
||||
@ -54,6 +54,12 @@ enum EGxBlend {
|
||||
GxBlends_Last = 12
|
||||
};
|
||||
|
||||
enum EGxBuffer {
|
||||
GxBuffers_Color = 0,
|
||||
GxBuffers_Depth = 1,
|
||||
GxBuffers_Last,
|
||||
};
|
||||
|
||||
enum EGxColorFormat {
|
||||
GxCF_argb = 0,
|
||||
GxCF_rgba = 1,
|
||||
|
||||
@ -60,11 +60,11 @@ enum NETMESSAGE {
|
||||
CMSG_AUTH_SRP6_BEGIN = 0x0033,
|
||||
CMSG_AUTH_SRP6_PROOF = 0x0034,
|
||||
CMSG_AUTH_SRP6_RECODE = 0x0035,
|
||||
CMSG_CREATE_CHARACTER = 0x0036,
|
||||
CMSG_CHAR_CREATE = 0x0036,
|
||||
CMSG_ENUM_CHARACTERS = 0x0037,
|
||||
CMSG_CHAR_DELETE = 0x0038,
|
||||
SMSG_AUTH_SRP6_RESPONSE = 0x0039,
|
||||
SMSG_CREATE_CHAR = 0x003A,
|
||||
SMSG_CHAR_CREATE = 0x003A,
|
||||
SMSG_ENUM_CHARACTERS_RESULT = 0x003B,
|
||||
SMSG_DELETE_CHAR = 0x003C,
|
||||
CMSG_PLAYER_LOGIN = 0x003D,
|
||||
|
||||
@ -91,7 +91,7 @@ RealmConnection::RealmConnection(RealmResponse* realmResponse) {
|
||||
this->SetMessageHandler(SMSG_AUTH_RESPONSE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_ADDON_INFO, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_ENUM_CHARACTERS_RESULT, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_CREATE_CHAR, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_CHAR_CREATE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_CHARACTER_LOGIN_FAILED, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_LOGOUT_COMPLETE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_LOGOUT_CANCEL_ACK, &RealmConnection::MessageHandler, this);
|
||||
|
||||
@ -95,6 +95,10 @@ void CGObject_C::Disable() {
|
||||
this->m_disableTimeMs = CWorld::GetCurTimeMs();
|
||||
}
|
||||
|
||||
float CGObject_C::GetFacing() const {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
int32_t CGObject_C::GetModelFileName(const char*& name) const {
|
||||
return false;
|
||||
}
|
||||
@ -103,6 +107,10 @@ CM2Model* CGObject_C::GetObjectModel() {
|
||||
return this->m_model;
|
||||
}
|
||||
|
||||
C3Vector CGObject_C::GetPosition() const {
|
||||
return { 0.0f, 0.0f, 0.0f };
|
||||
}
|
||||
|
||||
int32_t CGObject_C::IsInReenable() {
|
||||
return this->m_inReenable;
|
||||
}
|
||||
|
||||
@ -36,6 +36,10 @@ class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID
|
||||
virtual void HandleOutOfRange(OUT_OF_RANGE_TYPE type) {};
|
||||
virtual void UpdateWorldObject(int32_t a2);
|
||||
// TODO
|
||||
virtual C3Vector GetPosition() const;
|
||||
// TODO
|
||||
virtual float GetFacing() const;
|
||||
// TODO
|
||||
virtual int32_t GetModelFileName(const char*& name) const;
|
||||
// TODO
|
||||
virtual int32_t CanHighlight();
|
||||
|
||||
112
src/ui/game/CGCamera.cpp
Normal file
112
src/ui/game/CGCamera.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "ui/game/CGCamera.hpp"
|
||||
#include "ui/game/Types.hpp"
|
||||
#include "console/CVar.hpp"
|
||||
#include "world/World.hpp"
|
||||
#include <storm/String.hpp>
|
||||
#include <tempest/Math.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
static CVar* s_cameraView;
|
||||
|
||||
CGCamera::CameraViewData CGCamera::s_cameraViewDataDefault[MAX_CAMERA_VIEWS] = {
|
||||
{ "0.0", "0.0", "0.0" }, // VIEW_FIRST_PERSON
|
||||
{ "0.0", "0.0", "0.0" }, // VIEW_THIRD_PERSON_A
|
||||
{ "5.55", "10.0", "0.0" }, // VIEW_THIRD_PERSON_B
|
||||
{ "5.55", "20.0", "0.0" }, // VIEW_THIRD_PERSON_C
|
||||
{ "13.88", "30.0", "0.0" }, // VIEW_THIRD_PERSON_D
|
||||
{ "13.88", "10.0", "0.0" }, // VIEW_THIRD_PERSON_E
|
||||
{ "0.0", "0.0", "0.0" }, // VIEW_COMMENTATOR
|
||||
{ "5.0", "10.0", "0.0" }, // VIEW_BARBER_SHOP
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
bool ValidateCameraView(CVar* var, const char* oldValue, const char* value, void* arg) {
|
||||
auto view = SStrToFloat(value);
|
||||
auto min = static_cast<float>(VIEW_FIRST_PERSON);
|
||||
auto max = static_cast<float>(VIEW_BARBER_SHOP);
|
||||
|
||||
if (view >= min && view <= max) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO ConsoleWriteA("Value out of range (%f - %f)\n", DEFAULT_COLOR, min, max);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CGCamera::CGCamera() : CSimpleCamera(CWorld::GetNearClip(), CWorld::GetFarClip(), 90.0f * CMath::DEG2RAD) {
|
||||
this->m_model = nullptr;
|
||||
|
||||
this->m_target = 0;
|
||||
this->m_relativeTo = 0;
|
||||
|
||||
this->m_view = s_cameraView->GetInt();
|
||||
|
||||
this->m_distance = SStrToFloat(CGCamera::s_cameraViewDataDefault[this->m_view].m_distance);
|
||||
this->m_yaw = 0.0f;
|
||||
this->m_pitch = SStrToFloat(CGCamera::s_cameraViewDataDefault[this->m_view].m_pitch);
|
||||
this->m_roll = 0.0f;
|
||||
|
||||
this->m_fovOffset = 0.0f;
|
||||
}
|
||||
|
||||
float CGCamera::FOV() const {
|
||||
// Clamp offset-adjusted FOV between 0pi and 1pi
|
||||
return std::min(std::max(this->m_fov + this->m_fovOffset, 0.0f), CMath::PI);
|
||||
}
|
||||
|
||||
C3Vector CGCamera::Forward() const {
|
||||
if (this->m_relativeTo) {
|
||||
return this->CSimpleCamera::Forward() * this->ParentToWorld();
|
||||
}
|
||||
|
||||
return this->CSimpleCamera::Forward();
|
||||
}
|
||||
|
||||
const WOWGUID& CGCamera::GetTarget() const {
|
||||
return this->m_target;
|
||||
}
|
||||
|
||||
int32_t CGCamera::HasModel() const {
|
||||
return this->m_model != nullptr;
|
||||
}
|
||||
|
||||
C33Matrix CGCamera::ParentToWorld() const {
|
||||
// TODO
|
||||
return {};
|
||||
}
|
||||
|
||||
C3Vector CGCamera::Right() const {
|
||||
if (this->m_relativeTo) {
|
||||
return this->CSimpleCamera::Right() * this->ParentToWorld();
|
||||
}
|
||||
|
||||
return this->CSimpleCamera::Right();
|
||||
}
|
||||
|
||||
void CGCamera::SetupWorldProjection(const CRect& projRect) {
|
||||
this->SetGxProjectionAndView(projRect);
|
||||
}
|
||||
|
||||
C3Vector CGCamera::Target() const {
|
||||
return this->m_position + this->Forward();
|
||||
}
|
||||
|
||||
C3Vector CGCamera::Up() const {
|
||||
if (this->m_relativeTo) {
|
||||
return this->CSimpleCamera::Up() * this->ParentToWorld();
|
||||
}
|
||||
|
||||
return this->CSimpleCamera::Up();
|
||||
}
|
||||
|
||||
void CameraRegisterCVars() {
|
||||
// TODO
|
||||
|
||||
s_cameraView = CVar::Register("cameraView", nullptr, 0x10, "2", &ValidateCameraView, DEFAULT);
|
||||
|
||||
// TODO
|
||||
}
|
||||
56
src/ui/game/CGCamera.hpp
Normal file
56
src/ui/game/CGCamera.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef UI_GAME_C_G_CAMERA_HPP
|
||||
#define UI_GAME_C_G_CAMERA_HPP
|
||||
|
||||
#include "ui/simple/CSimpleCamera.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
|
||||
class CM2Model;
|
||||
|
||||
class CGCamera : public CSimpleCamera {
|
||||
public:
|
||||
// Public structs
|
||||
struct CameraViewData {
|
||||
const char* m_distance;
|
||||
const char* m_pitch;
|
||||
const char* m_yaw;
|
||||
};
|
||||
|
||||
// Public static variables
|
||||
static CameraViewData s_cameraViewDataDefault[];
|
||||
|
||||
// Virtual public member functions
|
||||
virtual ~CGCamera() = default;
|
||||
virtual float FOV() const;
|
||||
virtual C3Vector Forward() const;
|
||||
virtual C3Vector Right() const;
|
||||
virtual C3Vector Up() const;
|
||||
|
||||
// Public member functions
|
||||
CGCamera();
|
||||
const WOWGUID& GetTarget() const;
|
||||
int32_t HasModel() const;
|
||||
C33Matrix ParentToWorld() const;
|
||||
void SetupWorldProjection(const CRect& projRect);
|
||||
C3Vector Target() const;
|
||||
|
||||
private:
|
||||
// Private member variables
|
||||
CM2Model* m_model;
|
||||
// TODO
|
||||
WOWGUID m_target;
|
||||
// TODO
|
||||
WOWGUID m_relativeTo;
|
||||
// TODO
|
||||
int32_t m_view;
|
||||
// TODO
|
||||
float m_distance;
|
||||
float m_yaw;
|
||||
float m_pitch;
|
||||
float m_roll;
|
||||
// TODO
|
||||
float m_fovOffset;
|
||||
};
|
||||
|
||||
void CameraRegisterCVars();
|
||||
|
||||
#endif
|
||||
@ -8,6 +8,7 @@
|
||||
#include "ui/game/ActionBarScript.hpp"
|
||||
#include "ui/game/BattlefieldInfoScript.hpp"
|
||||
#include "ui/game/BattlenetUI.hpp"
|
||||
#include "ui/game/CGCamera.hpp"
|
||||
#include "ui/game/CGCharacterModelBase.hpp"
|
||||
#include "ui/game/CGCooldown.hpp"
|
||||
#include "ui/game/CGDressUpModelFrame.hpp"
|
||||
@ -284,4 +285,8 @@ void CGGameUI::RegisterGameCVars() {
|
||||
CVar::Register("fullSizeFocusFrame", "Increases the size of the focus frame to that of the target frame", 0x20, "0", nullptr, GAME);
|
||||
|
||||
// TODO
|
||||
|
||||
CameraRegisterCVars();
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
#include "ui/game/CGWorldFrame.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "gx/Transform.hpp"
|
||||
#include "object/Client.hpp"
|
||||
#include "ui/game/CGCamera.hpp"
|
||||
#include "ui/game/PlayerName.hpp"
|
||||
#include "world/World.hpp"
|
||||
#include <storm/Memory.hpp>
|
||||
#include <tempest/Matrix.hpp>
|
||||
|
||||
@ -46,6 +50,10 @@ CGWorldFrame::CGWorldFrame(CSimpleFrame* parent) : CSimpleFrame(parent) {
|
||||
this->EnableEvent(SIMPLE_EVENT_MOUSEWHEEL, -1);
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_camera = STORM_NEW(CGCamera);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGWorldFrame::OnFrameRender(CRenderBatch* batch, uint32_t layer) {
|
||||
@ -56,10 +64,49 @@ void CGWorldFrame::OnFrameRender(CRenderBatch* batch, uint32_t layer) {
|
||||
}
|
||||
}
|
||||
|
||||
void CGWorldFrame::OnFrameSizeChanged(const CRect& rect) {
|
||||
this->CSimpleFrame::OnFrameSizeChanged(rect);
|
||||
|
||||
// Screen rect (DDC)
|
||||
this->m_screenRect.minX = std::max(this->m_rect.minX, 0.0f);
|
||||
this->m_screenRect.minY = std::max(this->m_rect.minY, 0.0f);
|
||||
this->m_screenRect.maxX = std::min(this->m_rect.maxX, NDCToDDCWidth(1.0f));
|
||||
this->m_screenRect.maxY = std::min(this->m_rect.maxY, NDCToDDCHeight(1.0f));
|
||||
|
||||
// Camera aspect ratio
|
||||
if (this->m_camera) {
|
||||
this->m_camera->SetScreenAspect(this->m_screenRect);
|
||||
}
|
||||
|
||||
// Viewport (NDC)
|
||||
DDCToNDC(this->m_rect.minX, this->m_rect.minY, &this->m_viewport.minX, &this->m_viewport.minY);
|
||||
DDCToNDC(this->m_rect.maxX, this->m_rect.maxY, &this->m_viewport.maxX, &this->m_viewport.maxY);
|
||||
this->m_viewport.minX = std::max(this->m_viewport.minX, 0.0f);
|
||||
this->m_viewport.minY = std::max(this->m_viewport.minY, 0.0f);
|
||||
this->m_viewport.maxX = std::min(this->m_viewport.maxX, 1.0f);
|
||||
this->m_viewport.maxY = std::min(this->m_viewport.maxY, 1.0f);
|
||||
}
|
||||
|
||||
void CGWorldFrame::OnWorldRender() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGWorldFrame::OnWorldUpdate() {
|
||||
// TODO
|
||||
|
||||
auto target = ClntObjMgrObjectPtr(this->m_camera->GetTarget(), TYPE_OBJECT, __FILE__, __LINE__);
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_camera->SetupWorldProjection(this->m_screenRect);
|
||||
|
||||
// TODO
|
||||
|
||||
auto targetPos = target && !this->m_camera->HasModel()
|
||||
? target->GetPosition()
|
||||
: this->m_camera->Position();
|
||||
|
||||
CWorld::Update(this->m_camera->Position(), this->m_camera->Target(), targetPos);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include "ui/simple/CSimpleFrame.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CGCamera;
|
||||
|
||||
class CGWorldFrame : public CSimpleFrame {
|
||||
public:
|
||||
// Static variables
|
||||
@ -15,11 +17,22 @@ class CGWorldFrame : public CSimpleFrame {
|
||||
|
||||
// Virtual member functions
|
||||
virtual void OnFrameRender(CRenderBatch* batch, uint32_t layer);
|
||||
// TODO
|
||||
virtual void OnFrameSizeChanged(const CRect& rect);
|
||||
|
||||
// Member functions
|
||||
CGWorldFrame(CSimpleFrame* parent);
|
||||
void OnWorldRender();
|
||||
void OnWorldUpdate();
|
||||
|
||||
private:
|
||||
// Private member variables
|
||||
// TODO
|
||||
CRect m_screenRect;
|
||||
CRect m_viewport;
|
||||
// TODO
|
||||
CGCamera* m_camera;
|
||||
// TODO
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -13,4 +13,16 @@ enum SCRIPTEVENT {
|
||||
// TODO
|
||||
};
|
||||
|
||||
enum CAMERA_VIEW {
|
||||
VIEW_FIRST_PERSON = 0,
|
||||
VIEW_THIRD_PERSON_A = 1,
|
||||
VIEW_THIRD_PERSON_B = 2,
|
||||
VIEW_THIRD_PERSON_C = 3,
|
||||
VIEW_THIRD_PERSON_D = 4,
|
||||
VIEW_THIRD_PERSON_E = 5,
|
||||
VIEW_COMMENTATOR = 6,
|
||||
VIEW_BARBER_SHOP = 7,
|
||||
MAX_CAMERA_VIEWS,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
140
src/ui/simple/CSimpleCamera.cpp
Normal file
140
src/ui/simple/CSimpleCamera.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include "ui/simple/CSimpleCamera.hpp"
|
||||
#include "gx/Transform.hpp"
|
||||
#include "model/Model2.hpp"
|
||||
#include <tempest/Math.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
void FaceDirection(const C3Vector& direction, C3Vector& xPrime, C3Vector& yPrime, C3Vector& zPrime) {
|
||||
STORM_ASSERT(CMath::fnotequal(direction.SquaredMag(), 0.0f));
|
||||
|
||||
// Forward
|
||||
xPrime = direction;
|
||||
|
||||
// Right
|
||||
if (CMath::fequal(xPrime.SquaredMag(), 0.0f)) {
|
||||
yPrime.x = 1.0f;
|
||||
yPrime.y = 0.0f;
|
||||
yPrime.z = 0.0f;
|
||||
} else {
|
||||
yPrime.x = -xPrime.y;
|
||||
yPrime.y = xPrime.x;
|
||||
yPrime.z = 0.0f;
|
||||
|
||||
CMath::normalize(yPrime.x, yPrime.y);
|
||||
}
|
||||
|
||||
// Up (Forward cross Right)
|
||||
zPrime = C3Vector::Cross(xPrime, yPrime);
|
||||
}
|
||||
|
||||
void BuildBillboardMatrix(const C3Vector& direction, C33Matrix& rotation) {
|
||||
C3Vector xPrime = {};
|
||||
C3Vector yPrime = {};
|
||||
C3Vector zPrime = {};
|
||||
|
||||
FaceDirection(direction, xPrime, yPrime, zPrime);
|
||||
|
||||
// Forward
|
||||
rotation.a0 = xPrime.x;
|
||||
rotation.a1 = xPrime.y;
|
||||
rotation.a2 = xPrime.z;
|
||||
|
||||
// Right
|
||||
rotation.b0 = yPrime.x;
|
||||
rotation.b1 = yPrime.y;
|
||||
rotation.b2 = yPrime.z;
|
||||
|
||||
// Up
|
||||
rotation.c0 = zPrime.x;
|
||||
rotation.c1 = zPrime.y;
|
||||
rotation.c2 = zPrime.z;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CSimpleCamera::CSimpleCamera(float nearZ, float farZ, float fov) {
|
||||
this->m_scene = nullptr;
|
||||
|
||||
this->m_nearZ = nearZ;
|
||||
this->m_farZ = farZ;
|
||||
this->m_fov = fov;
|
||||
this->m_aspect = 1.0f;
|
||||
|
||||
this->SetFacing(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
float CSimpleCamera::FOV() const {
|
||||
return this->m_fov;
|
||||
}
|
||||
|
||||
C3Vector CSimpleCamera::Forward() const {
|
||||
return { this->m_facing.a0, this->m_facing.a1, this->m_facing.a2 };
|
||||
}
|
||||
|
||||
CM2Scene* CSimpleCamera::GetScene() {
|
||||
if (!this->m_scene) {
|
||||
this->m_scene = M2CreateScene();
|
||||
}
|
||||
|
||||
return this->m_scene;
|
||||
}
|
||||
|
||||
C3Vector CSimpleCamera::Right() const {
|
||||
return { this->m_facing.b0, this->m_facing.b1, this->m_facing.b2 };
|
||||
}
|
||||
|
||||
const C3Vector& CSimpleCamera::Position() const {
|
||||
return this->m_position;
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetFacing(const C3Vector& forward) {
|
||||
BuildBillboardMatrix(forward, this->m_facing);
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetFacing(const C3Vector& forward, const C3Vector& up) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetFacing(float yaw, float pitch, float roll) {
|
||||
this->m_facing.FromEulerAnglesZYX(yaw, pitch, roll);
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetFarZ(float farZ) {
|
||||
this->m_farZ = farZ;
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetFieldOfView(float fov) {
|
||||
this->m_fov = fov;
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetGxProjectionAndView(const CRect& projRect) {
|
||||
// Projection
|
||||
|
||||
this->m_aspect = (projRect.maxX - projRect.minX) / (projRect.maxY - projRect.minY);
|
||||
|
||||
C44Matrix projMat;
|
||||
GxuXformCreateProjection_Exact(this->FOV() * 0.6f, this->m_aspect, this->m_nearZ, this->m_farZ, projMat);
|
||||
|
||||
GxXformSetProjection(projMat);
|
||||
|
||||
// View
|
||||
|
||||
C3Vector eye;
|
||||
C44Matrix viewMat;
|
||||
GxuXformCreateLookAtSgCompat(eye, this->Forward(), this->Up(), viewMat);
|
||||
|
||||
GxXformSetView(viewMat);
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetNearZ(float nearZ) {
|
||||
this->m_nearZ = nearZ;
|
||||
}
|
||||
|
||||
void CSimpleCamera::SetScreenAspect(const CRect& screenRect) {
|
||||
this->m_aspect = (screenRect.maxX - screenRect.minX) / (screenRect.maxY - screenRect.minY);
|
||||
}
|
||||
|
||||
C3Vector CSimpleCamera::Up() const {
|
||||
return { this->m_facing.c0, this->m_facing.c1, this->m_facing.c2 };
|
||||
}
|
||||
42
src/ui/simple/CSimpleCamera.hpp
Normal file
42
src/ui/simple/CSimpleCamera.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef UI_SIMPLE_C_SIMPLE_CAMERA_HPP
|
||||
#define UI_SIMPLE_C_SIMPLE_CAMERA_HPP
|
||||
|
||||
#include <tempest/Matrix.hpp>
|
||||
#include <tempest/Rect.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CM2Scene;
|
||||
|
||||
class CSimpleCamera {
|
||||
public:
|
||||
// Virtual public member functions
|
||||
virtual float FOV() const;
|
||||
virtual C3Vector Forward() const;
|
||||
virtual C3Vector Right() const;
|
||||
virtual C3Vector Up() const;
|
||||
|
||||
// Public member functions
|
||||
CSimpleCamera(float nearZ, float farZ, float fov);
|
||||
CM2Scene* GetScene();
|
||||
const C3Vector& Position() const;
|
||||
void SetFacing(const C3Vector& forward);
|
||||
void SetFacing(const C3Vector& forward, const C3Vector& up);
|
||||
void SetFacing(float yaw, float pitch, float roll);
|
||||
void SetFarZ(float farZ);
|
||||
void SetFieldOfView(float fov);
|
||||
void SetGxProjectionAndView(const CRect& projRect);
|
||||
void SetNearZ(float nearZ);
|
||||
void SetScreenAspect(const CRect& screenRect);
|
||||
|
||||
protected:
|
||||
// Protected member variables
|
||||
CM2Scene* m_scene;
|
||||
C3Vector m_position;
|
||||
C33Matrix m_facing;
|
||||
float m_nearZ;
|
||||
float m_farZ;
|
||||
float m_fov;
|
||||
float m_aspect;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -2,6 +2,7 @@
|
||||
#include "gx/Gx.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "model/Model2.hpp"
|
||||
#include "world/CWorldParam.hpp"
|
||||
#include "world/Map.hpp"
|
||||
#include "world/Weather.hpp"
|
||||
#include <storm/Memory.hpp>
|
||||
@ -10,14 +11,36 @@ uint32_t CWorld::s_curTimeMs;
|
||||
float CWorld::s_curTimeSec;
|
||||
uint32_t CWorld::s_enables;
|
||||
uint32_t CWorld::s_enables2;
|
||||
float CWorld::s_farClip;
|
||||
uint32_t CWorld::s_gameTimeFixed;
|
||||
float CWorld::s_gameTimeSec;
|
||||
CM2Scene* CWorld::s_m2Scene;
|
||||
float CWorld::s_nearClip = 0.1f;
|
||||
float CWorld::s_prevFarClip;
|
||||
uint32_t CWorld::s_tickTimeFixed;
|
||||
uint32_t CWorld::s_tickTimeMs;
|
||||
float CWorld::s_tickTimeSec;
|
||||
Weather* CWorld::s_weather;
|
||||
|
||||
namespace {
|
||||
|
||||
float AdjustFarClip(float farClip, int32_t mapID) {
|
||||
float minFarClip = 183.33333f;
|
||||
float maxFarClip = 1583.3334f;
|
||||
|
||||
if (mapID < 530 || mapID == 575 || mapID == 543) {
|
||||
if (!CWorldParam::cvar_farClipOverride || CWorldParam::cvar_farClipOverride->GetInt() < 1) {
|
||||
maxFarClip = 791.66669f;
|
||||
}
|
||||
} else if (false /* TODO OsGetPhysicalMemory() <= 1073741824 */) {
|
||||
maxFarClip = 791.66669f;
|
||||
}
|
||||
|
||||
return std::min(std::max(farClip, minFarClip), maxFarClip);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HWORLDOBJECT CWorld::AddObject(CM2Model* model, void* handler, void* handlerParam, uint64_t param64, uint32_t param32, uint32_t objFlags) {
|
||||
auto entity = CMap::AllocEntity(objFlags & 0x8 ? true : false);
|
||||
|
||||
@ -55,6 +78,10 @@ float CWorld::GetCurTimeSec() {
|
||||
return CWorld::s_curTimeSec;
|
||||
}
|
||||
|
||||
float CWorld::GetFarClip() {
|
||||
return CWorld::s_farClip;
|
||||
}
|
||||
|
||||
uint32_t CWorld::GetFixedPrecisionTime(float timeSec) {
|
||||
return static_cast<uint32_t>(timeSec * 1024.0f);
|
||||
}
|
||||
@ -71,6 +98,10 @@ CM2Scene* CWorld::GetM2Scene() {
|
||||
return CWorld::s_m2Scene;
|
||||
}
|
||||
|
||||
float CWorld::GetNearClip() {
|
||||
return CWorld::s_nearClip;
|
||||
}
|
||||
|
||||
uint32_t CWorld::GetTickTimeFixed() {
|
||||
return CWorld::s_tickTimeFixed;
|
||||
}
|
||||
@ -133,10 +164,14 @@ void CWorld::Initialize() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CWorld::LoadMap(const char* mapName, const C3Vector& position, int32_t zoneID) {
|
||||
void CWorld::LoadMap(const char* mapName, const C3Vector& position, int32_t mapID) {
|
||||
CWorld::s_farClip = AdjustFarClip(CWorldParam::cvar_farClip->GetFloat(), mapID);
|
||||
CWorld::s_nearClip = 0.2f;
|
||||
CWorld::s_prevFarClip = CWorld::s_farClip;
|
||||
|
||||
// TODO
|
||||
|
||||
CMap::Load(mapName, zoneID);
|
||||
CMap::Load(mapName, mapID);
|
||||
|
||||
// TODO
|
||||
}
|
||||
@ -147,6 +182,24 @@ int32_t CWorld::OnTick(const EVENT_DATA_TICK* data, void* param) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CWorld::SetFarClip(float farClip) {
|
||||
farClip = AdjustFarClip(farClip, CMap::s_mapID);
|
||||
|
||||
if (CWorld::s_farClip == farClip) {
|
||||
return;
|
||||
}
|
||||
|
||||
CWorld::s_prevFarClip = CWorld::s_farClip;
|
||||
CWorld::s_farClip = farClip;
|
||||
|
||||
// TODO CMapRenderChunk::DirtyPools();
|
||||
|
||||
CWorld::s_nearClip = 0.2f;
|
||||
|
||||
// TODO dword_D1C410 = 1;
|
||||
// TODO dword_ADEEE0 = 1;
|
||||
}
|
||||
|
||||
void CWorld::SetUpdateTime(float tickTimeSec, uint32_t curTimeMs) {
|
||||
auto tickTimeFixed = CWorld::GetFixedPrecisionTime(tickTimeSec);
|
||||
|
||||
@ -160,3 +213,7 @@ void CWorld::SetUpdateTime(float tickTimeSec, uint32_t curTimeMs) {
|
||||
CWorld::s_tickTimeMs = static_cast<uint32_t>(tickTimeSec * 1000.0f);
|
||||
CWorld::s_tickTimeSec = tickTimeSec;
|
||||
}
|
||||
|
||||
void CWorld::Update(const C3Vector& cameraPos, const C3Vector& cameraTarget, const C3Vector& targetPos) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@ -57,24 +57,31 @@ class CWorld {
|
||||
static HWORLDOBJECT AddObject(CM2Model* model, void* handler, void* handlerParam, uint64_t param64, uint32_t param32, uint32_t objFlags);
|
||||
static uint32_t GetCurTimeMs();
|
||||
static float GetCurTimeSec();
|
||||
static float GetFarClip();
|
||||
static uint32_t GetGameTimeFixed();
|
||||
static float GetGameTimeSec();
|
||||
static CM2Scene* GetM2Scene();
|
||||
static float GetNearClip();
|
||||
static uint32_t GetTickTimeFixed();
|
||||
static uint32_t GetTickTimeMs();
|
||||
static float GetTickTimeSec();
|
||||
static void Initialize();
|
||||
static void LoadMap(const char* mapName, const C3Vector& position, int32_t zoneID);
|
||||
static void LoadMap(const char* mapName, const C3Vector& position, int32_t mapID);
|
||||
static int32_t OnTick(const EVENT_DATA_TICK* data, void* param);
|
||||
static void SetFarClip(float farClip);
|
||||
static void SetUpdateTime(float tickTimeSec, uint32_t curTimeMs);
|
||||
static void Update(const C3Vector& cameraPos, const C3Vector& cameraTarget, const C3Vector& targetPos);
|
||||
|
||||
private:
|
||||
// Private static variables
|
||||
static uint32_t s_curTimeMs;
|
||||
static float s_curTimeSec;
|
||||
static float s_farClip;
|
||||
static uint32_t s_gameTimeFixed;
|
||||
static float s_gameTimeSec;
|
||||
static CM2Scene* s_m2Scene;
|
||||
static float s_nearClip;
|
||||
static float s_prevFarClip;
|
||||
static uint32_t s_tickTimeFixed;
|
||||
static uint32_t s_tickTimeMs;
|
||||
static float s_tickTimeSec;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "world/CWorldParam.hpp"
|
||||
#include "world/CWorld.hpp"
|
||||
#include "console/CVar.hpp"
|
||||
|
||||
CVar* CWorldParam::cvar_baseMip;
|
||||
@ -53,7 +54,8 @@ bool CWorldParam::ExtShadowQualityCallback(CVar* var, const char* oldValue, cons
|
||||
}
|
||||
|
||||
bool CWorldParam::FarClipCallback(CVar* var, const char* oldValue, const char* value, void* arg) {
|
||||
// TODO
|
||||
CWorld::SetFarClip(SStrToFloat(value));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef WORLD_C_WORLD_PARAM_HPP
|
||||
#define WORLD_C_WORLD_PARAM_HPP
|
||||
|
||||
class CVar;
|
||||
#include "console/CVar.hpp"
|
||||
|
||||
class CWorldParam {
|
||||
public:
|
||||
|
||||
@ -28,6 +28,7 @@ uint32_t* CMap::s_mapObjDefGroupHeap;
|
||||
uint32_t* CMap::s_mapObjDefHeap;
|
||||
uint32_t* CMap::s_mapObjGroupHeap;
|
||||
uint32_t* CMap::s_mapObjHeap;
|
||||
int32_t CMap::s_mapID = -1;
|
||||
char CMap::s_mapName[256];
|
||||
char CMap::s_mapPath[256];
|
||||
char CMap::s_wdtFilename[256];
|
||||
@ -61,7 +62,7 @@ void CMap::Initialize() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CMap::Load(const char* mapName, int32_t zoneID) {
|
||||
void CMap::Load(const char* mapName, int32_t mapID) {
|
||||
// TODO
|
||||
|
||||
auto nameOfs = SStrCopy(CMap::s_mapPath, "World\\Maps\\");
|
||||
@ -72,6 +73,10 @@ void CMap::Load(const char* mapName, int32_t zoneID) {
|
||||
SStrPrintf(CMap::s_wdtFilename, sizeof(CMap::s_wdtFilename), "%s\\%s.wdt", CMap::s_mapPath, CMap::s_mapName);
|
||||
|
||||
// TODO
|
||||
|
||||
CMap::s_mapID = mapID;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CMap::MapMemInitialize() {
|
||||
|
||||
@ -23,6 +23,7 @@ class CMap {
|
||||
static uint32_t* s_mapObjDefHeap;
|
||||
static uint32_t* s_mapObjGroupHeap;
|
||||
static uint32_t* s_mapObjHeap;
|
||||
static int32_t s_mapID;
|
||||
static char s_mapName[];
|
||||
static char s_mapPath[];
|
||||
static char s_wdtFilename[];
|
||||
@ -30,7 +31,7 @@ class CMap {
|
||||
// Static functions
|
||||
static CMapEntity* AllocEntity(int32_t a1);
|
||||
static void Initialize();
|
||||
static void Load(const char* mapName, int32_t zoneID);
|
||||
static void Load(const char* mapName, int32_t mapID);
|
||||
static void MapMemInitialize();
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user