bool PhysShape::castRayLocal(const Point3F &startLocal, const Point3F &endLocal, RayInfo* info) { if (m_physInfo.owner) { const VectorF& scale = m_physInfo.owner->getScale(); const MatrixF& objToWorld = m_physInfo.owner->getTransform(); Point3F start(startLocal); Point3F end (endLocal); start.convolve(scale); end.convolve(scale); objToWorld.mulP(start); objToWorld.mulP(end); bool res = castRay(start,end,info); if (res && info) { info->normal = startLocal - endLocal; info->normal.normalize(); } return res; } return false; }
void GFXDrawUtil::_drawSolidCapsule( const GFXStateBlockDesc &desc, const Point3F ¢er, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm ) { MatrixF mat; if ( xfm ) mat = *xfm; else mat = MatrixF::Identity; S32 numPoints = sizeof(circlePoints)/sizeof(Point2F); GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoints * 2 + 2, GFXBufferTypeVolatile); verts.lock(); for (S32 i=0; i<numPoints + 1; i++) { S32 imod = i % numPoints; verts[2 * i].point = Point3F( circlePoints[imod].x * radius, circlePoints[imod].y * radius, height ); verts[2 * i].color = color; verts[2 * i + 1].point = Point3F( circlePoints[imod].x * radius, circlePoints[imod].y * radius, -height ); verts[2 * i + 1].color = color; } S32 totalNumPnts = numPoints * 2 + 2; // Apply xfm if we were passed one. for ( U32 i = 0; i < totalNumPnts; i++ ) mat.mulP( verts[i].point ); // Apply position offset for ( U32 i = 0; i < totalNumPnts; i++ ) verts[i].point += center; verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 * numPoints ); Point3F sphereCenter; MatrixF sphereMat; if ( xfm ) sphereMat = *xfm; else sphereMat = MatrixF::Identity; sphereCenter.set( 0, 0, 0.5f * height ); mat.mulV( sphereCenter ); sphereCenter += center; drawSphere( desc, radius, sphereCenter, color, true, false, &sphereMat ); sphereCenter.set( 0, 0, -0.5f * height ); mat.mulV( sphereCenter ); sphereCenter += center; drawSphere( desc, radius, sphereCenter, color, false, true, &sphereMat ); }
bool AtlasGeomChunkTracer::castRay(const Point3F &start, const Point3F &end, RayInfo *info) { // Don't collide if nothing's there... if(!mChunk->mColTree) return false; // Do our tracing math in 0..1 space, but still need filespace coordinates // as that's how our geometry is currently stored. So let's store off the // values pass, then convert them to chunkspace (0..1) so we can process // them normally. // Cache the delta of the ray, to save us some per-tri vector math later on... mRayDelta = end - start; mRayStart = start; mRayEnd = end; // Figure scale and offset to get to chunkspace from filespace. mScale.set(1.0 / mChunk->mBounds.len_x(), 1.0 / mChunk->mBounds.len_y(), 1.0); mOffset = -mChunk->mBounds.minExtents; mOffset.z = 0; // Now, scale down to chunkspace, and cast the ray! Point3F adjStart = (start + mOffset); adjStart.convolve(mScale); Point3F adjEnd = (end + mOffset); adjEnd.convolve(mScale); return QuadTreeTracer::castRay(adjStart, adjEnd, info); }
void TurretShape::getRenderWeaponMountTransform( F32 delta, S32 mountPoint, const MatrixF &xfm, MatrixF *outMat ) { // Returns mount point to world space transform if ( mountPoint >= 0 && mountPoint < SceneObject::NumMountPoints) { S32 ni = mDataBlock->weaponMountNode[mountPoint]; if (ni != -1) { MatrixF mountTransform = mShapeInstance->mNodeTransforms[ni]; mountTransform.mul( xfm ); const Point3F& scale = getScale(); // The position of the mount point needs to be scaled. Point3F position = mountTransform.getPosition(); position.convolve( scale ); mountTransform.setPosition( position ); // Also we would like the object to be scaled to the model. mountTransform.scale( scale ); outMat->mul(getRenderTransform(), mountTransform); return; } } // Then let SceneObject handle it. GrandParent::getRenderMountTransform( delta, mountPoint, xfm, outMat ); }
/** Resolve collision with an immovable object Computes & applies the collision impulse needed to keep the body from penetrating the given surface. */ bool Rigid::resolveCollision(const Point3F& p, const Point3F &normal) { atRest = false; Point3F v,r; getOriginVector(p,&r); getVelocity(r,&v); F32 n = -mDot(v,normal); if (n >= 0.0f) { // Collision impulse, straight forward force stuff. F32 d = getZeroImpulse(r,normal); F32 j = n * (1.0f + restitution) * d; Point3F impulse = normal * j; // Friction impulse, calculated as a function of the // amount of force it would take to stop the motion // perpendicular to the normal. Point3F uv = v + (normal * n); F32 ul = uv.len(); if (ul) { uv /= -ul; F32 u = ul * getZeroImpulse(r,uv); j *= friction; if (u > j) u = j; impulse += uv * u; } // applyImpulse(r,impulse); } return true; }
void VPathNode::updateWorldData( void ) { if ( !mPath ) { setWorldPosition( getLocalPosition() ); setWorldRotation( getLocalRotation() ); return; } // Fetch Path Details. const MatrixF &pathTransform = mPath->getTransform(); const QuatF &pathRotation( pathTransform ); // Calculate the World Position. Point3F newPosition = getLocalPosition(); newPosition.convolve( mPath->getScale() ); pathTransform.mulP( newPosition ); // Calculate the new Rotation. QuatF newRotation; newRotation.mul( getLocalRotation(), pathRotation ); // Apply. setWorldPosition( newPosition ); setWorldRotation( newRotation ); }
bool PxSingleActor::prepRenderImage( SceneState *state, const U32 stateKey, const U32 startZone, const bool modifyBaseState ) { if ( !mShapeInstance || !state->isObjectRendered(this) ) return false; Point3F cameraOffset; getTransform().getColumn(3,&cameraOffset); cameraOffset -= state->getDiffuseCameraPosition(); F32 dist = cameraOffset.len(); if ( dist < 0.01f ) dist = 0.01f; F32 invScale = (1.0f/getMax(getMax(getScale().x,getScale().y),getScale().z)); dist *= invScale; S32 dl = mShapeInstance->setDetailFromDistance( state, dist ); if (dl<0) return false; renderObject( state ); return false; }
void Projectile::interpolateTick(F32 delta) { Parent::interpolateTick(delta); if( mHasExploded ) return; Point3F interpPos = mCurrDeltaBase + mCurrBackDelta * delta; Point3F dir = mCurrVelocity; if(dir.isZero()) dir.set(0,0,1); else dir.normalize(); MatrixF xform(true); xform = MathUtils::createOrientFromDir(dir); xform.setPosition(interpPos); setRenderTransform(xform); // fade out the projectile image S32 time = (S32)(mCurrTick - delta); if(time > mDataBlock->fadeDelay) { F32 fade = F32(time - mDataBlock->fadeDelay); mFadeValue = 1.0 - (fade / F32(mDataBlock->lifetime)); } else mFadeValue = 1.0; updateSound(); }
void CloudLayer::renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mi ) { GFXTransformSaver saver; const Point3F &camPos = state->getCameraPosition(); MatrixF xfm(true); xfm.setPosition(camPos); GFX->multWorld(xfm); if ( state->isReflectPass() ) GFX->setProjectionMatrix( state->getSceneManager()->getNonClipProjection() ); GFX->setShader( mShader ); GFX->setShaderConstBuffer( mShaderConsts ); GFX->setStateBlock( mStateblock ); // Set all the shader consts... MatrixF xform(GFX->getProjectionMatrix()); xform *= GFX->getViewMatrix(); xform *= GFX->getWorldMatrix(); mShaderConsts->setSafe( mModelViewProjSC, xform ); mShaderConsts->setSafe( mEyePosWorldSC, camPos ); LightInfo *lightinfo = LIGHTMGR->getSpecialLight(LightManager::slSunLightType); const ColorF &sunlight = state->getAmbientLightColor(); Point3F ambientColor( sunlight.red, sunlight.green, sunlight.blue ); mShaderConsts->setSafe( mAmbientColorSC, ambientColor ); const ColorF &sunColor = lightinfo->getColor(); Point3F data( sunColor.red, sunColor.green, sunColor.blue ); mShaderConsts->setSafe( mSunColorSC, data ); mShaderConsts->setSafe( mSunVecSC, lightinfo->getDirection() ); for ( U32 i = 0; i < TEX_COUNT; i++ ) mShaderConsts->setSafe( mTexOffsetSC[i], mTexOffset[i] ); Point3F scale( mTexScale[0], mTexScale[1], mTexScale[2] ); mShaderConsts->setSafe( mTexScaleSC, scale ); Point3F color; color.set( mBaseColor.red, mBaseColor.green, mBaseColor.blue ); mShaderConsts->setSafe( mBaseColorSC, color ); mShaderConsts->setSafe( mCoverageSC, mCoverage ); mShaderConsts->setSafe( mExposureSC, mExposure ); GFX->setTexture( mNormalHeightMapSC->getSamplerRegister(), mTexture ); GFX->setVertexBuffer( mVB ); GFX->setPrimitiveBuffer( mPB ); GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, smVertCount, 0, smTriangleCount ); }
//---------------------------------------------------------------------------- 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; F32 len = scaledVelocity.len(); F32 newLen = len + (10 * dt); // 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 // component of the min member of the mWorkingQueryBox, which is lame, but // it works ok. bool updateSet = false; Box3F convexBox = mConvex.getBoundingBox(getTransform(), getScale()); F32 l = (newLen * 1.1) + 0.1; // from Convex::updateWorkingList convexBox.minExtents -= Point3F(l, l, l); convexBox.maxExtents += Point3F(l, l, l); // Check containment { if (mWorkingQueryBox.minExtents.x != -1e9) { if (mWorkingQueryBox.isContained(convexBox) == false) { // Needed region is outside the cached region. Update it. updateSet = true; } else { // We can leave it alone, we're still inside the cached region } } else { // Must update updateSet = true; } } // Actually perform the query, if necessary if (updateSet == true) { mWorkingQueryBox = convexBox; mWorkingQueryBox.minExtents -= Point3F(2 * l, 2 * l, 2 * l); mWorkingQueryBox.maxExtents += Point3F(2 * l, 2 * l, 2 * l); disableCollision(); if (mCollisionObject) mCollisionObject->disableCollision(); mConvex.updateWorkingList(mWorkingQueryBox, mask); if (mCollisionObject) mCollisionObject->enableCollision(); enableCollision(); } }
void SceneObject::getRenderMountTransform( F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat ) { MatrixF mountTransform( xfm ); const Point3F &scale = getScale(); Point3F position = mountTransform.getPosition(); position.convolve( scale ); mountTransform.setPosition( position ); outMat->mul( mRenderObjToWorld, mountTransform ); }
void Point3NormalizeValidator::validateType(SimObject *object, void *typePtr) { Point3F *v = (Point3F *) typePtr; const F32 len = v->len(); if(!mIsEqual(len, 1.0f)) { consoleError(object, "Vector length must be %g", length); *v *= length / len; } }
void GFXCubemap::initNormalize( U32 size ) { Point3F axis[6] = {Point3F(1.0, 0.0, 0.0), Point3F(-1.0, 0.0, 0.0), Point3F(0.0, 1.0, 0.0), Point3F( 0.0, -1.0, 0.0), Point3F(0.0, 0.0, 1.0), Point3F( 0.0, 0.0, -1.0),}; Point3F s[6] = {Point3F(0.0, 0.0, -1.0), Point3F( 0.0, 0.0, 1.0), Point3F(1.0, 0.0, 0.0), Point3F( 1.0, 0.0, 0.0), Point3F(1.0, 0.0, 0.0), Point3F(-1.0, 0.0, 0.0),}; Point3F t[6] = {Point3F(0.0, -1.0, 0.0), Point3F(0.0, -1.0, 0.0), Point3F(0.0, 0.0, 1.0), Point3F(0.0, 0.0, -1.0), Point3F(0.0, -1.0, 0.0), Point3F(0.0, -1.0, 0.0),}; F32 span = 2.0; F32 start = -1.0; F32 stride = span / F32(size - 1); GFXTexHandle faces[6]; for(U32 i=0; i<6; i++) { GFXTexHandle &tex = faces[i]; GBitmap *bitmap = new GBitmap(size, size); // fill in... for(U32 v=0; v<size; v++) { for(U32 u=0; u<size; u++) { Point3F vector; vector = axis[i] + ((F32(u) * stride) + start) * s[i] + ((F32(v) * stride) + start) * t[i]; vector.normalizeSafe(); vector = ((vector * 0.5) + Point3F(0.5, 0.5, 0.5)) * 255.0; vector.x = mClampF(vector.x, 0.0f, 255.0f); vector.y = mClampF(vector.y, 0.0f, 255.0f); vector.z = mClampF(vector.z, 0.0f, 255.0f); // easy way to avoid knowledge of the format (RGB, RGBA, RGBX, ...)... U8 *bits = bitmap->getAddress(u, v); bits[0] = U8(vector.x); bits[1] = U8(vector.y); bits[2] = U8(vector.z); } } tex.set(bitmap, &GFXDefaultStaticDiffuseProfile, true, "Cubemap"); } initStatic(faces); }
float Player::coverage (Point3F eye) { float total = 0; Point3F foot = getLinearPosition () + collisionImage.sphere.center / 2; Point3F head = foot + collisionImage.sphere.center; Point3F temp; Point3F lshoulder; Point3F rshoulder; temp = getRot (); RMat3F rot (EulerF(temp.x, temp.y, temp.z)); temp.set (collisionImage.bbox.fMin.x / 2, 0, 0); m_mul (temp, rot, &lshoulder); lshoulder += getLinearPosition (); lshoulder.z += collisionImage.sphere.center.z; lshoulder.z += collisionImage.sphere.center.z / 4; temp.set (collisionImage.bbox.fMax.x / 2, 0, 0); m_mul (temp, rot, &rshoulder); rshoulder += getLinearPosition (); rshoulder.z += collisionImage.sphere.center.z; rshoulder.z += collisionImage.sphere.center.z / 4; SimContainerQuery cq; cq.id = getId(); cq.type = -1; cq.mask = SimTerrainObjectType | SimInteriorObjectType | SimPlayerObjectType | StaticObjectType; cq.box.fMin = eye; cq.box.fMax = foot; SimCollisionInfo info; SimContainer* root = findObject(manager,SimRootContainerId,(SimContainer*)0); bool obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = head; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = lshoulder; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = rshoulder; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; return total; }
void Scene::loop() { //Basic movement glm::mat4x4 delta = glm::mat4x4(1); if (movement[4]) pitch -= keyCameraSpeed; if (movement[5]) pitch += keyCameraSpeed; if (movement[6]) yaw -= keyCameraSpeed; if (movement[7]) yaw += keyCameraSpeed; delta = glm::rotate(delta, -yaw, glm::vec3(0, 0, 1)); float speed = movementSpeed; if (mouseButtons[1]) speed *= 2.f; Point2F move = Point2F(); if (movement[0]) move.x -= speed; if (movement[1]) move.x += speed; if (movement[2]) move.y -= speed; if (movement[3]) move.y += speed; #ifdef BUILD_PHYSICS glm::vec3 torque = glm::vec3(glm::translate(delta, glm::vec3(move.x, move.y, 0))[3]); delta = glm::rotate(delta, -pitch, glm::vec3(1, 0, 0)); sphere->applyTorque(Point3F(torque.x, torque.y, torque.z) * 20); if (sphere->getColliding()) { Point3F normal = sphere->getCollisionNormal(); if (movement[8] && normal.dot(Point3F(0, 0, 1)) > 0.1) sphere->applyImpulse((normal + Point3F(0, 0, 1)) / 2.f, Point3F(0, 0, -1)); } else { sphere->applyImpulse(Point3F(torque.y, -torque.x, torque.z) / 4.f, Point3F(0, 0, 0)); } Point3F pos = sphere->getPosition(); cameraPosition = glm::vec3(pos.x, pos.y, pos.z); cameraPosition += glm::vec3(glm::translate(delta, glm::vec3(0, -2.5, 0))[3]); if (sphere->getPosition().z < difs[0]->interior[0]->boundingBox.getMin().x) { sphere->setPosition(Point3F(0, 30, 60)); } #else /* BUILD_PHYSICS */ move *= 3; if (movement[8]) move *= 2; delta = glm::rotate(delta, -pitch, glm::vec3(1, 0, 0)); delta = glm::translate(delta, glm::vec3(move.y, -move.x, 0)); cameraPosition += glm::vec3(delta[3]); #endif /* BUILD_PHYSICS */ }
MatrixF PlaneReflector::getFrustumClipProj( MatrixF &modelview ) { static MatrixF rotMat(EulerF( static_cast<F32>(M_PI / 2.f), 0.0, 0.0)); static MatrixF invRotMat(EulerF( -static_cast<F32>(M_PI / 2.f), 0.0, 0.0)); MatrixF revModelview = modelview; revModelview = rotMat * revModelview; // add rotation to modelview because it needs to be removed from projection // rotate clip plane into modelview space Point4F clipPlane; Point3F pnt = refplane * -(refplane.d + 0.0 ); Point3F norm = refplane; revModelview.mulP( pnt ); revModelview.mulV( norm ); norm.normalize(); clipPlane.set( norm.x, norm.y, norm.z, -mDot( pnt, norm ) ); // Manipulate projection matrix //------------------------------------------------------------------------ MatrixF proj = GFX->getProjectionMatrix(); proj.mul( invRotMat ); // reverse rotation imposed by Torque proj.transpose(); // switch to row-major order // Calculate the clip-space corner point opposite the clipping plane // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix Vector4F q; q.x = sgn(clipPlane.x) / proj(0,0); q.y = sgn(clipPlane.y) / proj(1,1); q.z = -1.0F; q.w = ( 1.0F - proj(2,2) ) / proj(3,2); F32 a = 1.0 / (clipPlane.x * q.x + clipPlane.y * q.y + clipPlane.z * q.z + clipPlane.w * q.w); Vector4F c = clipPlane * a; // CodeReview [ags 1/23/08] Come up with a better way to deal with this. if(GFX->getAdapterType() == OpenGL) c.z += 1.0f; // Replace the third column of the projection matrix proj.setColumn( 2, c ); proj.transpose(); // convert back to column major order proj.mul( rotMat ); // restore Torque rotation return proj; }
bool WindEmitter::findBest( const Point3F& cameraPos, const VectorF& cameraDir, F32 viewDistance, U32 maxResults, WindEmitterList* results ) { PROFILE_START(WindEmitter_findBest); // Build a sphere from the camera point. SphereF cameraSphere; cameraSphere.center = cameraPos; cameraSphere.radius = viewDistance; // Collect the active spheres within the camera space and score them. WindEmitterList best; WindEmitterList::iterator iter = smAllEmitters.begin(); for ( ; iter != smAllEmitters.end(); iter++ ) { const SphereF& sphere = *(*iter); // Skip any spheres outside of our camera range or that are disabled. if ( !(*iter)->mEnabled || !cameraSphere.isIntersecting( sphere ) ) continue; // Simple score calculation... // // score = ( radius / distance to camera ) * dot( cameraDir, vector from camera to sphere ) // Point3F vect = sphere.center - cameraSphere.center; F32 dist = vect.len(); (*iter)->mScore = dist * sphere.radius; vect /= getMax( dist, 0.001f ); (*iter)->mScore *= mDot( vect, cameraDir ); best.push_back( *iter ); } // Sort the results by score! dQsort( best.address(), best.size(), sizeof(WindEmitter*), &WindEmitter::_sortByScore ); // Clip the results to the max requested. if ( best.size() > maxResults ) best.setSize( maxResults ); // Merge the results and return. results->merge( best ); PROFILE_END(); // WindEmitter_findBest return best.size() > 0; }
void Etherform::updateWorkingCollisionSet() { // First, we need to adjust our velocity for possible acceleration. It is assumed // that we will never accelerate more than 20 m/s for gravity, plus 10 m/s for // jetting, and an equivalent 10 m/s for jumping. We also assume that the // working list is updated on a Tick basis, which means we only expand our // box by the possible movement in that tick. Point3F scaledVelocity = mVelocity * TickSec; F32 len = scaledVelocity.len(); F32 newLen = len + (10.0f * 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 // component of the min member of the mWorkingQueryBox, which is lame, but // it works ok. bool updateSet = false; Box3F convexBox = mConvex.getBoundingBox(getTransform(), getScale()); F32 l = (newLen * 1.1f) + 0.1f; // from Convex::updateWorkingList const Point3F lPoint( l, l, l ); convexBox.minExtents -= lPoint; convexBox.maxExtents += lPoint; // Check containment if (mWorkingQueryBox.minExtents.x != -1e9f) { if (mWorkingQueryBox.isContained(convexBox) == false) // Needed region is outside the cached region. Update it. updateSet = true; } else { // Must update updateSet = true; } // Actually perform the query, if necessary if (updateSet == true) { const Point3F twolPoint( 2.0f * l, 2.0f * l, 2.0f * l ); mWorkingQueryBox = convexBox; mWorkingQueryBox.minExtents -= twolPoint; mWorkingQueryBox.maxExtents += twolPoint; disableCollision(); mConvex.updateWorkingList(mWorkingQueryBox, isGhost() ? sClientCollisionContactMask : sServerCollisionContactMask); enableCollision(); } }
void PxSingleActor::_createActor() { // NXU::instantiateCollection sometimes calls methods that need // to have write access. mWorld->releaseWriteLock(); if ( mActor ) { mWorld->releaseActor( *mActor ); mActor = NULL; } NxScene *scene = mWorld->getScene(); NxMat34 nxMat; nxMat.setRowMajor44( getTransform() ); Point3F scale = getScale(); // Look for a zero scale in any component. if ( mIsZero( scale.least() ) ) return; bool createActors = false; if ( !mDataBlock->clientOnly || (mDataBlock->clientOnly && isClientObject()) ) createActors = true; mActor = createActors ? mDataBlock->createActor( scene, &nxMat, scale ) : NULL; if ( !mActor ) { mBuildScale = getScale(); mBuildAngDrag = 0; mBuildLinDrag = 0; return; } U32 group = mDataBlock->clientOnly ? PxGroup_ClientOnly : PxGroup_Default; mActor->setGroup( group ); mActor->userData = &mUserData; mActor->setContactReportFlags( NX_NOTIFY_ON_START_TOUCH_FORCE_THRESHOLD | NX_NOTIFY_FORCES ); mActor->setContactReportThreshold( mDataBlock->forceThreshold ); mBuildScale = getScale(); mBuildAngDrag = mActor->getAngularDamping(); mBuildLinDrag = mActor->getLinearDamping(); }
//---------------------------------------------------------------------------- // Update ring //---------------------------------------------------------------------------- void Splash::updateRing( SplashRing& ring, F32 dt ) { for( U32 i=0; i<ring.points.size(); i++ ) { if( mDead ) { Point3F vel = ring.points[i].velocity; vel.normalize(); vel *= mDataBlock->acceleration; ring.points[i].velocity += vel * dt; } ring.points[i].velocity += Point3F( 0.0f, 0.0f, -9.8f ) * dt; ring.points[i].position += ring.points[i].velocity * dt; } }
void PxCapsulePlayer::setSpacials( const Point3F &nPos, const Point3F &nSize ) { AssertFatal( nSize.least() > 0.0f, "PxCapsulePlayer::setSpacials(), invalid extents!" ); if ( mWorld ) mWorld->releaseWriteLock(); mSize = nSize; F32 radius = getMax( nSize.x, nSize.y ) * 0.5f; radius -= mSkinWidth; radius = getMax(radius,0.01f); F32 height = nSize.z - ( radius * 2.0f ); height -= mSkinWidth * 2.0f; height = getMax(height,0.01f); // The CapsuleController's 'actual' position we are setting. // We are assuming the position passed in is at the bottom of the object // box, like a standard player. Point3F adjustedPos = nPos; adjustedPos.z += mSize.z * 0.5f; mCapsuleController->setPosition( pxCast<NxExtendedVec3>( adjustedPos ) ); mCapsuleController->setRadius( radius ); mCapsuleController->setHeight( height ); }
bool TurretShape::getNodeTransform(S32 node, MatrixF& mat) { if (node == -1) return false; MatrixF nodeTransform = mShapeInstance->mNodeTransforms[node]; const Point3F& scale = getScale(); // The position of the node needs to be scaled. Point3F position = nodeTransform.getPosition(); position.convolve( scale ); nodeTransform.setPosition( position ); mat.mul(mObjToWorld, nodeTransform); return true; }
void GjkCollisionState::getClosestPoints(Point3F& p1, Point3F& p2) { F32 sum = 0; p1.set(0, 0, 0); p2.set(0, 0, 0); for (int i = 0, bit = 1; i < 4; ++i, bit <<= 1) { if (bits & bit) { sum += det[bits][i]; p1 += p[i] * det[bits][i]; p2 += q[i] * det[bits][i]; } } F32 s = 1 / sum; p1 *= s; p2 *= s; }
bool PxCapsulePlayer::testSpacials( const Point3F &nPos, const Point3F &nSize ) const { AssertFatal( nSize.least() > 0.0f, "PxCapsulePlayer::testSpacials(), invalid extents!" ); F32 radius = getMax( nSize.x, nSize.y ) / 2.0f; radius -= mSkinWidth; radius = getMax(radius,0.01f); F32 height = nSize.z - ( radius * 2.0f ); height -= mSkinWidth * 2.0f; height = getMax( height, 0.01f ); F32 halfHeight = height * 0.5f; // We are assuming the position passed in is at the bottom of the object // box, like a standard player. Point3F adjustedPos = nPos; adjustedPos.z += nSize.z * 0.5f; NxVec3 origin = pxCast<NxVec3>( adjustedPos ); NxCapsule worldCapsule( NxSegment(origin,origin), radius ); worldCapsule.p0.z -= halfHeight; worldCapsule.p1.z += halfHeight; bool hit = mWorld->getScene()->checkOverlapCapsule( worldCapsule, NX_STATIC_SHAPES, 0xffffffff, NULL ); return !hit; }
//---------------------------------------------------------------------------- // Create ring //---------------------------------------------------------------------------- SplashRing Splash::createRing() { SplashRing ring; U32 numPoints = mDataBlock->numSegments + 1; Point3F ejectionAxis( 0.0, 0.0, 1.0 ); Point3F axisx; if (mFabs(ejectionAxis.z) < 0.999f) mCross(ejectionAxis, Point3F(0, 0, 1), &axisx); else mCross(ejectionAxis, Point3F(0, 1, 0), &axisx); axisx.normalize(); for( U32 i=0; i<numPoints; i++ ) { F32 t = F32(i) / F32(numPoints); AngAxisF thetaRot( axisx, mDataBlock->ejectionAngle * (M_PI / 180.0)); AngAxisF phiRot( ejectionAxis, t * (M_PI * 2.0)); Point3F pointAxis = ejectionAxis; MatrixF temp; thetaRot.setMatrix(&temp); temp.mulP(pointAxis); phiRot.setMatrix(&temp); temp.mulP(pointAxis); Point3F startOffset = axisx; temp.mulV( startOffset ); startOffset *= mDataBlock->startRadius; SplashRingPoint point; point.position = getPosition() + startOffset; point.velocity = pointAxis * mDataBlock->velocity; ring.points.push_back( point ); } ring.color = mDataBlock->colors[0]; ring.lifetime = mDataBlock->ringLifetime; ring.elapsedTime = 0.0; ring.v = mDataBlock->texFactor * mFmod( mElapsedTime, 1.0 ); return ring; }
virtual void process(NetConnection *con) { // Con::printf("WebViewDataURLEvent: %s, %s, %s;", mWebViewData->getName(), mURL, mFrame); if(mObject.isValid()) { Con::printf("ShapeBaseTransformEvent::process: %f, %f, %f", mObject->getPosition().x, mObject->getPosition().y, mObject->getPosition().z); Con::printf("ShapeBaseTransformEvent::process2: %f, %f, %f", mTransform.getPosition().x, mTransform.getPosition().y, mTransform.getPosition().z); if(mReletive) { if(mScale.x!=1.0f || mScale.y!=1.0f || mScale.z!=1.0f) { Point3F scale = mObject->getScale() * mScale; mObject->setScale(scale); } // if(!(mTransform.isIdentity())) // { // MatrixF mat = mTransform; // mat.mul(mObject->getTransform()); // mObject->setTransform(mat); mObject->setPosition(mObject->getPosition() + mTransform.getPosition()); if(mTransform.hasRotation()) { MatrixF mat(true); mTransform.getOrientation().setMatrix(&mat); mat.mulL(mObject->getTransform()); mObject->setTransform(mat); } // } } else { if(mObject->getScale() != mScale) mObject->setScale(mScale); // if(!mTransform.hasRotation()) // { // Point3F pos = mTransform.getPosition(); // mTransform.set(mObject->getTransform()); // mTransform.mPosition = pos; // } // mObject->setTransform(mTransform.getMatrix()); if(mTransform.hasRotation()) mObject->setTransform(mTransform.getMatrix()); else mObject->setPosition(mTransform.getPosition()); } if(!mVelocity.isZero()) { // mObject->setVelocity(mVelocity); RigidShape* rigid = static_cast<RigidShape*>(mObject.getPointer()); if(rigid) rigid->reset(); mObject->applyImpulse(mObject->getWorldBox().getCenter(), mVelocity); } } }
//----------------------------------------------------------------------------- // This function based on code originally written for the book: // 3D Game Engine Design, by David H. Eberly // F32 sqrDistanceEdges(const Point3F& start0, const Point3F& end0, const Point3F& start1, const Point3F& end1, Point3F* is, Point3F* it) { Point3F direction0 = end0 - start0; F32 fA00 = direction0.lenSquared(); Point3F direction1 = end1 - start1; F32 fA11 = direction1.lenSquared(); F32 fA01 = -mDot(direction0, direction1); Point3F kDiff = start0 - start1; F32 fC = kDiff.lenSquared(); F32 fB0 = mDot(kDiff, direction0); F32 fDet = mFabs(fA00*fA11 - fA01*fA01); // Since the endpoints are tested as vertices, we're not interested // in parallel lines, and intersections that don't involve end-points. if (fDet >= 0.00001) { // Calculate time of intersection for each line F32 fB1 = -mDot(kDiff, direction1); F32 fS = fA01*fB1-fA11*fB0; F32 fT = fA01*fB0-fA00*fB1; // Only interested in collisions that don't involve the end points if (fS >= 0.0 && fS <= fDet && fT >= 0.0 && fT <= fDet) { F32 fInvDet = 1.0 / fDet; fS *= fInvDet; fT *= fInvDet; F32 fSqrDist = (fS*(fA00*fS + fA01*fT + 2.0*fB0) + fT*(fA01*fS + fA11*fT + 2.0*fB1) + fC); // Intersection points. *is = start0 + direction0 * fS; *it = start1 + direction1 * fT; return mFabs(fSqrDist); } } // Return a large number in the cases where endpoints are involved. return 1e10f; }
bool Projectile::calculateImpact(float, Point3F& pointOfImpact, float& impactTime) { Con::warnf(ConsoleLogEntry::General, "Projectile::calculateImpact: Should never be called"); impactTime = 0; pointOfImpact.set(0, 0, 0); return false; }
void GameTSCtrl::onMouseMove(const GuiEvent &evt) { if(gSnapLine) return; MatrixF mat; Point3F vel; if ( GameGetCameraTransform(&mat, &vel) ) { Point3F pos; mat.getColumn(3,&pos); Point3F screenPoint((F32)evt.mousePoint.x, (F32)evt.mousePoint.y, 1.0f); Point3F worldPoint; if (unproject(screenPoint, &worldPoint)) { Point3F vec = worldPoint - pos; lineTestStart = pos; vec.normalizeSafe(); lineTestEnd = pos + vec * 500; static U32 losMask = VehicleObjectType | StaticShapeObjectType; RayInfo ri; bool hit = gClientContainer.castRay( lineTestStart, lineTestEnd, losMask, &ri); if (!hit) { //Con::printf("no hit!"); if (mCursorObject != NULL) mCursorObject->setHighlighted(false); mCursorObject = NULL; } else { if (ri.object != mCursorObject && mCursorObject != NULL) mCursorObject->setHighlighted(false); mCursorObject = (ShapeBase*)ri.object; mCursorObject->setHighlighted(true); } } } }
void CelAnimMesh::setCommonScale( Shape::Mesh & otherMesh ) { CelAnimMesh *potherMesh = dynamic_cast<CelAnimMesh *>(&otherMesh); AssertFatal(potherMesh, "TS::CelAnimMesh::setCommonScale: meshes not same type"); #if 0 // array of unpacked verts -- points only Point3F *unpackedVerts = new Point3F[fVerts.size()]; int v; for (v=0;v<fVerts.size();v++) fVerts[v].getPoint(unpackedVerts[v],fScale,fOrigin); Point3F *otherUnpackedVerts = new Point3F[potherMesh->fVerts.size()]; for (v=0;v<potherMesh->fVerts.size();v++) potherMesh->fVerts[v].getPoint(otherUnpackedVerts[v],potherMesh->fScale,potherMesh->fOrigin); // get minVert and maxVert for setting new fScale, fOrigin, and fRadius Point3F minVert = unpackedVerts[0]; Point3F maxVert = unpackedVerts[0]; for (v=1;v<fVerts.size();v++) { minVert.setMin( unpackedVerts[v] ); maxVert.setMax( unpackedVerts[v] ); } for (v=0;v<potherMesh->fVerts.size();v++) { minVert.setMin( otherUnpackedVerts[v] ); maxVert.setMax( otherUnpackedVerts[v] ); } // figure new fOrigin, fScale, and fRadius Point3F newOrigin = minVert; maxVert -= minVert; Point3F newScale( maxVert.x/255.0f, maxVert.y/255.0f, maxVert.z/255.0f); float newRadius = maxVert.len(); // re-pack this shapes verts int i; Point3F temp; for (i=0;i<fVerts.size();i++) fVerts[i].setPoint(unpackedVerts[i],newScale,newOrigin); fOrigin=newOrigin; fScale=newScale; fRadius=newRadius; // re-pack other shapes verts for (i=0;i<potherMesh->fVerts.size();i++) potherMesh->fVerts[i].setPoint(otherUnpackedVerts[i],newScale,newOrigin); potherMesh->fOrigin=fOrigin; potherMesh->fScale=newScale; potherMesh->fRadius=newRadius; delete [] unpackedVerts; delete [] otherUnpackedVerts; #endif }