bool C_PortalGhostRenderable::GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel ) { if( m_pGhostedRenderable == NULL ) return false; Vector ghostVel; if( m_pGhostedRenderable->GetAttachmentVelocity( number, ghostVel, angleVel ) ) { Vector3DMultiply( m_matGhostTransform, ghostVel, originVel ); Vector3DMultiply( m_matGhostTransform, *(Vector*)( &angleVel ), *(Vector*)( &angleVel ) ); return true; } return false; }
void CSDKPlayer::SDKThrowWeaponDir( CWeaponSDKBase *pWeapon, const Vector &vecForward, Vector *pVecThrowDir ) { VMatrix zRot; MatrixBuildRotateZ( zRot, random->RandomFloat( -60.0f, 60.0f ) ); Vector vecThrow; Vector3DMultiply( zRot, vecForward, *pVecThrowDir ); pVecThrowDir->z = random->RandomFloat( -0.5f, 0.5f ); VectorNormalize( *pVecThrowDir ); }
//----------------------------------------------------------------------------- // Builds a rotation matrix that rotates one direction vector into another //----------------------------------------------------------------------------- void MatrixBuildRotation( VMatrix &dst, const Vector& initialDirection, const Vector& finalDirection ) { float angle = DotProduct( initialDirection, finalDirection ); assert( IsFinite(angle) ); Vector axis; // No rotation required if (angle - 1.0 > -1e-3) { // parallel case MatrixSetIdentity(dst); return; } else if (angle + 1.0 < 1e-3) { // antiparallel case, pick any axis in the plane // perpendicular to the final direction. Choose the direction (x,y,z) // which has the minimum component of the final direction, use that // as an initial guess, then subtract out the component which is // parallel to the final direction int idx = 0; if (FloatMakePositive(finalDirection[1]) < FloatMakePositive(finalDirection[idx])) idx = 1; if (FloatMakePositive(finalDirection[2]) < FloatMakePositive(finalDirection[idx])) idx = 2; axis.Init( 0, 0, 0 ); axis[idx] = 1.0f; VectorMA( axis, -DotProduct( axis, finalDirection ), finalDirection, axis ); VectorNormalize(axis); angle = 180.0f; } else { CrossProduct( initialDirection, finalDirection, axis ); VectorNormalize( axis ); angle = acos(angle) * 180 / M_PI; } MatrixBuildRotationAboutAxis( dst, axis, angle ); #ifdef _DEBUG Vector test; Vector3DMultiply( dst, initialDirection, test ); test -= finalDirection; assert( test.LengthSqr() < 1e-3 ); #endif }
void CTrailParticles::RenderParticles(CParticleRenderIterator *pIterator) { const TrailParticle *pParticle = (const TrailParticle*) pIterator->GetFirst(); while (pParticle) { //Get our remaining time float lifePerc = 1.0f - (pParticle->m_flLifetime / pParticle->m_flDieTime); float scale = (pParticle->m_flLength*lifePerc); if (scale < 0.01f) scale = 0.01f; Vector start, delta; //NOTE: We need to do everything in screen space TransformParticle(ParticleMgr()->GetModelView(), pParticle->m_Pos, start); float sortKey = start.z; Vector3DMultiply(ParticleMgr()->GetModelView(), pParticle->m_vecVelocity, delta); float color[4]; float ramp = 1.0; // Fade in for the first few frames if (pParticle->m_flLifetime <= 0.3 && m_fFlags & bitsPARTICLE_TRAIL_FADE_IN) { ramp = pParticle->m_flLifetime; } else if (m_fFlags & bitsPARTICLE_TRAIL_FADE) { ramp = (1.0f - (pParticle->m_flLifetime / pParticle->m_flDieTime)); } color[0] = pParticle->m_color.r * ramp * (1.0f / 255.0f); color[1] = pParticle->m_color.g * ramp * (1.0f / 255.0f); color[2] = pParticle->m_color.b * ramp * (1.0f / 255.0f); color[3] = pParticle->m_color.a * ramp * (1.0f / 255.0f); float flLength = (pParticle->m_vecVelocity * scale).Length();//( delta - pos ).Length(); float flWidth = (flLength < pParticle->m_flWidth) ? flLength : pParticle->m_flWidth; //See if we should fade Vector vecScaledDelta = (delta*scale); Tracer_Draw(pIterator->GetParticleDraw(), start, vecScaledDelta, flWidth, color); pParticle = (const TrailParticle*) pIterator->GetNext(sortKey); } }
//----------------------------------------------------------------------------- // Does a fast inverse, assuming the matrix only contains translation and rotation. //----------------------------------------------------------------------------- void MatrixInverseTR( const VMatrix& src, VMatrix &dst ) { Vector vTrans, vNewTrans; // Transpose the upper 3x3. dst.m[0][0] = src.m[0][0]; dst.m[0][1] = src.m[1][0]; dst.m[0][2] = src.m[2][0]; dst.m[1][0] = src.m[0][1]; dst.m[1][1] = src.m[1][1]; dst.m[1][2] = src.m[2][1]; dst.m[2][0] = src.m[0][2]; dst.m[2][1] = src.m[1][2]; dst.m[2][2] = src.m[2][2]; // Transform the translation. vTrans.Init( -src.m[0][3], -src.m[1][3], -src.m[2][3] ); Vector3DMultiply( dst, vTrans, vNewTrans ); MatrixSetColumn( dst, 3, vNewTrans ); // Fill in the bottom row. dst.m[3][0] = dst.m[3][1] = dst.m[3][2] = 0.0f; dst.m[3][3] = 1.0f; }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ bool CPlasmaSpray::SimulateAndRender(Particle *pParticle, ParticleDraw *pDraw, float &sortDist ) { SimpleParticle* pSimpleParticle = (SimpleParticle*)pParticle; //Should this particle die? pSimpleParticle->m_flLifetime += pDraw->GetTimeDelta(); C_PlasmaBeamNode* pNode = (C_PlasmaBeamNode*)((C_BaseEntity*)m_pOwner); if ( pSimpleParticle->m_flLifetime >= pSimpleParticle->m_flDieTime ) { return false; } // If owner is gone or spray off remove me else if (pNode == NULL || !pNode->m_bSprayOn) { return false; } float scale = random->RandomFloat( 0.02, 0.08 ); // NOTE: We need to do everything in screen space Vector delta; Vector start; TransformParticle(g_ParticleMgr.GetModelView(), pSimpleParticle->m_Pos, start); Vector3DMultiply( CurrentWorldToViewMatrix(), pSimpleParticle->m_vecVelocity, delta ); delta[0] *= scale; delta[1] *= scale; delta[2] *= scale; // See c_tracer.* for this method Tracer_Draw( pDraw, start, delta, random->RandomInt( 2, 8 ), 0 ); //Simulate the movement with collision trace_t trace; float timeDelta = pDraw->GetTimeDelta(); m_ParticleCollision.MoveParticle( pSimpleParticle->m_Pos, pSimpleParticle->m_vecVelocity, NULL, timeDelta, &trace ); return true; }
//----------------------------------------------------------------------------- // Transform a plane //----------------------------------------------------------------------------- void MatrixTransformPlane( const VMatrix &src, const cplane_t &inPlane, cplane_t &outPlane ) { // What we want to do is the following: // 1) transform the normal into the new space. // 2) Determine a point on the old plane given by plane dist * plane normal // 3) Transform that point into the new space // 4) Plane dist = DotProduct( new normal, new point ) // An optimized version, which works if the plane is orthogonal. // 1) Transform the normal into the new space // 2) Realize that transforming the old plane point into the new space // is given by [ d * n'x + Tx, d * n'y + Ty, d * n'z + Tz ] // where d = old plane dist, n' = transformed normal, Tn = translational component of transform // 3) Compute the new plane dist using the dot product of the normal result of #2 // For a correct result, this should be an inverse-transpose matrix // but that only matters if there are nonuniform scale or skew factors in this matrix. Vector3DMultiply( src, inPlane.normal, outPlane.normal ); outPlane.dist = inPlane.dist * DotProduct( outPlane.normal, outPlane.normal ); outPlane.dist += DotProduct( outPlane.normal, src.GetTranslation() ); }
//----------------------------------------------------------------------------- // Updates the relative orientation of the camera, spring mode //----------------------------------------------------------------------------- void CWeaponIFMSteadyCam::ComputeMouseRay( const VMatrix &steadyCamToPlayer, Vector &vecForward ) { // Create a ray in steadycam space float flMaxD = 1.0f / tan( M_PI * m_flFOV / 360.0f ); // Remap offsets into normalized space int w, h; GetViewportSize( w, h ); float flViewX = ( w != 0 ) ? m_vecViewOffset.x / ( w / 2 ) : 0.0f; float flViewY = ( h != 0 ) ? m_vecViewOffset.y / ( h / 2 ) : 0.0f; flViewX *= flMaxD; flViewY *= flMaxD; Vector vecSelectionDir( 1.0f, -flViewX, -flViewY ); VectorNormalize( vecSelectionDir ); // Rotate the ray into player coordinates Vector3DMultiply( steadyCamToPlayer, vecSelectionDir, vecForward ); }
void CWeaponIFMSteadyCam::UpdateRelativeOrientation() { if ( m_bIsLocked ) return; if ( m_bInDirectMode ) { UpdateDirectRelativeOrientation(); return; } if ( ( m_vecViewOffset.x == 0.0f ) && ( m_vecViewOffset.y == 0.0f ) ) return; // Compute a player to steadycam matrix VMatrix steadyCamToPlayer; MatrixFromAngles( m_angRelativeAngles, steadyCamToPlayer ); MatrixSetColumn( steadyCamToPlayer, 3, m_vecRelativePosition ); Vector vecCurrentForward; MatrixGetColumn( steadyCamToPlayer, 0, &vecCurrentForward ); // Create a ray in steadycam space float flMaxD = 1.0f / tan( M_PI * m_flFOV / 360.0f ); // Remap offsets into normalized space float flViewX = m_vecViewOffset.x / ( 384 / 2 ); float flViewY = m_vecViewOffset.y / ( 288 / 2 ); flViewX *= flMaxD * ifm_steadycam_mousefactor.GetFloat(); flViewY *= flMaxD * ifm_steadycam_mousefactor.GetFloat(); Vector vecSelectionDir( 1.0f, -flViewX, -flViewY ); VectorNormalize( vecSelectionDir ); // Rotate the ray into player coordinates Vector vecDesiredDirection; Vector3DMultiply( steadyCamToPlayer, vecSelectionDir, vecDesiredDirection ); float flDot = DotProduct( vecDesiredDirection, vecCurrentForward ); flDot = clamp( flDot, -1.0f, 1.0f ); float flAngle = 180.0f * acos( flDot ) / M_PI; if ( flAngle < 1e-3 ) { matrix3x4_t mat; MatrixFromForwardDirection( vecDesiredDirection, mat ); MatrixAngles( mat, m_angRelativeAngles ); return; } Vector vecAxis; CrossProduct( vecCurrentForward, vecDesiredDirection, vecAxis ); VectorNormalize( vecAxis ); float flRotateRate = ifm_steadycam_rotaterate.GetFloat(); if ( flRotateRate < 1.0f ) { flRotateRate = 1.0f; } float flRateFactor = flAngle / flRotateRate; flRateFactor *= flRateFactor * flRateFactor; float flRate = flRateFactor * 30.0f; float flMaxAngle = gpGlobals->frametime * flRate; flAngle = clamp( flAngle, 0.0f, flMaxAngle ); Vector vecNewForard; VMatrix rotation; MatrixBuildRotationAboutAxis( rotation, vecAxis, flAngle ); Vector3DMultiply( rotation, vecCurrentForward, vecNewForard ); matrix3x4_t mat; MatrixFromForwardDirection( vecNewForard, mat ); MatrixAngles( mat, m_angRelativeAngles ); Assert( m_angRelativeAngles.IsValid() ); }
static int vmatrix_Vector3DMultiply (lua_State *L) { Vector3DMultiply(luaL_checkvmatrix(L, 1), luaL_checkvector(L, 2), luaL_checkvector(L, 3)); return 0; }