Merge branch 'TorqueGameEngines:development' into Skurpz/UI-Module-Fixes

This commit is contained in:
Sir-Skurpsalot 2025-12-18 00:05:17 -07:00 committed by GitHub
commit d8db0859d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 257 additions and 174 deletions

View file

@ -20,7 +20,7 @@ jobs:
build-linux:
if: github.repository == 'TorqueGameEngines/Torque3D'
name: ${{matrix.config.name}}
runs-on: macos-13
runs-on: macos-latest
strategy:
fail-fast: false
matrix:

View file

@ -149,7 +149,7 @@ SoundAsset::SoundAsset()
mSubtitleString = StringTable->EmptyString();
mLoadedState = AssetErrCode::NotLoaded;
mPreload = false;
mPreload = true;
// SFX description inits
// reverb is useless here, reverb is inacted on listener.
mProfileDesc.mPitch = 1;
@ -164,10 +164,17 @@ SoundAsset::SoundAsset()
mProfileDesc.mConeOutsideAngle = 360;
mProfileDesc.mConeOutsideVolume = 1;
mProfileDesc.mRolloffFactor = -1.0f;
mProfileDesc.mFadeInTime = 0.0f;
mProfileDesc.mFadeOutTime = 0.0f;
mProfileDesc.mFadeLoops = false;
mProfileDesc.mScatterDistance = Point3F(0.f, 0.f, 0.f);
mProfileDesc.mStreamPacketSize = 8;
mProfileDesc.mStreamReadAhead = 3;
mProfileDesc.mPriority = 1.0f;
mProfileDesc.mSourceGroup = NULL;
mProfileDesc.mFadeInEase = EaseF();
mProfileDesc.mReverb = SFXSoundReverbProperties();
dMemset(mProfileDesc.mParameters, 0, sizeof(mProfileDesc.mParameters));
mIsPlaylist = false;
mPlaylist.mNumSlotsToPlay = SFXPlayList::SFXPlaylistSettings::NUM_SLOTS;
@ -182,6 +189,15 @@ SoundAsset::SoundAsset()
SoundAsset::~SoundAsset()
{
for (U32 i = 0; i < SFXPlayList::NUM_SLOTS; i++)
{
if(mSFXProfile[i].isProperlyAdded() && !mSFXProfile[i].isDeleted())
mSFXProfile[i].unregisterObject();
}
if (mPlaylist.isProperlyAdded() && !mPlaylist.isDeleted())
mPlaylist.unregisterObject();
}
//-----------------------------------------------------------------------------
@ -353,6 +369,7 @@ void SoundAsset::onAssetRefresh(void)
mSoundPath[i] = getOwned() ? expandAssetFilePath(mSoundFile[i]) : mSoundPath[i];
}
}
U32 SoundAsset::load()
@ -372,6 +389,8 @@ U32 SoundAsset::load()
numSlots++;
}
if (mProfileDesc.mSourceGroup == NULL)
mProfileDesc.mSourceGroup = dynamic_cast<SFXSource*>(Sim::findObject("AudioChannelMaster"));
if (numSlots > 1)
{
@ -391,16 +410,14 @@ U32 SoundAsset::load()
return mLoadedState;
}
else
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
if (mProfileDesc.mSourceGroup == NULL)
mProfileDesc.mSourceGroup = dynamic_cast<SFXSource*>(Sim::findObject("AudioChannelMaster"));
{
SFXProfile* trackProfile = new SFXProfile();
trackProfile->setDescription(&mProfileDesc);
trackProfile->setSoundFileName(mSoundPath[i]);
trackProfile->setPreload(mPreload);
trackProfile->getBuffer();
mSFXProfile[i] = *trackProfile;
mSFXProfile[i].registerObject(String::ToString("%s_profile_track%d", getAssetName()).c_str());
mPlaylist.mSlots.mTrack[i] = trackProfile;
@ -409,6 +426,7 @@ U32 SoundAsset::load()
}
mPlaylist.setDescription(&mProfileDesc);
mPlaylist.registerObject(String::ToString("%s_playlist", getAssetName()).c_str());
}
else
{
@ -424,15 +442,12 @@ U32 SoundAsset::load()
return mLoadedState;
}
else
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
if (mProfileDesc.mSourceGroup == NULL)
mProfileDesc.mSourceGroup = dynamic_cast<SFXSource*>(Sim::findObject("AudioChannelMaster"));
{
mSFXProfile[0].setDescription(&mProfileDesc);
mSFXProfile[0].setSoundFileName(mSoundPath[0]);
mSFXProfile[0].setPreload(mPreload);
//give it a nudge to preload if required
mSFXProfile[0].getBuffer();
mSFXProfile[0].registerObject(String::ToString("%s_profile", getAssetName()).c_str());
}
}

View file

