Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quaternions #1796

Draft
wants to merge 50 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
54dd6ca
Quternion draft. Untested, must be bugged as hell
lhog Sep 10, 2021
b102c48
Fix
lhog Dec 3, 2024
bfa91c6
Switch CQuaternion to use basic types to give the compiler more optio…
lhog Dec 3, 2024
564f0a5
WIP
lhog Dec 5, 2024
66182fa
Undo WIP for now
lhog Dec 8, 2024
ef89c4f
Moved S3DModelPiece to use Transform/Quaternions(partially)
lhog Dec 10, 2024
9a76c89
Fix accelerate to infinity bug
lhog Dec 11, 2024
b17fe0d
Remove CMatrix44f::FromTQS
lhog Dec 11, 2024
1147df6
Add some Normalization rigor
lhog Dec 11, 2024
93ae2ca
Switch to more compact CQuaternion::Rotate() version
lhog Dec 11, 2024
dd6e0b0
More fixes
lhog Dec 11, 2024
95c3ba2
More fixes 2
lhog Dec 11, 2024
4537ce8
Change
lhog Dec 11, 2024
1460c08
Bugfixes and further migration
lhog Dec 11, 2024
97dd2cf
Typo
lhog Dec 11, 2024
cc880e0
Formatting
lhog Dec 11, 2024
9505676
Add CMatrix44f::equal()
lhog Dec 11, 2024
22de98c
Fixes and more tests
lhog Dec 12, 2024
198b04f
Fix to CQuaternion::DecomposeIntoTRS()
lhog Dec 12, 2024
12c508c
Add operator* to transform float3/4 by the Transform state
lhog Dec 12, 2024
eef6d6c
Add the rate of change to all animation routines, not wired to the re…
lhog Dec 12, 2024
1491c78
-
lhog Dec 12, 2024
81e041e
Normalization rigor in CQuaternion::MakeFrom(const float3& v1, const …
lhog Dec 12, 2024
d826700
+ to the previous
lhog Dec 12, 2024
6d07ccb
Comments formatting
lhog Dec 12, 2024
b201c6b
Fix compilation?
lhog Dec 12, 2024
ae61a7c
Fix compilation for real
lhog Dec 13, 2024
20316ec
Minor changes + Euler angles implementation (correctness to be verified)
lhog Dec 13, 2024
e85f223
Fix Euler angles in CQuaternion. Migrate S3DModelPiece::ComposeTransf…
lhog Dec 13, 2024
3897048
Small improvements
lhog Dec 14, 2024
713c742
A few minor changes
lhog Dec 14, 2024
3240bd2
Convert Transform::FromMatrix to static
lhog Dec 14, 2024
caa0843
Switch to a single uniform scaling factor for model pieces / local mo…
lhog Dec 14, 2024
836ba67
Compilation fix
lhog Dec 14, 2024
154397b
SetBakedMatrix --> SetBakedTransform
lhog Dec 14, 2024
c214f8e
A bunch of renames before changing from CMatrix44f --> Transform
lhog Dec 14, 2024
5097507
WIP
lhog Dec 14, 2024
b2ff07b
Make UpdateList a separate entity
lhog Aug 3, 2024
f332c07
Actually checkout UpdateList.cpp/UpdateList.h
lhog Dec 14, 2024
8f1a20a
++
lhog Dec 14, 2024
3356c6a
Big refactoring before switching from CMatrix44f to Transform
lhog Dec 15, 2024
f0c7043
++
lhog Dec 15, 2024
9573bd7
Fix? compilation
lhog Dec 15, 2024
2e810b2
Fix float3::PickNonParallel()
lhog Dec 15, 2024
7090d65
Misc
lhog Dec 15, 2024
a91f1fc
Remove CRTP/inheritance from ModelsMemStorage
lhog Dec 15, 2024
67366b6
Misc
lhog Dec 15, 2024
6769034
Fixes / misc
lhog Dec 15, 2024
06f93bf
Remove invalid asserts, alingas(16) ModelUniformData
lhog Dec 15, 2024
8aab2c2
First fugly version with GL4 quaternion shader
lhog Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 54 additions & 19 deletions cont/base/springcontent/shaders/GLSL/ModelVertProgGL4.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,13 @@ layout(std140, binding = 1) uniform UniformParamsBuffer {
vec4 teamColor[255]; //all team colors
};

layout(std140, binding = 0) readonly buffer MatrixBuffer {
mat4 mat[];
struct Transform {
vec4 quat;
vec4 trSc;
};

layout(std140, binding = 0) readonly buffer TransformBuffer {
Transform transforms[];
};

uniform int cameraMode = 0;
Expand Down Expand Up @@ -114,7 +119,7 @@ out Data {
};
out float gl_ClipDistance[3];

#line 1117
#line 1122

void TransformPlayerCam(vec4 worldPos) {
gl_Position = cameraViewProj * worldPos;
Expand All @@ -132,6 +137,37 @@ uint GetUnpackedValue(uint packedValue, uint byteNum) {
return (packedValue >> (8u * byteNum)) & 0xFFu;
}

vec4 MultiplyQuat(vec4 a, vec4 b)
{
return vec4(a.w * b.w - dot(a.w, b.w), a.w * b.xyz + b.w * a.xyz + cross(a.xyz, b.xyz));
}

vec3 RotateByQuaternion(vec4 q, vec3 v) {
return 2.0f * dot(q.xyz, v) * q.xyz + (q.w * q.w - dot(q.xyz, q.xyz)) * v + 2.0 * q.w * cross(q.xyz, v);
}

vec4 RotateByQuaternion(vec4 q, vec4 v) {
return vec4(RotateByQuaternion(q, v.xyz), v.w);
}

vec3 ApplyTransform(Transform tra, vec3 v) {
return RotateByQuaternion(tra.quat, v * tra.trSc.w) + tra.trSc.xyz;
}

vec4 ApplyTransform(Transform tra, vec4 v) {
return vec4(ApplyTransform(tra, v.xyz), v.w);
}

Transform ApplyTransform(Transform parentTra, Transform childTra) {
return Transform(
MultiplyQuat(parentTra.quat, childTra.quat),
vec4(
parentTra.trSc.xyz + RotateByQuaternion(parentTra.quat, parentTra.trSc.w * childTra.trSc.xyz),
parentTra.trSc.w * childTra.trSc.w
)
);
}

void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
{
bool staticModel = (matrixMode > 0);
Expand All @@ -146,13 +182,12 @@ void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
);

uint b0 = GetUnpackedValue(bonesInfo.x, 0); //first boneID
mat4 b0BoneMat = mat[instData.x + b0 + uint(!staticModel)];
mat3 b0NormMat = mat3(b0BoneMat);
Transform b0BoneTra = transforms[instData.x + b0 + uint(!staticModel)];

weights[0] *= b0BoneMat[3][3];
weights[0] *= step(0.0, b0BoneTra.trSc.w);

msPosition = b0BoneMat * piecePos;
msNormal = b0NormMat * normal;
msPosition = ApplyTransform(b0BoneTra, piecePos);
msNormal = RotateByQuaternion(b0BoneTra.quat, normal);

if (staticModel || weights[0] == 1.0)
return;
Expand All @@ -164,7 +199,7 @@ void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
wSum += weights[0];

uint numPieces = GetUnpackedValue(instData.z, 3);
mat4 bposeMat = mat[instData.w + b0];
Transform bposeTra = transforms[instData.w + b0];

// Vertex[ModelSpace,BoneX] = PieceMat[BoneX] * InverseBindPosMat[BoneX] * BindPosMat[Bone0] * Vertex[Bone0]
for (uint bi = 1; bi < 3; ++bi) {
Expand All @@ -173,16 +208,15 @@ void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
if (bID == 0xFFu || weights[bi] == 0.0)
continue;

mat4 bposeInvMat = mat[instData.w + numPieces + bID];
mat4 boneMat = mat[instData.x + 1u + bID];
Transform bposeInvTra = transforms[instData.w + numPieces + bID];
Transform boneTra = transforms[instData.x + 1u + bID];

weights[bi] *= boneMat[3][3];
weights[bi] *= step(0.0, boneTra.trSc.w);

mat4 skinMat = boneMat * bposeInvMat * bposeMat;
mat3 normMat = mat3(skinMat);
Transform skinTra = ApplyTransform(ApplyTransform(boneTra, bposeInvTra), bposeTra);

msPosition += skinMat * piecePos * weights[bi];
msNormal += normMat * normal * weights[bi];
msPosition += ApplyTransform(skinTra, piecePos * weights[bi]);
msNormal += RotateByQuaternion(skinTra.quat, normal * weights[bi]);
wSum += weights[bi];
}

Expand All @@ -194,14 +228,15 @@ void main(void)
{
bool staticModel = (matrixMode > 0);

mat4 worldMatrix = staticModel ? staticModelMatrix : mat[instData.x]; //don't cover ARRAY_MATMODE yet
//mat4 worldMatrix = staticModel ? staticModelMatrix : mat[instData.x]; //don't cover ARRAY_MATMODE yet
Transform worldTra = transforms[instData.x]; //don't cover ARRAY_MATMODE yet

vec4 modelPos;
vec3 modelNormal;
GetModelSpaceVertex(modelPos, modelNormal);

worldPos = worldMatrix * modelPos;
worldNormal = mat3(worldMatrix) * modelNormal;
worldPos = ApplyTransform(worldTra, modelPos);
worldNormal = RotateByQuaternion(worldTra.quat, modelNormal);

gl_ClipDistance[0] = dot(modelPos, clipPlane0); //upper construction clip plane
gl_ClipDistance[1] = dot(modelPos, clipPlane1); //lower construction clip plane
Expand Down
19 changes: 13 additions & 6 deletions rts/Game/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,11 @@ void CGame::PreLoadRendering()
geometricObjects = new CGeometricObjects();

// load components that need to exist before PostLoadSimulation
matrixUploader.Init();
modelsUniformsUploader.Init();
modelUniformsStorage.Init();
//transformsMemStorage.Init(); // Add?

transformsUploader.Init();
modelUniformsUploader.Init();
worldDrawer.InitPre();
}

Expand Down Expand Up @@ -997,8 +1000,9 @@ void CGame::KillRendering()
icon::iconHandler.Kill();
spring::SafeDelete(geometricObjects);
worldDrawer.Kill();
matrixUploader.Kill();
modelsUniformsUploader.Kill();

transformsUploader.Kill();
modelUniformsUploader.Kill();
}

void CGame::KillInterface()
Expand Down Expand Up @@ -1041,6 +1045,9 @@ void CGame::KillSimulation()
unitHandler.Kill();
projectileHandler.Kill();

modelUniformsStorage.Kill();
//transformsMemStorage.Kill(); //Add?

LOG("[Game::%s][3]", __func__);
IPathManager::FreeInstance(pathManager);
IMapDamage::FreeMapDamage(mapDamage);
Expand Down Expand Up @@ -1470,8 +1477,8 @@ bool CGame::UpdateUnsynced(const spring_time currentTime)
shadowHandler.Update();
{
worldDrawer.Update(newSimFrame);
matrixUploader.Update();
modelsUniformsUploader.Update();
transformsUploader.Update();
modelUniformsUploader.Update();
}

mouse->UpdateCursorCameraDir(); // make sure mouse->dir is in sync with camera
Expand Down
2 changes: 1 addition & 1 deletion rts/Lua/LuaOpenGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1423,7 +1423,7 @@ static void GLObjectPieceMultMatrix(lua_State* L, const CSolidObject* obj)
if (lmp == nullptr)
return;

glMultMatrixf(lmp->GetModelSpaceMatrix());
glMultMatrixf(lmp->GetModelSpaceTransform().ToMatrix());
}

static bool GLObjectDrawWithLuaMat(lua_State* L, CSolidObject* obj, LuaObjType objType)
Expand Down
2 changes: 1 addition & 1 deletion rts/Lua/LuaShaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ namespace {
if (o == nullptr)
luaL_error(L, "gl.%s() Invalid %s id (%d)", func, &spring::TypeToCStr<T>()[1], id);

ModelUniformData& uni = modelsUniformsStorage.GetObjUniformsArray(o);
ModelUniformData& uni = modelUniformsStorage.GetObjUniformsArray(o);

std::array<float, ModelUniformData::MAX_MODEL_UD_UNIFORMS> floatArray = {0};
int size = LuaUtils::ParseFloatArray(L, 2, floatArray.data(), ModelUniformData::MAX_MODEL_UD_UNIFORMS);
Expand Down
2 changes: 1 addition & 1 deletion rts/Lua/LuaSyncedRead.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8245,7 +8245,7 @@ static int GetSolidObjectPieceMatrix(lua_State* L, const CSolidObject* o)
if (lmp == nullptr)
return 0;

const CMatrix44f& mat = lmp->GetModelSpaceMatrix();
const CMatrix44f& mat = lmp->GetModelSpaceTransform().ToMatrix();

for (float mi: mat.m) {
lua_pushnumber(L, mi);
Expand Down
8 changes: 4 additions & 4 deletions rts/Lua/LuaVBOImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,8 +986,8 @@ SInstanceData LuaVBOImpl::InstanceDataFromGetData(int id, int attrID, uint8_t de
uint32_t teamID = defTeamID;

const TObj* obj = LuaUtils::SolIdToObject<TObj>(id, __func__);
const uint32_t matOffset = static_cast<uint32_t>(matrixUploader.GetElemOffset(obj));
const uint32_t uniIndex = static_cast<uint32_t>(modelsUniformsStorage.GetObjOffset(obj)); //doesn't need to exist for defs and model. Don't check for validity
const uint32_t matOffset = static_cast<uint32_t>(transformsUploader.GetElemOffset(obj));
const uint32_t uniIndex = static_cast<uint32_t>(modelUniformsStorage.GetObjOffset(obj)); //doesn't need to exist for defs and model. Don't check for validity

if (matOffset == ~0u) {
LuaUtils::SolLuaError("[LuaVBOImpl::%s] Invalid data supplied. See infolog for details", __func__);
Expand All @@ -1003,11 +1003,11 @@ SInstanceData LuaVBOImpl::InstanceDataFromGetData(int id, int attrID, uint8_t de
size_t bposeIndex = 0;
if constexpr (std::is_same<TObj, S3DModel>::value) {
numPieces = static_cast<uint8_t>(obj->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj);
bposeIndex = transformsUploader.GetElemOffset(obj);
}
else {
numPieces = static_cast<uint8_t>(obj->model->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj->model);
bposeIndex = transformsUploader.GetElemOffset(obj->model);
}

return SInstanceData(matOffset, teamID, drawFlags, numPieces, uniIndex, bposeIndex);
Expand Down
1 change: 1 addition & 0 deletions rts/Rendering/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ set(sources_engine_Rendering
"${CMAKE_CURRENT_SOURCE_DIR}/Common/ModelDrawerData.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/ModelDrawerState.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/ModelDrawerHelpers.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/UpdateList.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Features/FeatureDrawerData.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Features/FeatureDrawer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Units/UnitDrawerData.cpp"
Expand Down
4 changes: 2 additions & 2 deletions rts/Rendering/Common/ModelDrawer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

namespace GL { struct GeometryBuffer; }
template<typename T> class ScopedModelDrawerImpl;
class ScopedMatricesMemAlloc;
class ScopedTransformMemAlloc;


static constexpr const char* ModelDrawerNames[ModelDrawerTypes::MODEL_DRAWER_CNT] = {
Expand Down Expand Up @@ -110,7 +110,7 @@ class CModelDrawerBase : public CModelDrawerConcept {
static bool CanDrawDeferred() { return modelDrawerState->CanDrawDeferred(); }
static bool SetTeamColor(int team, const float alpha = 1.0f) { return modelDrawerState->SetTeamColor(team, alpha); }
static void SetNanoColor(const float4& color) { modelDrawerState->SetNanoColor(color); }
static const ScopedMatricesMemAlloc& GetMatricesMemAlloc(const ObjType* o) { return const_cast<const TDrawerData*>(modelDrawerData)->GetObjectMatricesMemAlloc(o); }
static const ScopedTransformMemAlloc& GetTransformMemAlloc(const ObjType* o) { return const_cast<const TDrawerData*>(modelDrawerData)->GetObjectTransformMemAlloc(o); }
public:
virtual void Update() const = 0;
// Draw*
Expand Down
41 changes: 21 additions & 20 deletions rts/Rendering/Common/ModelDrawerData.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ class CModelDrawerDataBase : public CModelDrawerDataConcept

void ClearPreviousDrawFlags() { for (auto object : unsortedObjects) object->previousDrawFlag = 0; }

const ScopedMatricesMemAlloc& GetObjectMatricesMemAlloc(const T* o) const {
const auto it = matricesMemAllocs.find(const_cast<T*>(o));
return (it != matricesMemAllocs.end()) ? it->second : ScopedMatricesMemAlloc::Dummy();
const auto& GetObjectTransformMemAlloc(const T* o) const {
const auto it = scTransMemAllocMap.find(const_cast<T*>(o));
return (it != scTransMemAllocMap.end()) ? it->second : ScopedTransformMemAlloc::Dummy();
}
ScopedMatricesMemAlloc& GetObjectMatricesMemAlloc(const T* o) { return matricesMemAllocs[const_cast<T*>(o)]; }
auto& GetObjectTransformMemAlloc(const T* o) { return scTransMemAllocMap[const_cast<T*>(o)]; }
private:
static constexpr int MMA_SIZE0 = 2 << 16;
protected:
std::array<ModelRenderContainer<T>, MODELTYPE_CNT> modelRenderers;

std::vector<T*> unsortedObjects;
std::unordered_map<T*, ScopedMatricesMemAlloc> matricesMemAllocs;
std::unordered_map<T*, ScopedTransformMemAlloc> scTransMemAllocMap;

bool& mtModelDrawer;
};
Expand All @@ -100,15 +100,15 @@ inline CModelDrawerDataBase<T>::CModelDrawerDataBase(const std::string& ecName,
: CModelDrawerDataConcept(ecName, ecOrder)
, mtModelDrawer(mtModelDrawer_)
{
matricesMemAllocs.reserve(MMA_SIZE0);
scTransMemAllocMap.reserve(MMA_SIZE0);
for (auto& mr : modelRenderers) { mr.Clear(); }
}

template<typename T>
inline CModelDrawerDataBase<T>::~CModelDrawerDataBase()
{
unsortedObjects.clear();
matricesMemAllocs.clear();
scTransMemAllocMap.clear();
}

template<typename T>
Expand All @@ -126,9 +126,9 @@ inline void CModelDrawerDataBase<T>::AddObject(const T* co, bool add)
unsortedObjects.emplace_back(o);

const uint32_t numMatrices = (o->model ? o->model->numPieces : 0) + 1u;
matricesMemAllocs.emplace(o, ScopedMatricesMemAlloc(numMatrices));
scTransMemAllocMap.emplace(o, ScopedTransformMemAlloc(numMatrices));

modelsUniformsStorage.GetObjOffset(co);
modelUniformsStorage.AddObject(co);
}

template<typename T>
Expand All @@ -141,8 +141,8 @@ inline void CModelDrawerDataBase<T>::DelObject(const T* co, bool del)
}

if (del && spring::VectorErase(unsortedObjects, o)) {
matricesMemAllocs.erase(o);
modelsUniformsStorage.GetObjOffset(co);
scTransMemAllocMap.erase(o);
modelUniformsStorage.DelObject(co);
}
}

Expand All @@ -157,15 +157,13 @@ inline void CModelDrawerDataBase<T>::UpdateObject(const T* co, bool init)
template<typename T>
inline void CModelDrawerDataBase<T>::UpdateObjectSMMA(const T* o)
{
ScopedMatricesMemAlloc& smma = GetObjectMatricesMemAlloc(o);
ScopedTransformMemAlloc& smma = GetObjectTransformMemAlloc(o);

const auto tmNew = o->GetTransformMatrix();
const auto& tmOld = const_cast<const ScopedMatricesMemAlloc&>(smma)[0];
const auto tmNew = Transform::FromMatrix(o->GetTransformMatrix());

// from one point it doesn't worth the comparison, cause units usually move
// but having not updated smma[0] allows for longer solid no-update areas in ModelsUniformsUploader::UpdateDerived()
if (tmNew != tmOld)
smma[0] = tmNew;
// but having not updated smma[0] allows for longer solid no-update areas in ModelUniformsUploader::UpdateDerived()
smma.UpdateIfChanged(0, tmNew);

for (int i = 0; i < o->localModel.pieces.size(); ++i) {
const LocalModelPiece& lmp = o->localModel.pieces[i];
Expand All @@ -175,22 +173,25 @@ inline void CModelDrawerDataBase<T>::UpdateObjectSMMA(const T* o)
continue;

if unlikely(!lmp.GetScriptVisible()) {
smma[i + 1] = CMatrix44f::Zero();
//smma[i + 1] = CMatrix44f::Zero();
smma.UpdateForced(i + 1, Transform::Zero());
continue;
}

smma[i + 1] = lmp.GetModelSpaceMatrix();
// UpdateIfChanged is not needed, wasCustomDirty takes that role
smma.UpdateForced(i + 1, lmp.GetModelSpaceTransform());
}
}

template<typename T>
inline void CModelDrawerDataBase<T>::UpdateObjectUniforms(const T* o)
{
auto& uni = modelsUniformsStorage.GetObjUniformsArray(o);
auto& uni = modelUniformsStorage.GetObjUniformsArray(o);
uni.drawFlag = o->drawFlag;

if (gu->spectatingFullView || o->IsInLosForAllyTeam(gu->myAllyTeam)) {
uni.id = o->id;
// TODO remove drawPos, replace with pos
uni.drawPos = float4{ o->drawPos, o->heading * math::PI / SPRING_MAX_HEADING };
uni.speed = o->speed;
uni.maxHealth = o->maxHealth;
Expand Down
Loading