diff --git a/Engine/source/CMakeLists.txt b/Engine/source/CMakeLists.txt index d439a06e2..2ca86a2f7 100644 --- a/Engine/source/CMakeLists.txt +++ b/Engine/source/CMakeLists.txt @@ -501,12 +501,23 @@ string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCH) set(IS_X86 FALSE) set(IS_ARM FALSE) -if(ARCH MATCHES "x86_64|amd64|i[3-6]86") - set(IS_X86 TRUE) -endif() - -if(ARCH MATCHES "arm64|aarch64") - set(IS_ARM TRUE) +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + # Use the CMAKE_OSX_ARCHITECTURES list for universal builds + foreach(arch IN LISTS CMAKE_OSX_ARCHITECTURES) + if(arch STREQUAL "x86_64") + set(IS_X86 TRUE) + elseif(arch STREQUAL "arm64") + set(IS_ARM TRUE) + endif() + endforeach() +else() + # Non-macOS detection + if(ARCH MATCHES "arm64|aarch64") + set(IS_ARM TRUE) + endif() + if(ARCH MATCHES "x86_64|amd64|i[3-6]86") + set(IS_X86 TRUE) + endif() endif() # always available diff --git a/Engine/source/T3D/decal/decalManager.cpp b/Engine/source/T3D/decal/decalManager.cpp index 1dc6ff236..7a21cd5e0 100644 --- a/Engine/source/T3D/decal/decalManager.cpp +++ b/Engine/source/T3D/decal/decalManager.cpp @@ -660,12 +660,14 @@ DecalInstance* DecalManager::raycast( const Point3F &start, const Point3F &end, RayInfo ri; bool containsPoint = false; if ( gServerContainer.castRayRendered( start, end, STATIC_COLLISION_TYPEMASK, &ri ) ) - { + { + RectF rect = inst->mDataBlock->texRect[inst->mTextureRectIdx]; + rect.extent *= inst->mSize * 0.5f; Point2F poly[4]; - poly[0].set( inst->mPosition.x - (inst->mSize / 2), inst->mPosition.y + (inst->mSize / 2)); - poly[1].set( inst->mPosition.x - (inst->mSize / 2), inst->mPosition.y - (inst->mSize / 2)); - poly[2].set( inst->mPosition.x + (inst->mSize / 2), inst->mPosition.y - (inst->mSize / 2)); - poly[3].set( inst->mPosition.x + (inst->mSize / 2), inst->mPosition.y + (inst->mSize / 2)); + poly[0].set(inst->mPosition.x - rect.extent.x, inst->mPosition.y + rect.extent.y); + poly[1].set( inst->mPosition.x - rect.extent.x, inst->mPosition.y - rect.extent.y); + poly[2].set( inst->mPosition.x + rect.extent.x, inst->mPosition.y - rect.extent.y); + poly[3].set( inst->mPosition.x + rect.extent.x, inst->mPosition.y + rect.extent.y); if ( MathUtils::pointInPolygon( poly, 4, Point2F(ri.point.x, ri.point.y) ) ) containsPoint = true; diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 96893a7ba..7c7830ddc 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -264,7 +264,7 @@ IMPLEMENT_CALLBACK( PlayerData, onLeaveLiquid, void, ( Player* obj, const char* "@param obj The Player object\n" "@param type The type of liquid the player has left\n" ); -IMPLEMENT_CALLBACK( PlayerData, animationDone, void, ( Player* obj, const char * animName), ( obj, animName), +IMPLEMENT_CALLBACK( PlayerData, animationDone, void, ( Player* obj,const char * animName), ( obj, animName), "@brief Called on the server when a scripted animation completes.\n\n" "@param obj The Player object\n" "@see Player::setActionThread() for setting a scripted animation and its 'hold' parameter to " @@ -4805,7 +4805,7 @@ Point3F Player::_move( const F32 travelTime, Collision *outCol ) static Polyhedron sBoxPolyhedron; static ExtrudedPolyList sExtrudedPolyList; static ExtrudedPolyList sPhysZonePolyList; - + Vector norms; for (; count < sMoveRetryCount; count++) { F32 speed = mVelocity.len(); if (!speed && !mDeath.haveVelocity()) @@ -4931,7 +4931,7 @@ Point3F Player::_move( const F32 travelTime, Collision *outCol ) mFalling = false; // Back off... - if ( velLen > 0.f ) { + if ( velLen > POINT_EPSILON) { F32 newT = getMin(0.01f / velLen, dt); start -= mVelocity * newT; totalMotion -= velLen * newT; @@ -4983,30 +4983,82 @@ Point3F Player::_move( const F32 travelTime, Collision *outCol ) // Subtract out velocity VectorF dv = collision->normal * (bd + sNormalElasticity); mVelocity += dv; + + bool blocked = false; if (count == 0) { firstNormal = collision->normal; } else { - if (count == 1) + bool uniqueNorm = true; + for (U32 norm = 0; norm < norms.size(); norm++) { - // Re-orient velocity along the crease. - if (mDot(dv,firstNormal) < 0.0f && - mDot(collision->normal,firstNormal) < 0.0f) + if (mFabs(mDot(collision->normal, norms[norm])) > (1.0f - POINT_EPSILON)) { - VectorF nv; - mCross(collision->normal,firstNormal,&nv); - F32 nvl = nv.len(); - if (nvl) - { - if (mDot(nv,mVelocity) < 0.0f) - nvl = -nvl; - nv *= mVelocity.len() / nvl; - mVelocity = nv; - } + uniqueNorm = false; + break; } } + if (uniqueNorm) + { + VectorF n = collision->normal; + n.normalizeSafe(); + norms.push_back(n); + } + // Use the number of unique normals to determine how to project velocity + if (norms.size() == 1) + { + VectorF n = norms[0]; + mVelocity -= mDot(mVelocity, n) * n; + if (mVelocity.lenSquared() < POINT_EPSILON) + blocked = true; + } + else if (norms.size() == 2) + { + VectorF nv; + mCross(norms[0], norms[1], &nv); + F32 nvl = nv.len(); + if (nvl > POINT_EPSILON) + { + nv /= nvl; + F32 vel = mClampF(mDot(mVelocity, nv), -speed, speed); + mVelocity = nv * vel; + if (mVelocity.lenSquared() < POINT_EPSILON) + blocked = true; + } + else blocked = true; + } + else // 3 or more unique normals: project off all using a Gram-Schmidt variant + { + Vector orthoNorms; + for (U32 i = 0; i < norms.size(); ++i) + { + VectorF n = norms[i]; + for (U32 j = 0; j < orthoNorms.size(); ++j) + n -= mDot(n, orthoNorms[j]) * orthoNorms[j]; + if (n.lenSquared() > POINT_EPSILON) + { + n.normalize(); + orthoNorms.push_back(n); + } + } + for (U32 i = 0; i < orthoNorms.size(); ++i) + mVelocity -= mDot(mVelocity, orthoNorms[i]) * orthoNorms[i]; + if (mVelocity.lenSquared() < POINT_EPSILON) + blocked = true; + } + } + if (blocked) + { + mVelocity.zero(); + return start; + } + F32 newSpeed = mVelocity.len(); + if (newSpeed > speed) + { + mVelocity.normalize(); + mVelocity *= speed; } } else @@ -5017,7 +5069,7 @@ Point3F Player::_move( const F32 travelTime, Collision *outCol ) } } - if (count == sMoveRetryCount) + if (count == sMoveRetryCount || mVelocity.lenSquared() < POINT_EPSILON) { // Failed to move start = initialPosition; diff --git a/Engine/source/T3D/projectile.cpp b/Engine/source/T3D/projectile.cpp index 4476d70dd..a6f4c5ef6 100644 --- a/Engine/source/T3D/projectile.cpp +++ b/Engine/source/T3D/projectile.cpp @@ -873,8 +873,11 @@ bool Projectile::onAdd() } } if (mSourceObject.isValid()) + { processAfter(mSourceObject); - + if (isClientObject()) + mSourceObject->getRenderMuzzlePoint(mSourceObjectSlot, &mCurrPosition); + } // Setup our bounding box if (bool(mDataBlock->getProjectileShape()) == true) mObjBox = mDataBlock->getProjectileShape()->mBounds; diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index 96fadaf6e..44fe70382 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -1164,13 +1164,6 @@ void ShapeBase::onRemove() { mConvexList->nukeList(); - Parent::onRemove(); - - // Stop any running sounds on the client - if (isGhost()) - for (S32 i = 0; i < MaxSoundThreads; i++) - stopAudio(i); - // Accumulation and environment mapping if (isClientObject() && mShapeInstance) { @@ -1178,6 +1171,13 @@ void ShapeBase::onRemove() AccumulationVolume::removeObject(this); } + Parent::onRemove(); + + // Stop any running sounds on the client + if (isGhost()) + for (S32 i = 0; i < MaxSoundThreads; i++) + stopAudio(i); + if ( isClientObject() ) { if (mCubeReflector) diff --git a/Engine/source/gui/buttons/guiBitmapButtonCtrl.h b/Engine/source/gui/buttons/guiBitmapButtonCtrl.h index ec96e9344..5a5f56ee0 100644 --- a/Engine/source/gui/buttons/guiBitmapButtonCtrl.h +++ b/Engine/source/gui/buttons/guiBitmapButtonCtrl.h @@ -123,7 +123,7 @@ private: String mBitmapFile; public: void _setBitmap(StringTableEntry _in) { - if (_in == NULL || _in == StringTable->EmptyString() || _in == "") + if (_in == NULL || _in == StringTable->EmptyString() || _in[0] == '\0') { mBitmapAsset = NULL; mBitmapFile = ""; diff --git a/Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp b/Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp index abb778ca0..26d6f742a 100644 --- a/Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp +++ b/Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp @@ -516,11 +516,12 @@ void GuiDecalEditorCtrl::renderScene(const RectI & updateRect) if ( gDecalManager->clipDecal( mSELDecal, &mSELEdgeVerts ) ) _renderDecalEdge( mSELEdgeVerts, ColorI( 255, 255, 255, 255 ) ); - const F32 &decalSize = mSELDecal->mSize; + const F32 &decalSize = mSELDecal->mSize * 0.5; Point3F boxSize( decalSize, decalSize, decalSize ); - MatrixF worldMat( true ); - mSELDecal->getWorldMatrix( &worldMat, true ); + mSELDecal->getWorldMatrix( &worldMat, true ); + RectF rect = mSELDecal->mDataBlock->texRect[mSELDecal->mTextureRectIdx]; + worldMat.scale(Point3F(rect.extent.x, rect.extent.y, 0.25f)); drawUtil->drawObjectBox( desc, boxSize, mSELDecal->mPosition, worldMat, ColorI( 255, 255, 255, 255 ) ); } @@ -531,11 +532,13 @@ void GuiDecalEditorCtrl::renderScene(const RectI & updateRect) if ( gDecalManager->clipDecal( mHLDecal, &mHLEdgeVerts ) ) _renderDecalEdge( mHLEdgeVerts, ColorI( 255, 255, 255, 255 ) ); - const F32 &decalSize = mHLDecal->mSize; + const F32 &decalSize = mHLDecal->mSize * 0.5; Point3F boxSize( decalSize, decalSize, decalSize ); MatrixF worldMat( true ); mHLDecal->getWorldMatrix( &worldMat, true ); + RectF rect = mHLDecal->mDataBlock->texRect[mHLDecal->mTextureRectIdx]; + worldMat.scale(Point3F(rect.extent.x, rect.extent.y, 0.25f)); drawUtil->drawObjectBox( desc, boxSize, mHLDecal->mPosition, worldMat, ColorI( 255, 255, 255, 255 ) ); } diff --git a/Engine/source/math/impl/mat44_impl.inl b/Engine/source/math/impl/mat44_impl.inl index da6971d0d..abe0e4cbb 100644 --- a/Engine/source/math/impl/mat44_impl.inl +++ b/Engine/source/math/impl/mat44_impl.inl @@ -15,8 +15,13 @@ namespace math_backend::mat44 inline float mat44_get_determinant(const float* m) { - f32x4x4 ma = m_load(m); - return v_extract0(m_determinant_affine(ma)); + f32x4 r0 = v_load3_vec(m + 0); // row0 xyz + f32x4 r1 = v_load3_vec(m + 4); // row1 xyz + f32x4 r2 = v_load3_vec(m + 8); // row2 xyz + + f32x4 c0 = v_cross(r1, r2); // cofactor for row0 + f32x4 det = v_dot3(r0, c0); // splatted determinant + return v_extract0(det); } // Matrix Scale: Float3 (assume w = 1.0f) @@ -32,51 +37,66 @@ namespace math_backend::mat44 m_store(m, ma); } - inline void mat44_transform_plane_impl(const float* m, const float* scale, const float* plane, float* plane_result) + inline void mat44_transform_plane_impl(const float* m, const float* s, const float* p, float* presult) { + f32x4 scale = v_load3_pos(s); + f32x4 invScale = v_div(v_set1(1.0f), scale); + + //-------------------------------------------------- + // Load affine 3x3 rows and translation + //-------------------------------------------------- + f32x4 row0 = v_load3_vec(m + 0); + f32x4 row1 = v_load3_vec(m + 4); + f32x4 row2 = v_load3_vec(m + 8); + f32x4 shear = v_set(m[3], m[7], m[11], 1.0); + + //-------------------------------------------------- + // Compute A, B, C = -dot(row, shear) + //-------------------------------------------------- + f32x4 A = v_mul(v_dot3(row0, shear), v_set1(-1.0f)); + f32x4 B = v_mul(v_dot3(row1, shear), v_set1(-1.0f)); + f32x4 C = v_mul(v_dot3(row2, shear), v_set1(-1.0f)); + + + f32x4x4 invTrMatrix; + invTrMatrix.r0 = v_set(m[0], m[1], m[2], v_extract0(A)); + invTrMatrix.r1 = v_set(m[4], m[5], m[6], v_extract0(B)); + invTrMatrix.r2 = v_set(m[8], m[9], m[10], v_extract0(C)); + invTrMatrix.r3 = v_set(0.0f, 0.0f, 0.0f, 1.0f); + + // Apply inverse scale to upper-left 3x3 + invTrMatrix.r0 = v_mul(invTrMatrix.r0, invScale); + invTrMatrix.r1 = v_mul(invTrMatrix.r1, invScale); + invTrMatrix.r2 = v_mul(invTrMatrix.r2, invScale); + + + f32x4 normal = v_load3_pos(p); // plane normal {x,y,z,1} + f32x4 point = v_mul(normal, v_set1(-p[3])); // point = -d * normal + + // Apply transform to normal + f32x4 normTransformed = m_mul_vec3(invTrMatrix, normal); + normTransformed = v_normalize3(normTransformed); + + // transform point with original + f32x4 scaleVec = v_load3_pos(s); // scale vector + f32x4 pointScaled = v_mul(point, scaleVec); + + pointScaled = v_insert_w(pointScaled, v_set1(1.0f)); + f32x4x4 M = m_load(m); + // Transform point + f32x4 pointTransformed = m_mul_vec4(M, pointScaled); - f32x4 plane_v = v_load(plane); - f32x4 scale_v = v_load3_vec(scale); - f32x4 invScale = v_rcp_nr(scale_v); + //-------------------------------------------------- + // Compute plane d = -dot(normal, transformedPoint) + //-------------------------------------------------- + f32x4 dp = v_dot3( pointTransformed, normTransformed); + float planeD = -v_extract0(dp); - // normal = plane.xyz - f32x4 normal = plane_v; - - // apply Inv(s) - normal = v_mul(normal, invScale); - - // multiply by Inv(Tr(m)) (only the rotation part matters) - f32x4 nx = v_mul(v_swizzle_singular_mask(normal, 0), M.r0); - f32x4 ny = v_mul(v_swizzle_singular_mask(normal, 1), M.r1); - f32x4 nz = v_mul(v_swizzle_singular_mask(normal, 2), M.r2); - - normal = v_add(v_add(nx, ny), nz); - - normal = v_normalize3(normal); - - // compute point on plane - float d = v_extract0(v_swizzle_singular_mask(plane_v, 3)); - - f32x4 point = v_mul(plane_v, v_set1(-d)); - point = v_preserve_w(point, v_set1(1.0f)); - - // apply scale - point = v_mul(point, scale_v); - - // transform point by matrix - point = m_mul_vec4(M, point); - - // compute new plane distance - float newD = -v_extract0(v_dot3(point, normal)); - - alignas(16) float n[4]; - v_store(n, normal); - - plane_result[0] = n[0]; - plane_result[1] = n[1]; - plane_result[2] = n[2]; - plane_result[3] = newD; + presult[0] = v_extract0(normTransformed); + presult[1] = v_extract0(v_swizzle_singular_mask(normTransformed, 1)); + presult[2] = v_extract0(v_swizzle_singular_mask(normTransformed, 2)); + presult[3] = planeD; } inline void mat44_get_scale_impl(const float* m, float* s) @@ -109,92 +129,138 @@ namespace math_backend::mat44 m_store(m, ma); } + // Vector Multiply: m * v (assume w = 0.0f) + inline void mat44_mul_vec3_impl(const float* m, const float* v, float* r) + { + f32x4x4 ma = m_load(m); + f32x4 va = v_load3_vec(v); + f32x4 vr = m_mul_vec3(ma, va); + v_store3(r, vr); + } + + // Matrix Inverse inline void mat44_inverse_impl(float* m) { - f32x4x4 ma = m_load(m); + //// using Cramers Rule find the Inverse + //// Minv = (1/det(M)) * adjoint(M) + f32x4 r0 = v_load3_vec(m + 0); // row 0: m00 m01 m02 + f32x4 r1 = v_load3_vec(m + 4); // row 1: m10 m11 m12 + f32x4 r2 = v_load3_vec(m + 8); // row 2: m20 m21 m22 + float det = mat44_get_determinant(m); + f32x4 invDet = v_set1(1.0f / det); - // Compute cofactors using cross products - f32x4x4 mTemp; - mTemp.r0 = v_cross(ma.r1, ma.r2); - mTemp.r1 = v_cross(ma.r2, ma.r0); - mTemp.r2 = v_cross(ma.r0, ma.r1); + f32x4x4 temp; - // Determinant = dot(ma.r0, c0) - f32x4 det = v_dot3(ma.r0, mTemp.r0); - f32x4 invDet = v_rcp_nr(det); + temp.r0 = v_set( + (m[5] * m[10] - m[6] * m[9]), + (m[9] * m[2] - m[10] * m[1]), + (m[1] * m[6] - m[2] * m[5]), + 0 + ); - // Scale cofactors - mTemp.r0 = v_mul(mTemp.r0, invDet); - mTemp.r1 = v_mul(mTemp.r1, invDet); - mTemp.r2 = v_mul(mTemp.r2, invDet); + temp.r1 = v_set( + (m[6] * m[8] - m[4] * m[10]), + (m[10] * m[0] - m[8] * m[2]), + (m[2] * m[4] - m[0] * m[6]), + 0 + ); - // Store inverse 3x3 (transpose of cofactor matrix) + temp.r2 = v_set( + (m[4] * m[9] - m[5] * m[8]), + (m[8] * m[1] - m[9] * m[0]), + (m[0] * m[5] - m[1] * m[4]), + 0 + ); - mTemp = m_transpose(mTemp); - mTemp.r3 = ma.r3; + temp.r0 = v_mul(temp.r0, invDet); + temp.r1 = v_mul(temp.r1, invDet); + temp.r2 = v_mul(temp.r2, invDet); - // ---- Translation ---- + // Compute new translation: -R^-1 * T + f32x4 t = v_set(m[3], m[7], m[11], 0.0f); // row-major: last element in row + f32x4 t_new; - // Load original translation - f32x4 T = v_set(m[3], m[7], m[11], 0.0f); - - // Compute -(Tx*ma.r0 + Ty*ma.r1 + Tz*ma.r2) - f32x4 result = v_mul(ma.r0, v_swizzle_singular_mask(T, 0)); - result = v_add(result, v_mul(ma.r1, v_swizzle_singular_mask(T, 1))); - result = v_add(result, v_mul(ma.r2, v_swizzle_singular_mask(T, 2))); - result = v_mul(result, v_set1(-1.0f)); + t_new = v_set( + -v_extract0(v_dot3(temp.r0, t)), + -v_extract0(v_dot3(temp.r1, t)), + -v_extract0(v_dot3(temp.r2, t)), + 0.0f + ); - m_store(m, mTemp); + // Store back rotation + m[0] = v_extract0(temp.r0); m[1] = v_extract0(v_swizzle_singular_mask(temp.r0, 1)); m[2] = v_extract0(v_swizzle_singular_mask(temp.r0, 2)); + m[4] = v_extract0(temp.r1); m[5] = v_extract0(v_swizzle_singular_mask(temp.r1, 1)); m[6] = v_extract0(v_swizzle_singular_mask(temp.r1, 2)); + m[8] = v_extract0(temp.r2); m[9] = v_extract0(v_swizzle_singular_mask(temp.r2, 1)); m[10] = v_extract0(v_swizzle_singular_mask(temp.r2, 2)); - // Store translation - m[3] = v_extract0(result); - m[7] = v_extract0(v_swizzle_singular_mask(result, 1)); - m[11] = v_extract0(v_swizzle_singular_mask(result, 2)); + // Store translation + m[3] = v_extract0(t_new); + m[7] = v_extract0(v_swizzle_singular_mask(t_new, 1)); + m[11] = v_extract0(v_swizzle_singular_mask(t_new, 2)); } // Matrix Inverse - inline void mat44_inverse_to_impl(const float* m, float* dst) + inline void mat44_inverse_to_impl(const float* m, float* d) { - f32x4x4 ma = m_load(m); + //// using Cramers Rule find the Inverse + //// Minv = (1/det(M)) * adjoint(M) + f32x4 r0 = v_load3_vec(m + 0); // row 0: m00 m01 m02 + f32x4 r1 = v_load3_vec(m + 4); // row 1: m10 m11 m12 + f32x4 r2 = v_load3_vec(m + 8); // row 2: m20 m21 m22 + float det = mat44_get_determinant(m); + f32x4 invDet = v_set1(1.0f / det); - // Compute cofactors using cross products - f32x4x4 mTemp; - mTemp.r0 = v_cross(ma.r1, ma.r2); - mTemp.r1 = v_cross(ma.r2, ma.r0); - mTemp.r2 = v_cross(ma.r0, ma.r1); + f32x4x4 temp; - // Determinant = dot(ma.r0, c0) - f32x4 det = v_dot3(ma.r0, mTemp.r0); - f32x4 invDet = v_rcp_nr(det); + temp.r0 = v_set( + (m[5] * m[10] - m[6] * m[9]), + (m[9] * m[2] - m[10] * m[1]), + (m[1] * m[6] - m[2] * m[5]), + 0 + ); - // Scale cofactors - mTemp.r0 = v_mul(mTemp.r0, invDet); - mTemp.r1 = v_mul(mTemp.r1, invDet); - mTemp.r2 = v_mul(mTemp.r2, invDet); + temp.r1 = v_set( + (m[6] * m[8] - m[4] * m[10]), + (m[10] * m[0] - m[8] * m[2]), + (m[2] * m[4] - m[0] * m[6]), + 0 + ); - // Store inverse 3x3 (transpose of cofactor matrix) + temp.r2 = v_set( + (m[4] * m[9] - m[5] * m[8]), + (m[8] * m[1] - m[9] * m[0]), + (m[0] * m[5] - m[1] * m[4]), + 0 + ); - mTemp = m_transpose(mTemp); - mTemp.r3 = ma.r3; + temp.r0 = v_mul(temp.r0, invDet); + temp.r1 = v_mul(temp.r1, invDet); + temp.r2 = v_mul(temp.r2, invDet); - // ---- Translation ---- + // Compute new translation: -R^-1 * T + f32x4 t = v_set(m[3], m[7], m[11], 0.0f); // row-major: last element in row + f32x4 t_new; - // Load original translation - f32x4 T = v_set(m[3], m[7], m[11], 0.0f); + t_new = v_set( + -v_extract0(v_dot3(temp.r0, t)), + -v_extract0(v_dot3(temp.r1, t)), + -v_extract0(v_dot3(temp.r2, t)), + 0.0f + ); - // Compute -(Tx*ma.r0 + Ty*ma.r1 + Tz*ma.r2) - f32x4 result = v_mul(ma.r0, v_swizzle_singular_mask(T, 0)); - result = v_add(result, v_mul(ma.r1, v_swizzle_singular_mask(T, 1))); - result = v_add(result, v_mul(ma.r2, v_swizzle_singular_mask(T, 2))); - result = v_mul(result, v_set1(-1.0f)); + // Store back rotation + d[0] = v_extract0(temp.r0); d[1] = v_extract0(v_swizzle_singular_mask(temp.r0, 1)); d[2] = v_extract0(v_swizzle_singular_mask(temp.r0, 2)); + d[4] = v_extract0(temp.r1); d[5] = v_extract0(v_swizzle_singular_mask(temp.r1, 1)); d[6] = v_extract0(v_swizzle_singular_mask(temp.r1, 2)); + d[8] = v_extract0(temp.r2); d[9] = v_extract0(v_swizzle_singular_mask(temp.r2, 1)); d[10] = v_extract0(v_swizzle_singular_mask(temp.r2, 2)); - m_store(dst, mTemp); - - // Store translation - dst[3] = v_extract0(result); - dst[7] = v_extract0(v_swizzle_singular_mask(result, 1)); - dst[11] = v_extract0(v_swizzle_singular_mask(result, 2)); + // Store translation + d[3] = v_extract0(t_new); + d[7] = v_extract0(v_swizzle_singular_mask(t_new, 1)); + d[11] = v_extract0(v_swizzle_singular_mask(t_new, 2)); + d[12] = m[12]; + d[13] = m[13]; + d[14] = m[14]; + d[15] = m[15]; } // Matrix Affine Inverse @@ -275,15 +341,6 @@ namespace math_backend::mat44 v_store3(r, vr); } - // Vector Multiply: m * v (assume w = 0.0f) - inline void mat44_mul_vec3_impl(const float* m, const float* v, float* r) - { - f32x4x4 ma = m_load(m); - f32x4 va = v_load3_vec(v); - f32x4 vr = m_mul_vec3(ma, va); - v_store3(r, vr); - } - // Vector Multiply: m * p (full [4x4] * [1x4]) inline void mat44_mul_float4_impl(const float* m, const float* p, float* r) { diff --git a/Engine/source/ts/tsShapeInstance.cpp b/Engine/source/ts/tsShapeInstance.cpp index 2a7cb9c35..337e432fc 100644 --- a/Engine/source/ts/tsShapeInstance.cpp +++ b/Engine/source/ts/tsShapeInstance.cpp @@ -239,8 +239,11 @@ void TSShapeInstance::initMeshObjects() void TSShapeInstance::setMaterialList( TSMaterialList *matList ) { // get rid of old list - if ( mOwnMaterialList ) + if (mOwnMaterialList) + { delete mMaterialList; + mMaterialList = NULL; + } mMaterialList = matList; mOwnMaterialList = false; @@ -891,6 +894,9 @@ void TSShapeInstance::prepCollision() // Returns true is the shape contains any materials with accumulation enabled. bool TSShapeInstance::hasAccumulation() { + if (!mOwnMaterialList || mMaterialList == NULL) + return false; + bool result = false; for ( U32 i = 0; i < mMaterialList->size(); ++i ) { diff --git a/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript b/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript index c9a5bec3c..602243639 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/SSAO/SSAOPostFx.tscript @@ -173,7 +173,7 @@ function PostEffectEditorInspector::toggleSSAOPostFx(%this) function SSAOPostFx::applyFromPreset(%this) { - if($PostFXManager::PostFX::Enable && $pref::PostFX::EnableSSAO) + if($PostFX::SSAOPostFx::Enabled && $pref::PostFX::EnableSSAO) %this.enable(); else %this.disable(); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript index 2b832d0ba..2df7b32da 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript @@ -127,6 +127,28 @@ function ImageAsset::generatePreviewImage(%this, %previewButton, %forceRegenerat return false; } +function ImageAsset::makeMaterialFrom(%this) +{ + %matName = %this.assetName @ "_Mat"; + %assetLoc = AssetDatabase.getAssetPath(%this.getAssetId()) @"/"@ %this.assetName @"_Mat.asset.taml"; + %newMat = new Material(%matName) { + diffuseMapAsset[0] = %this.getAssetId(); + mapTo = %this.assetName; + }; + + %matAsset = new MaterialAsset() { + assetName = %matName; + materialDefinitionName = %matName; + }; + + %matAsset.add(%newMat); + + TamlWrite(%matAsset, expandPath(%assetLoc)); + AssetDatabase.addDeclaredAsset(AssetDatabase.getAssetModule(%this.getAssetId()), %assetLoc); + return %matAsset; +} + + function ImageAsset::onShowActionMenu(%this) { GenericAsset::onShowActionMenu(%this); @@ -134,6 +156,8 @@ function ImageAsset::onShowActionMenu(%this) %assetId = %this.getAssetId(); EditAssetPopup.setItemPosition("Create Composite Texture" TAB "" TAB "CompositeTextureEditor.buildComposite(\"" @ %assetId @ "\");", 4); + EditAssetPopup.setItemPosition("Create Terrain Textures" TAB "" TAB "makeTerrainMapsFrom(\"" @ %assetId @ "\");", 5); + EditAssetPopup.setItemPosition("Create Material" TAB "" TAB %this @ ".makeMaterialFrom();", 6); EditAssetPopup.objectData = %assetId; EditAssetPopup.objectType = AssetDatabase.getAssetType(%assetId); diff --git a/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript b/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript index e234ffa70..43dc020f0 100644 --- a/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript @@ -173,15 +173,15 @@ function PE_ParticleEditor::updateParticle(%this, %propertyField, %value, %isSli function PE_ParticleEditor::setDirty( %this ) { - this.text = "*Particle"; - this.dirty = true; + %this.text = "*Particle"; + %this.dirty = true; if(!startsWith(%this-->PopupMenu.text, "*")) { %this-->PopupMenu.text = "*" @ %this-->PopupMenu.text; } - %particle = this.currParticle; + %particle = %this.currParticle; %filename = %particle.getFilename(); %editorFilename = "tools/particleEditor/scripts/particleParticleEditor.ed." @ $TorqueScriptFileExtension; @@ -211,17 +211,17 @@ function PE_ParticleEditor::setNotDirty( %this ) function PE_ParticleEditor::showNewDialog( %this, %replaceSlot ) { // Open a dialog if the current Particle is dirty - if( this.dirty ) + if( %this.dirty ) { toolsMessageBoxYesNoCancel("Save Particle Changes?", "Do you wish to save the changes made to the
current particle before changing the particle?", - "PE_ParticleEditor.saveParticle( " @ this.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );", - "PE_ParticleEditor.saveParticleDialogDontSave( " @ this.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );" + "PE_ParticleEditor.saveParticle( " @ %this.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );", + "PE_ParticleEditor.saveParticleDialogDontSave( " @ %this.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );" ); } else { - this.createParticle( %replaceSlot ); + %this.createParticle( %replaceSlot ); } } @@ -263,7 +263,7 @@ function PE_ParticleEditor::pickedNewParticleTargetModule( %this, %module ) ParticleEditorCreatePrompt.show("Particle", "ParticleData", "PE_ParticleEditor.doCreateNewParticle(\"" @ %module @ "\");" ); } -function PE_ParticleEditor::doCreateNewEmitter(%this, %module) +function PE_ParticleEditor::doCreateNewParticle(%this, %module) { //Sanity checks %newName = ParticleEditorCreatePrompt-->nameText.getText(); diff --git a/Tools/CMake/modules/openal.cmake b/Tools/CMake/modules/openal.cmake index 7bf8e4453..8e6ebe2c2 100644 --- a/Tools/CMake/modules/openal.cmake +++ b/Tools/CMake/modules/openal.cmake @@ -24,4 +24,7 @@ if(TORQUE_SFX_OPENAL) set(ALSOFT_UPDATE_BUILD_VERSION OFF CACHE BOOL "Update build Version" UPDATE) add_subdirectory("${TORQUE_LIB_ROOT_DIRECTORY}/openal-soft" ${TORQUE_LIB_TARG_DIRECTORY}/openal-soft EXCLUDE_FROM_ALL) + if(APPLE) + target_compile_options(OpenAL PRIVATE -Wno-error=undef) + endif() endif(TORQUE_SFX_OPENAL) diff --git a/Tools/CMake/torqueMacOSconfigs.cmake b/Tools/CMake/torqueMacOSconfigs.cmake index 793771c13..1d3ba7fbc 100644 --- a/Tools/CMake/torqueMacOSconfigs.cmake +++ b/Tools/CMake/torqueMacOSconfigs.cmake @@ -9,22 +9,22 @@ set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") # minimum for multi arch build is 11. set(CMAKE_OSX_DEPLOYMENT_TARGET "11" CACHE STRING "" FORCE) -set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "" FORCE) +set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Architectures to build" FORCE) set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET[arch=arm64] "11.0" CACHE STRING "arm 64 minimum deployment target" FORCE) -if(CMAKE_OSX_ARCHITECTURES MATCHES "((^|;|, )(arm64|arm64e|x86_64))+") - set(CMAKE_C_SIZEOF_DATA_PTR 8) - set(CMAKE_CXX_SIZEOF_DATA_PTR 8) - if(CMAKE_OSX_ARCHITECTURES MATCHES "((^|;|, )(arm64|arm64e))+") - set(CMAKE_SYSTEM_PROCESSOR "aarch64") - else() - set(CMAKE_SYSTEM_PROCESSOR "x86_64") - endif() -else() - set(CMAKE_C_SIZEOF_DATA_PTR 4) - set(CMAKE_CXX_SIZEOF_DATA_PTR 4) - set(CMAKE_SYSTEM_PROCESSOR "arm") -endif() +# if(CMAKE_OSX_ARCHITECTURES MATCHES "((^|;|, )(arm64|arm64e|x86_64))+") +# set(CMAKE_C_SIZEOF_DATA_PTR 8) +# set(CMAKE_CXX_SIZEOF_DATA_PTR 8) +# if(CMAKE_OSX_ARCHITECTURES MATCHES "((^|;|, )(arm64|arm64e))+") +# set(CMAKE_SYSTEM_PROCESSOR "aarch64") +# else() +# set(CMAKE_SYSTEM_PROCESSOR "x86_64") +# endif() +# else() +# set(CMAKE_C_SIZEOF_DATA_PTR 4) +# set(CMAKE_CXX_SIZEOF_DATA_PTR 4) +# set(CMAKE_SYSTEM_PROCESSOR "arm") +# endif() # Enable codesigning with secure timestamp when not in Debug configuration (required for Notarization) set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=Release] "--timestamp") diff --git a/Tools/CMake/torque_macros.cmake b/Tools/CMake/torque_macros.cmake index fe0cec4c6..ca1a65325 100644 --- a/Tools/CMake/torque_macros.cmake +++ b/Tools/CMake/torque_macros.cmake @@ -176,7 +176,27 @@ function(add_math_backend name compile_defs) elseif(name STREQUAL "avx2") target_compile_options(math_${name} PRIVATE -mavx2 -mfma) elseif(name STREQUAL "neon") - target_compile_options(math_${name} PRIVATE -march=armv8-a) + if(APPLE) + set_target_properties(math_${name} PROPERTIES OSX_ARCHITECTURES "arm64") + else() + target_compile_options(math_${name} PRIVATE -march=armv8-a) + endif() + endif() + endif() + + if(APPLE) + # ARM-only backend + if(name STREQUAL "neon") + set_target_properties(math_${name} PROPERTIES + OSX_ARCHITECTURES "arm64" + ) + endif() + + # x86-only backends + if(name MATCHES "sse2|sse41|avx|avx2") + set_target_properties(math_${name} PROPERTIES + OSX_ARCHITECTURES "x86_64" + ) endif() endif()