@ -140,7 +140,7 @@ DefineEngineMethod(className, set##name, void, (const char* assetName), , assetT
#define PACKDATA_ASSET(name)\
if (stream->writeFlag(m##name##Asset.notNull()))\
{\
stream->writeString(m##name##Asset.getAssetId());\
AssetDatabase.packDataAsset(stream, m##name##Asset.getAssetId());\
}\
else if(stream->writeFlag(m##name##Name != StringTable->EmptyString()))\
{\
@ -151,7 +151,7 @@ DefineEngineMethod(className, set##name, void, (const char* assetName), , assetT
#define UNPACKDATA_ASSET(name)\
if (stream->readFlag())\
{\
m##name##AssetId = stream->readSTString();\
m##name##AssetId = AssetDatabase.unpackDataAsset(stream);\
_set##name(m##name##AssetId);\
}\
else if (stream->readFlag())\
@ -168,8 +168,7 @@ DefineEngineMethod(className, set##name, void, (const char* assetName), , assetT
#define PACK_ASSET(netconn, name)\
if (stream->writeFlag(m##name##Asset.notNull()))\
{\
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
netconn->packNetStringHandleU(stream, assetIdStr);\
AssetDatabase.packDataAsset(stream, m##name##Asset.getAssetId());\
}\
else if (stream->writeFlag(m##name##Name != StringTable->EmptyString()))\
{\
@ -181,7 +180,7 @@ DefineEngineMethod(className, set##name, void, (const char* assetName), , assetT
#define UNPACK_ASSET(netconn, name)\
if (stream->readFlag())\
{\
m##name##AssetId = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
m##name##AssetId = AssetDatabase.unpackDataAsset(stream);\
_set##name(m##name##AssetId);\
}\
else if (stream->readFlag())\

View file

@ -311,8 +311,7 @@ SimSoundAssetEvent::SimSoundAssetEvent(StringTableEntry assetId, const MatrixF*
void SimSoundAssetEvent::pack(NetConnection* con, BitStream* stream)
{
NetStringHandle assetIdStr = mAsset->getAssetId();
con->packNetStringHandleU(stream, assetIdStr);
AssetDatabase.packUpdateAsset(con, 0, stream, mAsset.getAssetId());
SFXDescription* ad = mAsset->getSfxDescription();
if (stream->writeFlag(sentTransform))
@ -348,14 +347,7 @@ void SimSoundAssetEvent::write(NetConnection* con, BitStream* stream)
void SimSoundAssetEvent::unpack(NetConnection* con, BitStream* stream)
{
StringTableEntry temp = StringTable->insert(con->unpackNetStringHandleU(stream).getString());
if (AssetDatabase.isDeclaredAsset(temp))
{
AssetPtr<SoundAsset> tempSoundAsset;
tempSoundAsset = temp;
mAsset = temp;
}
mAsset = AssetDatabase.unpackUpdateAsset(con, stream);
sentTransform = stream->readFlag();
if (sentTransform) {

View file

@ -658,9 +658,9 @@ void Item::updateWorkingCollisionSet(const U32 mask, const F32 dt)
{
// It is assumed that we will never accelerate more than 10 m/s for gravity...
//
Point3F scaledVelocity = mVelocity * dt;
Point3F scaledVelocity = mVelocity * dt * TickSec;
F32 len = scaledVelocity.len();
F32 newLen = len + (10 * dt);
F32 newLen = len + (mDataBlock->getShape()->mRadius * dt * TickSec);
// Check to see if it is actually necessary to construct the new working list,
// or if we can use the cached version from the last query. We use the x

View file

@ -244,6 +244,7 @@ void LightAnimData::AnimValue<COUNT>::write( BitStream *stream ) const
stream->write( value2[i] );
stream->write( period[i] );
stream->writeString( keys[i] );
stream->writeFlag(smooth[i]);
}
}
@ -256,6 +257,7 @@ void LightAnimData::AnimValue<COUNT>::read( BitStream *stream )
stream->read( &value2[i] );
stream->read( &period[i] );
keys[i] = stream->readSTString();
smooth[i] = stream->readFlag();
}
}

View file

@ -6097,7 +6097,7 @@ void Player::updateWorkingCollisionSet()
// box by the possible movement in that tick.
Point3F scaledVelocity = mVelocity * TickSec;
F32 len = scaledVelocity.len();
F32 newLen = len + (10.0f * TickSec);
F32 newLen = len + (mDataBlock->getShape()->mRadius * TickSec);
// Check to see if it is actually necessary to construct the new working list,
// or if we can use the cached version from the last query. We use the x

View file

@ -47,8 +47,8 @@ Rigid::Rigid()
friction = 0.5f;
atRest = false;
sleepLinearThreshold = 0.0004f;
sleepAngThreshold = 0.0004f;
sleepLinearThreshold = POINT_EPSILON;
sleepAngThreshold = POINT_EPSILON;
sleepTimeThreshold = 0.75f;
sleepTimer = 0.0f;
}
@ -71,7 +71,7 @@ void Rigid::integrate(F32 delta)
linVelocity = linMomentum * oneOverMass;
// 2. advance orientation if ang vel significant
F32 angle = angVelocity.len();
F32 angle = angVelocity.len()*delta;
if (mFabs(angle)> POINT_EPSILON)
{
QuatF dq;
@ -101,7 +101,7 @@ void Rigid::integrate(F32 delta)
}
// 5. refresh ang velocity
updateAngularVelocity();
updateAngularVelocity(delta);
// 6. CoM update
@ -138,7 +138,7 @@ void Rigid::updateCenterOfMass()
void Rigid::applyImpulse(const Point3F &r, const Point3F &impulse)
{
if (impulse.lenSquared() < mass) return;
if ((impulse.lenSquared() - mass) < POINT_EPSILON) return;
wake();
// Linear momentum and velocity
@ -304,7 +304,8 @@ void Rigid::trySleep(F32 dt)
// If there is active force/torque, dont sleep
if (!force.isZero() || !torque.isZero())
{
sleepTimer = 0.0f; return;
sleepTimer = 0.0f;
return;
}
const F32 linV2 = linVelocity.lenSquared();

View file

@ -105,7 +105,7 @@ public:
//
void setSleepThresholds(F32 linVel2, F32 angVel2, F32 timeToSleep);
void wake();
TORQUE_FORCEINLINE void updateAngularVelocity() { invWorldInertia.mulV(angMomentum, &angVelocity); }
TORQUE_FORCEINLINE void updateAngularVelocity(F32 delta) { Point3F deltaVel = angVelocity * delta; invWorldInertia.mulV(angMomentum, &deltaVel); }
};

View file

@ -1138,7 +1138,7 @@ void RigidShape::updatePos(F32 dt)
// Update collision information based on our current pos.
bool collided = false;
if (!mDisableMove)
if (!mRigid.atRest && !mDisableMove)
{
collided = updateCollision(dt);
@ -1151,7 +1151,7 @@ void RigidShape::updatePos(F32 dt)
{
F32 k = mRigid.getKineticEnergy();
F32 G = mNetGravity* dt * TickMs / mDataBlock->integration;
F32 Kg = mRigid.mass * G * G;
F32 Kg = mRigid.mass * G * G * TickSec;
if (k < sRestTol * Kg && ++restCount > sRestCount)
mRigid.setAtRest();
}
@ -1447,7 +1447,7 @@ void RigidShape::updateWorkingCollisionSet(const U32 mask)
// working list is updated on a Tick basis, which means we only expand our box by
// the possible movement in that tick, plus some extra for caching purposes
Box3F convexBox = mConvex.getBoundingBox(getTransform(), getScale());
F32 len = (mRigid.linVelocity.len() + 50) * TickSec;
F32 len = (mRigid.linVelocity.len() + mDataBlock->getShape()->mRadius) * TickSec;
F32 l = (len * 1.1) + 0.1; // fudge factor
convexBox.minExtents -= Point3F(l, l, l);
convexBox.maxExtents += Point3F(l, l, l);

View file

@ -827,7 +827,7 @@ void Vehicle::updatePos(F32 dt)
{
F32 k = mRigid.getKineticEnergy();
F32 G = mNetGravity* dt * TickMs / mDataBlock->integration;
F32 Kg = 0.5 * mRigid.mass * G * G;
F32 Kg = mRigid.mass * G * G * TickSec;
if (k < sRestTol * Kg && ++restCount > sRestCount)
mRigid.setAtRest();
}

View file

@ -326,6 +326,17 @@ bool AssetManager::addDeclaredAsset( ModuleDefinition* pModuleDefinition, const
//-----------------------------------------------------------------------------
static U32 HashAssetId(const char* str)
{
U32 hash = 2166136261u;
while (*str)
{
hash ^= (U8)*str++;
hash *= 16777619u;
}
return hash;
}
StringTableEntry AssetManager::addPrivateAsset( AssetBase* pAssetBase )
{
// Debug Profiling.
@ -377,6 +388,22 @@ StringTableEntry AssetManager::addPrivateAsset( AssetBase* pAssetBase )
// Set ownership by asset manager.
pAssetDefinition->mpAssetBase->setOwned( this, pAssetDefinition );
U32 netId = HashAssetId(pAssetDefinition->mAssetName);
// Collision detection
typeNetIdToAssetMap::iterator netIterator = mNetIdToAsset.find(netId);
if (netIterator != mNetIdToAsset.end())
{
Con::warnf(
"AssetManager: Hash collision for '%s' and '%s'",
pAssetDefinition->mAssetName,
mNetIdToAsset.find(netId)->value
);
}
mNetIdToAsset.insert(netId, pAssetDefinition->mAssetId);
mAssetToNetId.insert(pAssetDefinition->mAssetId, netId);
// Store in declared assets.
mDeclaredAssets.insert( pAssetDefinition->mAssetId, pAssetDefinition );
@ -475,6 +502,14 @@ bool AssetManager::removeDeclaredAsset( const char* pAssetId )
// Remove from declared assets.
mDeclaredAssets.erase( declaredAssetItr );
typeAssetToNetIdMap::iterator netId = mAssetToNetId.find(pAssetId);
typeNetIdToAssetMap::iterator netChar = mNetIdToAsset.find(netId->value);
if (netId != mAssetToNetId.end() && netChar != mNetIdToAsset.end())
{
mNetIdToAsset.erase(netChar);
mAssetToNetId.erase(netId);
}
// Info.
if ( mEchoInfo )
{
@ -2691,17 +2726,6 @@ const char* AssetManager::getAssetLooseFile(const char* pAssetId, const S32& ind
//-----------------------------------------------------------------------------
static U32 HashAssetId(const char* str)
{
U32 hash = 2166136261u;
while (*str)
{
hash ^= (U8)*str++;
hash *= 16777619u;
}
return hash;
}
bool AssetManager::scanDeclaredAssets( const char* pPath, const char* pExtension, const bool recurse, ModuleDefinition* pModuleDefinition )
{
// Debug Profiling.
@ -2829,13 +2853,11 @@ bool AssetManager::scanDeclaredAssets( const char* pPath, const char* pExtension
typeNetIdToAssetMap::iterator netIterator = mNetIdToAsset.find(netId);
if (netIterator != mNetIdToAsset.end())
{
Con::errorf(
Con::warnf(
"AssetManager: Hash collision for '%s' and '%s'",
assetIdBuffer,
mNetIdToAsset.find(netId)->value
);
AssertFatal(false, "Asset hash collision detected.");
}
mNetIdToAsset.insert(netId, foundAssetDefinition.mAssetId);

View file

@ -402,6 +402,8 @@ namespace TorqueScript
#ifdef TORQUE_DEBUG
Con::printf("Executing %s.", scriptFileName);
#endif
if (Con::gTraceOn)
Con::printf("Executing %s.", scriptFileName);
CodeBlock *newCodeBlock = new CodeBlock();
StringTableEntry name = StringTable->insert(scriptFileName);

View file

@ -3055,7 +3055,7 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
Var *ibl = (Var *)LangElement::find("ibl");
if (!ibl)
{
ibl = new Var("ibl", "float3");
ibl = new Var("ibl", "float4");
}
Var* eyePos = (Var*)LangElement::find("eyePosWorld");
@ -3086,7 +3086,7 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
//Reflection vec
String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
computeForwardProbes += String("@,@,@,@,@,@,\r\n\t\t");
computeForwardProbes += String("@,@).rgb; \r\n");
computeForwardProbes += String("@,@); \r\n");
meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos,
skylightCubemapIdx, SkylightDamp, BRDFTexture, WetnessTexture, accumTime, dampness,
@ -3100,7 +3100,7 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
ambient->constSortPos = cspPass;
}
meta->addStatement(new GenOp(" @.rgb *= @.rgb;\r\n", ibl, ambient));
meta->addStatement(new GenOp(" @.rgb = @.rgb;\r\n", curColor, ibl));
meta->addStatement(new GenOp(" @ = @;\r\n", curColor, ibl));
output = meta;
}

View file

@ -3143,7 +3143,7 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
Var* ibl = (Var*)LangElement::find("ibl");
if (!ibl)
{
ibl = new Var("ibl", "float3");
ibl = new Var("ibl", "float4");
}
Var* eyePos = (Var*)LangElement::find("eyePosWorld");
@ -3174,7 +3174,7 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
computeForwardProbes += String("@,@,TORQUE_SAMPLER2D_MAKEARG(@),TORQUE_SAMPLER2D_MAKEARG(@), @, @,\r\n\t\t");
computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)).rgb; \r\n");
computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)); \r\n");
meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos,
skylightCubemapIdx, SkylightDamp, BRDFTexture, WetnessTexture, accumTime, dampness,
@ -3188,7 +3188,7 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
ambient->constSortPos = cspPass;
}
meta->addStatement(new GenOp(" @.rgb *= @.rgb;\r\n", ibl, ambient));
meta->addStatement(new GenOp(" @.rgb = @.rgb;\r\n", curColor, ibl));
meta->addStatement(new GenOp(" @ = @;\r\n", curColor, ibl));
output = meta;
}

View file

@ -84,7 +84,11 @@ MatrixF AssimpAppNode::getTransform(F32 time)
// no parent (ie. root level) => scale by global shape <unit>
mLastTransform.identity();
mLastTransform.scale(ColladaUtils::getOptions().unit * ColladaUtils::getOptions().formatScaleFactor);
ColladaUtils::convertTransform(mLastTransform);
if (!isBounds())
{
MatrixF axisFix = ColladaUtils::getOptions().axisCorrectionMat;
mLastTransform.mulL(axisFix);
}
}
// If this node is animated in the active sequence, fetch the animated transform

View file

@ -48,52 +48,33 @@ AssimpAppSequence::~AssimpAppSequence()
void AssimpAppSequence::determineTimeMultiplier(aiAnimation* a)
{
// Set fps from the file or use default
fps = (a->mTicksPerSecond > 0) ? a->mTicksPerSecond : 30.0f;
if (fps >= 1000.0f) { // Indicates milliseconds (GLTF or similar formats)
mTimeMultiplier = 1.0f / 1000.0f; // Convert milliseconds to seconds
Con::printf("[Assimp] Detected milliseconds timing (FPS >= 1000). Time Multiplier: %f", mTimeMultiplier);
}
else if (fps > 0.0f) { // Standard FPS
fps = mClamp(fps, 5 /*TSShapeLoader::MinFrameRate*/, TSShapeLoader::MaxFrameRate);
mTimeMultiplier = 1.0f / fps;
Con::printf("[Assimp] Standard FPS detected. Time Multiplier: %f", mTimeMultiplier);
}
else {
// Fall back to 30 FPS as default
mTimeMultiplier = 1.0f / 30.0f;
Con::printf("[Assimp] FPS not specified. Using default 30 FPS. Time Multiplier: %f", mTimeMultiplier);
}
// Assimp convention: if mTicksPerSecond == 0, assume 25 Hz
const float ticksPerSecond =
(a->mTicksPerSecond > 0.0)
? (float)a->mTicksPerSecond
: 25.0f;
mTimeMultiplier = 1.0f / ticksPerSecond;
Con::printf(
"[Assimp] TicksPerSecond: %f, Time Multiplier: %f",
ticksPerSecond,
mTimeMultiplier
);
}
void AssimpAppSequence::calculateSequenceEnd(aiAnimation* a)
{
for (U32 i = 0; i < a->mNumChannels; ++i) {
aiNodeAnim* nodeAnim = a->mChannels[i];
F32 maxKeyTime = 0.0f;
// mDuration is in ticks
seqEnd = (F32)a->mDuration * mTimeMultiplier;
// Calculate the maximum time across all keyframes for this channel
for (U32 k = 0; k < nodeAnim->mNumPositionKeys; ++k) {
maxKeyTime = getMax(maxKeyTime, (F32)nodeAnim->mPositionKeys[k].mTime);
}
for (U32 k = 0; k < nodeAnim->mNumRotationKeys; ++k) {
maxKeyTime = getMax(maxKeyTime, (F32)nodeAnim->mRotationKeys[k].mTime);
}
for (U32 k = 0; k < nodeAnim->mNumScalingKeys; ++k) {
maxKeyTime = getMax(maxKeyTime, (F32)nodeAnim->mScalingKeys[k].mTime);
}
// Use the multiplier to convert to real sequence time
seqEnd = mTimeMultiplier * getMax(seqEnd, maxKeyTime);
}
Con::printf("[Assimp] Sequence End Time: %f seconds", seqEnd);
Con::printf(
"[Assimp] Sequence End Time: %f seconds (Duration ticks: %f)",
seqEnd,
(F32)a->mDuration
);
}
void AssimpAppSequence::setActive(bool active)
{
if (active)

View file

@ -380,7 +380,66 @@ void AssimpShapeLoader::getRootAxisTransform()
meta->Get("CoordAxis", coordAxis);
meta->Get("CoordAxisSign", coordSign);
ColladaUtils::getOptions().upAxis = (domUpAxisType)upAxis;
switch (upAxis)
{
case 0: ColladaUtils::getOptions().upAxis = UPAXISTYPE_X_UP; break;
case 1: ColladaUtils::getOptions().upAxis = UPAXISTYPE_Y_UP; break;
case 2: ColladaUtils::getOptions().upAxis = UPAXISTYPE_Z_UP; break;
default: ColladaUtils::getOptions().upAxis = UPAXISTYPE_Y_UP; break;
}
MatrixF rot(true);
// ===== Y-UP SOURCE =====
if (upAxis == 1)
{
if (frontAxis == 2)
{
// Y-up, Z-forward → Z-up, Y-forward
// Rotate 180° Y, then 90° X
rot(0, 0) = -1.0f;
rot(1, 1) = 0.0f; rot(2, 1) = 1.0f;
rot(1, 2) = 1.0f; rot(2, 2) = 0.0f;
}
else if (frontAxis == 0)
{
// Y-up, X-forward → Z-up, Y-forward
// Rotate -90° around Z then 90° around X
rot(0, 0) = 0.0f; rot(0, 1) = -1.0f;
rot(1, 0) = 1.0f; rot(1, 1) = 0.0f;
rot(2, 2) = 1.0f;
}
}
// ===== Z-UP SOURCE =====
if (upAxis == 2)
{
if (frontAxis == 1)
{
// Already Z-up, Y-forward → no change
}
else if (frontAxis == 0)
{
// Z-up, X-forward → rotate -90° around Z
rot(0, 0) = 0.0f; rot(0, 1) = -1.0f;
rot(1, 0) = 1.0f; rot(1, 1) = 0.0f;
}
}
// ===== X-UP SOURCE =====
if (upAxis == 0)
{
if (frontAxis == 2)
{
// X-up, Z-forward → Z-up, Y-forward
// Rotate -90° around Y then -90° around Z
rot(0, 0) = 0.0f; rot(0, 1) = 0.0f; rot(0, 2) = -1.0f;
rot(1, 0) = 1.0f; rot(1, 1) = 0.0f; rot(1, 2) = 0.0f;
rot(2, 0) = 0.0f; rot(2, 1) = -1.0f; rot(2, 2) = 0.0f;
}
}
ColladaUtils::getOptions().axisCorrectionMat = rot;
}
void AssimpShapeLoader::processAnimations()

View file

@ -120,6 +120,7 @@ namespace ColladaUtils
eAnimTimingType animTiming; // How to import timing data as frames, seconds or milliseconds
S32 animFPS; // FPS value to use if timing is set in frames and the animations does not have an fps set
F32 formatScaleFactor; // Scale factor applied to convert the shape format default unit to meters
MatrixF axisCorrectionMat;
ImportOptions()
{

View file

@ -46,7 +46,7 @@ $PostFX::HDRPostFX::colorFilter = "1.0 1.0 1.0";
/// The minimum luninace value to allow when tone mapping
/// the scene. Is particularly useful if your scene very
/// dark or has a black ambient color in places.
$PostFX::HDRPostFX::minLuminace = 0.001;
$PostFX::HDRPostFX::minLuminace = 0.5;
/// The rate of adaptation from the previous and new
/// average scene luminance.
@ -241,7 +241,7 @@ singleton GFXStateBlockData( HDRStateBlock )
function HDRPostFX::setShaderConsts( %this )
{
%this.setShaderConst( "$g_fMiddleGray", $PostFX::HDRPostFX::keyValue );
%this.setShaderConst( "$g_fMiddleGray", $PostFX::HDRPostFX::keyValue );
%minLuminace = $PostFX::HDRPostFX::minLuminace;
if ( %minLuminace <= 0.0 )
@ -357,17 +357,25 @@ function HDRPostFX::onEnabled( %this )
// disable this postFx.
GammaPostFX.disable();
if (%format $= %this.previousFormat)
return true;
// Set the right global shader define for HDR.
if ( %format $= "GFXFormatR10G10B10A2" )
{
addGlobalShaderMacro( "TORQUE_HDR_RGB10" );
removeGlobalShaderMacro( "TORQUE_HDR_RGB16" );
}
else if ( %format $= "GFXFormatR16G16B16A16F" )
{
addGlobalShaderMacro( "TORQUE_HDR_RGB16" );
removeGlobalShaderMacro( "TORQUE_HDR_RGB10" );
}
echo( "HDR FORMAT: " @ %format );
// Change the format of the offscreen surface
// to an HDR compatible format.
%this.previousFormat = AL_FormatToken.format;
%this.previousFormat = %format;
setReflectFormat( %format );
// Reset the light manager which will ensure the new
@ -390,10 +398,7 @@ function HDRPostFX::onDisabled( %this )
// Restore the non-HDR offscreen surface format.
%format = %this.previousFormat;
AL_FormatToken.format = %format;
setReflectFormat( %format );
removeGlobalShaderMacro( "TORQUE_HDR_RGB10" );
removeGlobalShaderMacro( "TORQUE_HDR_RGB16" );
setReflectFormat( %format );
// Reset the light manager which will ensure the new
// hdr encoding takes effect in all the shaders.
@ -565,9 +570,9 @@ function HDRPostFX::SetupBloomFX( %this )
singleton PostEffect( HDRPostFX )
{
enabled = false;
enabled = true;
allowReflectPass = false;
previousFormat = AL_FormatToken.format;
// Resolve the HDR before we render any editor stuff
// and before we resolve the scene to the backbuffer.
renderTime = "PFXBeforeBin";

View file

@ -6,10 +6,10 @@ $PostFX::HDRPostFX::saturationValue = 1;
$PostFX::HDRPostFX::colorFilter = "1.0 1.0 1.0";
$PostFX::HDRPostFX::minLuminace = "0.5";
$PostFX::HDRPostFX::whiteCutoff = 1;
$PostFX::HDRPostFX::adaptRate = "0.134615391";
$PostFX::HDRPostFX::adaptRate = "0.85";
$PostFX::HDRPostFX::tonemapMode = "ACES";
$PostFX::HDRPostFX::enableAutoExposure = "1";
$PostFX::HDRPostFX::keyValue = 0.18;
$PostFX::HDRPostFX::keyValue = 0.5;
$PostFX::HDRPostFX::enableBloom = 1;
$PostFX::HDRPostFX::threshold = 1;
$PostFX::HDRPostFX::intensity = 1;

View file

@ -71,4 +71,5 @@ function Core_Rendering::initClient(%this)
// we can hide any splash screen we have, and show the canvas.
// This keeps things looking nice, instead of having a blank window
Canvas.showWindow();
resetLightManager(); //make sure
}

View file

@ -31,7 +31,7 @@ function initRenderManager()
// PostEffect copies the result to the backbuffer.
new RenderFormatToken(AL_FormatToken)
{
enabled = "false";
enabled = true;
//When hdr is enabled this will be changed to the appropriate format
format = "GFXFormatR16G16B16A16F";
@ -46,6 +46,9 @@ function initRenderManager()
// provided in $inTex
resolveEffect = "AL_FormatCopy";
};
addGlobalShaderMacro( "TORQUE_HDR_RGB16" );
setReflectFormat( AL_FormatToken.format );
DiffuseRenderPassManager.addManager( new RenderPassStateBin() { renderOrder = 0.001; stateToken = AL_FormatToken; } );
DiffuseRenderPassManager.addManager( new RenderProbeMgr(ProbeBin) { bintype = "Probes"; renderOrder = 0.019; processAddOrder = 0.019; } );
@ -119,7 +122,7 @@ singleton PostEffect( AL_FormatCopy )
{
// This PostEffect is used by 'AL_FormatToken' directly. It is never added to
// the PostEffectManager. Do not call enable() on it.
enabled = false;
enabled = true;
allowReflectPass = true;
shader = PFX_PassthruShader;

View file

@ -226,9 +226,11 @@ float getDistanceAtt( vec3 unormalizedLightVector , float invSqrAttRadius )
vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
{
if (surface.depth >= 0.9999f)
return float3(0.0,0.0,0.0);
// Compute Fresnel term
vec3 F = F_Schlick(surface.f0, surfaceToLight.HdotV);
F += lerp(vec3(0.04f,0.04f,0.04f), surface.baseColor.rgb, surface.metalness);
// GGX Normal Distribution Function
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughness);
@ -594,7 +596,7 @@ vec4 computeForwardProbes(Surface surface,
vec2 envBRDF = textureLod(BRDFTexture, vec2(surface.NdotV, surface.roughness),0).rg;
vec3 diffuse = irradiance * lerp(surface.baseColor.rgb, vec3(0.04f,0.04f,0.04f), surface.metalness);
vec3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*surface.metalness;
vec3 specularCol = ((specular * surface.f0) * envBRDF.x + envBRDF.y)*surface.metalness;
float horizonOcclusion = 1.3;
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
@ -608,7 +610,8 @@ vec4 computeForwardProbes(Surface surface,
return vec4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),0);
else
{
return vec4(finalColor, 0);
float reflectionOpacity = min(surface.baseColor.a+surface.baseColor.a*length(finalColor),1.0);
return vec4(finalColor, reflectionOpacity);
}
}

View file

@ -226,9 +226,11 @@ float getDistanceAtt( float3 unormalizedLightVector , float invSqrAttRadius )
float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
{
if (surface.depth >= 0.9999f)
return float3(0.0,0.0,0.0);
// Compute Fresnel term
float3 F = F_Schlick(surface.f0, surfaceToLight.HdotV);
F += lerp(0.04f, surface.baseColor.rgb, surface.metalness);
// GGX Normal Distribution Function
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughness);
@ -599,7 +601,7 @@ float4 computeForwardProbes(Surface surface,
float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg;
float3 diffuse = irradiance * lerp(surface.baseColor.rgb, 0.04f, surface.metalness);
float3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*surface.metalness;
float3 specularCol = ((specular * surface.f0) * envBRDF.x + envBRDF.y)*surface.metalness;
float horizonOcclusion = 1.3;
float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N));
@ -613,7 +615,8 @@ float4 computeForwardProbes(Surface surface,
return float4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),0);
else
{
return float4(finalColor, 0);
float reflectionOpacity = min(surface.baseColor.a+surface.baseColor.a*length(finalColor),1.0);
return float4(finalColor, reflectionOpacity);
}
}

View file

@ -7,6 +7,6 @@
DecalsFile="@assetFile=ExampleLevel.mis.decals"
ForestFile="@assetFile=ExampleLevel.forest"
NavmeshFile="@assetFile=ExampleLevel.nav"
gameModesNames="ExampleGameMode"
staticObjectAssetDependency0="@asset=Prototyping:FloorGray"
gameModesNames="ExampleGameMode;"
VersionId="1"/>

View file

@ -1,82 +1,72 @@
//--- OBJECT WRITE BEGIN ---
new Scene(ExampleLevel) {
Enabled = "1";
gameModes="ExampleGameMode";
isEditing = "1";
gameModes = "ExampleGameMode";
enabled = "1";
new LevelInfo(theLevelInfo) {
fogColor = "0.6 0.6 0.7 1";
FogColor = "0.6 0.6 0.7 1";
fogDensityOffset = "700";
canvasClearColor = "0 0 0 255";
ambientLightBlendCurve = "2.69146e+20 0";
soundAmbience = "AudioAmbienceDefault";
advancedLightmapSupport = "0";
Enabled = "1";
advancedLightmapSupport = "0";
enabled = "1";
};
new SkyBox(theSky) {
MaterialAsset = "Core_Rendering:BlankSkyMat";
drawBottom = "0";
dirtyGameObject = "0";
dirtyGameObject = "0";
};
new Sun(theSun) {
azimuth = "230.396";
elevation = "45";
color = "0.968628 0.901961 0.901961 1";
ambient = "0.337255 0.533333 0.619608 1";
brightness = "2";
texSize = "2048";
overDarkFactor = "3000 1500 750 250";
shadowDistance = "200";
shadowSoftness = "0.25";
logWeight = "0.9";
fadeStartDistance = "0";
bias = "0.1";
Blur = "1";
dirtyGameObject = "0";
dynamicRefreshFreq = "8";
Enabled = "1";
height = "1024";
lightBleedFactor = "0.8";
minVariance = "0";
pointShadowType = "PointShadowType_Paraboloid";
shadowBox = "-100 -100 -100 100 100 100";
splitFadeDistances = "1 1 1 1";
staticRefreshFreq = "250";
width = "3072";
bias = "0.1";
Blur = "1";
dirtyGameObject = "0";
dynamicRefreshFreq = "8";
enabled = "1";
height = "1024";
lightBleedFactor = "0.8";
minVariance = "0";
pointShadowType = "PointShadowType_Paraboloid";
shadowBox = "-100 -100 -100 100 100 100";
splitFadeDistances = "1 1 1 1";
staticRefreshFreq = "250";
width = "3072";
};
new GroundPlane() {
scaleU = "25";
scaleV = "25";
MaterialAsset = "Prototyping:FloorGray";
dirtyGameObject = "0";
Enabled = "1";
position = "0 0 0";
rotation = "1 0 0 0";
scale = "1 1 1";
dirtyGameObject = "0";
enabled = "1";
position = "0 0 0";
rotation = "1 0 0 0";
scale = "1 1 1";
};
new Skylight() {
position = "1.37009 -5.23561 46.5817";
persistentId = "d5eb3afb-dced-11e9-a423-bb0e346e3870";
dirtyGameObject = "0";
dirtyGameObject = "0";
};
new SimGroup(CameraSpawnPoints) {
canSave = "1";
canSaveDynamicFields = "1";
enabled = "1";
new SpawnSphere(DefaultCameraSpawnSphere) {
autoSpawn = "0";
spawnTransform = "0";
radius = "1";
sphereWeight = "1";
indoorWeight = "1";
outdoorWeight = "1";
isAIControlled = "0";
dataBlock = "SpawnSphereMarker";
position = "0 0 10";
rotation = "1 0 0 0";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
enabled = "1";
homingCount = "0";
lockCount = "0";

View file

@ -4,12 +4,12 @@ $PostFX::HDRPostFX::whitePoint = 1;
$PostFX::HDRPostFX::logContrast = 1;
$PostFX::HDRPostFX::saturationValue = 1;
$PostFX::HDRPostFX::colorFilter = "1.0 1.0 1.0";
$PostFX::HDRPostFX::minLuminace = 0.001;
$PostFX::HDRPostFX::minLuminace = 0.5;
$PostFX::HDRPostFX::whiteCutoff = 1;
$PostFX::HDRPostFX::adaptRate = 2;
$PostFX::HDRPostFX::adaptRate = "0.85";
$PostFX::HDRPostFX::tonemapMode = "ACES";
$PostFX::HDRPostFX::enableAutoExposure = "0";
$PostFX::HDRPostFX::keyValue = 0.18;
$PostFX::HDRPostFX::keyValue = 0.5;
$PostFX::HDRPostFX::enableBloom = 1;
$PostFX::HDRPostFX::threshold = 1;
$PostFX::HDRPostFX::intensity = 1;

View file

@ -14,7 +14,7 @@ $PostFXManager::Settings::EnableLightRays = "1";
$PostFXManager::Settings::EnablePostFX = "1";
$PostFXManager::Settings::EnableSSAO = "1";
$PostFXManager::Settings::EnableVignette = "1";
$PostFXManager::Settings::HDR::adaptRate = "2";
$PostFXManager::Settings::HDR::adaptRate = "0.85";
$PostFXManager::Settings::HDR::blueShiftColor = "1.05 0.97 1.27";
$PostFXManager::Settings::HDR::brightPassThreshold = "1";
$PostFXManager::Settings::HDR::enableBloom = "1";
@ -23,7 +23,7 @@ $PostFXManager::Settings::HDR::enableToneMapping = "0.5";
$PostFXManager::Settings::HDR::gaussMean = "0";
$PostFXManager::Settings::HDR::gaussMultiplier = "0.3";
$PostFXManager::Settings::HDR::gaussStdDev = "0.8";
$PostFXManager::Settings::HDR::keyValue = "0.117347";
$PostFXManager::Settings::HDR::keyValue = "0.5";
$PostFXManager::Settings::HDR::minLuminace = "0.0459184";
$PostFXManager::Settings::HDR::whiteCutoff = "1";
$PostFXManager::Settings::LightRays::brightScalar = "0.75";

View file

@ -14,7 +14,7 @@ $PostFXManager::Settings::EnableLightRays = "1";
$PostFXManager::Settings::EnablePostFX = "1";
$PostFXManager::Settings::EnableSSAO = "1";
$PostFXManager::Settings::EnableVignette = "1";
$PostFXManager::Settings::HDR::adaptRate = "2";
$PostFXManager::Settings::HDR::adaptRate = "0.85";
$PostFXManager::Settings::HDR::blueShiftColor = "1.05 0.97 1.27";
$PostFXManager::Settings::HDR::brightPassThreshold = "1";
$PostFXManager::Settings::HDR::enableBloom = "1";
@ -23,7 +23,7 @@ $PostFXManager::Settings::HDR::enableToneMapping = "0.5";
$PostFXManager::Settings::HDR::gaussMean = "0";
$PostFXManager::Settings::HDR::gaussMultiplier = "0.3";
$PostFXManager::Settings::HDR::gaussStdDev = "0.8";
$PostFXManager::Settings::HDR::keyValue = "0.117347";
$PostFXManager::Settings::HDR::keyValue = "0.5";
$PostFXManager::Settings::HDR::minLuminace = "0.0459184";
$PostFXManager::Settings::HDR::whiteCutoff = "1";
$PostFXManager::Settings::LightRays::brightScalar = "0.75";

View file

@ -255,7 +255,7 @@ $guiContent = new GuiContainer(EditorGui,EditorGuiGroup) {
HorizSizing = "width";
VertSizing = "bottom";
Position = "0 0";
Extent = "800 40";
Extent = "800 36";
MinExtent = "8 8";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
@ -1470,7 +1470,7 @@ $guiContent = new GuiContainer(EditorGui,EditorGuiGroup) {
internalName = "AggregateControl";
horizSizing = "right";
vertSizing = "bottom";
position = "0 60";
position = "0 0";
extent = "1024 768";
minExtent = "8 8";
visible = "0";
@ -1478,8 +1478,8 @@ $guiContent = new GuiContainer(EditorGui,EditorGuiGroup) {
class = "EditorDropdownSliderContainer";
new GuiContainer(){
position = firstWord(CameraSpeedDropdownContainer.position) + firstWord(EditorGuiToolbar.position) + -6 SPC
(getWord(CameraSpeedDropdownContainer, 1)) + 31;
internalName = "container";
position = "0 0";
extent = "146 39";
isContainer = "1";
Profile = "IconDropdownProfile";

View file

@ -23,7 +23,7 @@ $guiContent = new GuiControl() {
VertSizing = "windowRelative";
Extent = "36 24";
MinExtent = "36 24";
Position = "-1 73";
Position = "0 64";
canSave = "1";
Visible = "1";
hovertime = "1000";

View file

@ -7,7 +7,7 @@ $guiContent = new GuiContainer(EWToolsToolbar) {
Profile = "ToolsMenubarProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 38";
Position = "0 30";
Extent = "0 33";
MinExtent = "8 34";
canSave = "1";

View file

@ -3359,11 +3359,11 @@ function TerrainSetHeightSliderCtrlContainer::onWake(%this)
}
//------------------------------------------------------------------------------------
function CameraSpeedDropdownContainer::onWake(%this)
function CameraSpeedDropdownCtrlContainer::onWake(%this)
{
%this-->slider.setValue(CameraSpeedDropdownCtrlContainer-->textEdit.getText());
%pos = CameraSpeedDropdownCtrlContainer.getGlobalPosition();
%this-->slider.setPositionGlobal(%pos.x, %pos.y + 25);
%this-->slider.setValue(CameraSpeedDropdownContainer-->textEdit.getText());
%pos = CameraSpeedDropdownContainer.getGlobalPosition();
%this-->container.setPositionGlobal(%pos.x, %pos.y + 25);
}
//------------------------------------------------------------------------------------