LTBOOL CBaseParticleSystemFX::CreateObject(ILTClient *pClientDE)
{
    if (!CSpecialFX::CreateObject(pClientDE)) return LTFALSE;

    LTVector vPos = m_vPos;
    LTRotation rRot;
	rRot.Init();

	// Use server object position if a position wasn't specified...

	if (m_hServerObject)
	{
        LTVector vZero(0, 0, 0), vServObjPos;
        if (vPos.Equals(vZero))
        {
			pClientDE->GetObjectPos(m_hServerObject, &vServObjPos);
			vPos = vServObjPos;
		}
		else
		{
            m_basecs.bClientControlsPos = LTTRUE;
		}

		// Calculate our offset from the server object...

		m_vPosOffset = vPos - vServObjPos;
	}

	// Use the specified rotation if applicable

	if (!m_rRot.IsIdentity())
	{
		rRot = m_rRot;
	}


	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	createStruct.m_ObjectType = OT_PARTICLESYSTEM;
	createStruct.m_Flags = FLAG_VISIBLE | FLAG_UPDATEUNSEEN | FLAG_FOGDISABLE;
	createStruct.m_Pos = vPos;
	createStruct.m_Rotation = rRot;

	m_hObject = m_pClientDE->CreateObject(&createStruct);

	// Setup the ParticleSystem...

	return SetupSystem();
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------------
    ArcBall::ArcBall(const glm::vec3& center, glm::float_t radius, const glm::mat4& screenToTCS) :
            mCenter(center),
            mRadius(radius),
            mScreenToTCS(screenToTCS)
    {
        // glm uses the following format for quaternions: w,x,y,z.
        //        w,    x,    y,    z
        glm::quat qOne(1.0, 0.0, 0.0, 0.0);
        glm::vec3 vZero(0.0, 0.0, 0.0);

        mVDown    = vZero;
        mVNow     = vZero;
        mQDown    = qOne;
        mQNow     = qOne;
    }
Ejemplo n.º 3
0
void
SurfaceCurrent::ComputeSurfaceCurrent(ParGridFunction & k)
{
   if (myid_ == 0) { cout << "Computing K ... " << flush; }

   k = 0.0;
   pcg_->Mult(*RHS_, *PSI_);
   *psi_ = *PSI_;

   Grad_->Mult(*PSI_,*K_);
   k = *K_;

   Vector vZero(3); vZero = 0.0;
   VectorConstantCoefficient Zero(vZero);
   k.ProjectBdrCoefficientTangent(Zero,non_k_bdr_);

   if (myid_ == 0) { cout << "done." << endl << flush; }
}
Ejemplo n.º 4
0
void PlayerVehicle::Respawn()
{
    LTFLOAT fRespawnTime = m_fRespawnTime;

	if (fRespawnTime >= 0.0f)
	{
        g_pLTServer->SetObjectPos(m_hObject, &m_vOriginalPos);
        g_pLTServer->SetObjectRotation(m_hObject, &m_rOriginalRot);

        LTVector vZero(0, 0, 0);
        g_pLTServer->SetVelocity(m_hObject, &vZero);
        g_pLTServer->SetAcceleration(m_hObject, &vZero);
	}
	else
	{
		fRespawnTime = 0.0f;
	}


	// Try to set our dims (make sure we fit where we were placed)...

	LTVector vDims = m_vOriginalDims;
    if (g_pLTServer->SetObjectDims2(m_hObject, &vDims) == LT_ERROR)
	{
        g_pLTServer->SetObjectDims2(m_hObject, &vDims);
	}

 	LTVector vVec(0, 0, 0);
	g_pLTServer->SetAcceleration(m_hObject, &vVec);
	g_pLTServer->SetVelocity(m_hObject, &vVec);

	uint32 dwFlags = g_pLTServer->GetObjectFlags(m_hObject);
	dwFlags &= ~FLAG_VISIBLE;
	dwFlags &= ~FLAG_GRAVITY;
    g_pLTServer->SetObjectFlags(m_hObject, dwFlags);

	m_RespawnTimer.Start(fRespawnTime);
    SetNextUpdate(0.001f);

	MoveObjectToFloor(m_hObject);
}
Ejemplo n.º 5
0
// idx인덱스 이하의 모든 관절의 매트릭스를 갱신함.
void XViewSpline::UpdateMatrix( int idx )
{
    D3DXMATRIX mWorld;

    D3DXMatrixTranslation( &mWorld, vCenter.x, vCenter.y, 0 );
    for( int i = idx; i < MAX_JOINT; ++i )
    {
        JOINT *j = &m_listJoint[ i ];
        // 각도가 돌아갔으므로 행렬과 노말도 갱신
        D3DXMATRIX mRot, mTrans, mLocal;
        D3DXMatrixRotationZ( &mRot, j->m_rAngle );
        D3DXMatrixTranslation( &mTrans, j->m_vLocal.x, j->m_vLocal.y, 0 );
        mLocal = mRot * mTrans;
        if( i > 0 )
            mWorld = mLocal * m_listJoint[ i - 1 ].m_mWorld;
        else
            mWorld = mLocal * mWorld;
        j->m_mWorld = mWorld;
        // 관절 양쪽끝 좌표 계산
        D3DXVECTOR2 v0 = D3DXVECTOR2( 0, 0 );			// 관절원점
        D3DXVECTOR2 v1 = D3DXVECTOR2( LEN_JOINT, 0 );		// 관절끝위치
        D3DXVECTOR2 v0T, v1T;
        D3DXVec2TransformCoord( &j->m_vStart, &v0, &mWorld );
        D3DXVec2TransformCoord( &j->m_vEnd, &v1, &mWorld );

        // 노말 재계산
        D3DXVECTOR2 vN;
        D3DXVECTOR2 vNLocal( 0, -1.f );
        D3DXVec2TransformCoord( &vN, &vNLocal, &mWorld );		// 노말도 같이 돌림
        D3DXVECTOR2 vZero(0, 0), vStart;
        //	D3DXVec2TransformCoord( &vStart, &vZero, &mWorld );	// 관절의 시작지점(월드)
        j->m_vNormal = vN - j->m_vStart;		// 노말(월드)
        //	D3DXMATRIX mInv;
        //	D3DXMatrixInverse( &mInv, nullptr, &mWorld );
        //	D3DXVec2TransformCoord( &j->m_vNormal, &vN, &mInv );		// 월드로 변환된 노말을 원점으로 돌린다.
    }
}
Ejemplo n.º 6
0
void AddBaseProps(CFastList<CEffectPropertyDesc> *pList)
{
	CEffectPropertyDesc fxProp;
	LTVector vZero(0, 0, 0);

	fxProp.SetupEnum( FXPROP_UPDATEPOS, "Follow", "Fixed,Follow,NodeAttach,SocketAttach", eCurve_None, "How this effect should be positioned and oriented with respect to its parent object");
	pList->AddTail(fxProp);

	fxProp.SetupString( FXPROP_ATTACHNAME, "", eCurve_None, "The node or socket to attach to when using NodeAttach or SocketAttach");
	pList->AddTail(fxProp);

	fxProp.SetupVector(FXPROP_INITIALROTATION, vZero, eCurve_None, "The starting rotational offset in degrees. For example, if you wanted a character turned 90 degrees to the right, X would be 90, if it was 90 degrees to the left, X would be -90, and so on.");
	pList->AddTail(fxProp);

	fxProp.SetupVector( FXPROP_ROTATION, vZero, eCurve_Linear, "The amount to rotate around each axis in degrees per second");
	pList->AddTail(fxProp);

	fxProp.SetupVector( FXPROP_OFFSET, vZero, eCurve_Linear, "The amount to offset from the parent position. Relative to the object space");
	pList->AddTail(fxProp);

	fxProp.SetupInt( FXPROP_MENULAYER, 0, eCurve_None, "For interface effects this determines the draw order");
	pList->AddTail(fxProp);

	fxProp.SetupEnumBool( FXPROP_SMOOTHSHUTDOWN, true, eCurve_None, "Determines if the effect should shut down smoothly or be removed instantly when it ends");
	pList->AddTail(fxProp);

	//the detail settings properties. Note that this must match the table in clientfxmgr.cpp
	fxProp.SetupEnum( FXPROP_DETAILLEVEL, "All", "All,High,Medium,Low,Medium+High,Low+Medium,Low+High", eCurve_None, "Specifies the detail settings that this effect should appear on");
	pList->AddTail(fxProp);

	fxProp.SetupEnum( FXPROP_ISGORE, "No", "No,Yes,LowViolenceOnly", eCurve_None, "Determines if this effect is considered to be content that should be filtered out in non-violence modes");
	pList->AddTail(fxProp);

	fxProp.SetupEnum( FXPROP_SLOWMOTION, "All", "All,SlowMoOnly,NoSlowMo", eCurve_None, "Specifies how this key should respond to slow motion. All - Shows up in or out of slow motion. SlowMoOnly - shows up only when in slow motion. NoSlowMo - Will not show up if in slow motion");
	pList->AddTail(fxProp);
}
Ejemplo n.º 7
0
void PlayerVehicle::Respawn()
{
    LTFLOAT fRespawnTime = m_fRespawnTime;

	if (fRespawnTime >= 0.0f)
	{
		g_pLTServer->SetObjectPos(m_hObject, &m_vOriginalPos);
		g_pLTServer->SetObjectRotation(m_hObject, &m_rOriginalRot);

        LTVector vZero(0, 0, 0);
		g_pPhysicsLT->SetVelocity(m_hObject, &vZero);
	}
	else
	{
		fRespawnTime = 0.0f;
	}


	// Try to set our dims (make sure we fit where we were placed)...

	LTVector vDims = m_vOriginalDims;
    if (g_pPhysicsLT->SetObjectDims(m_hObject, &vDims, SETDIMS_PUSHOBJECTS) == LT_ERROR)
	{
        g_pPhysicsLT->SetObjectDims(m_hObject, &vDims, 0);
	}

 	LTVector vVec(0, 0, 0);
	g_pPhysicsLT->SetVelocity(m_hObject, &vVec);

	g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE );

	m_RespawnTimer.Start(fRespawnTime);
    SetNextUpdate(UPDATE_NEXT_FRAME);

	MoveObjectToFloor(m_hObject);
}
Ejemplo n.º 8
0
void fxGetParticleSystemProps( CFastList<CEffectPropertyDesc> *pList )
{
	CEffectPropertyDesc	fxProp;

	LTVector vY(0, 1.0f, 0);
	LTVector vZero(0, 0, 0);

	// Add the generic "every effect has these" props
	AddBaseProps( pList );

	// Add specific Particle System Props
	
	//------------------------------------------------------------
	fxProp.SetupTextLine("System Rendering");
	pList->AddTail(fxProp);

	fxProp.SetupPath( "Material", "", "Material Files (*." RESEXT_MATERIAL ")|*." RESEXT_MATERIAL "|All Files (*.*)|*.*||", eCurve_None, "The material to use when rendering the particles. This material should be rigid, and if the alpha of the particle is not 1, should also be translucent." );
	pList->AddTail( fxProp );

	fxProp.SetupIntMinMax( "NumImages", 1, 1, CParticleSystemProps::knMaxParticleImages, eCurve_None, "The number of images contained within the textures used by the particle. These must be laid out in a horizontal strip, with each image occupying the same width." );
	pList->AddTail( fxProp );

	fxProp.SetupEnumBool( "Solid", false, eCurve_None, "Determines if this particle system should be treated as opaque or translucent" );
	pList->AddTail( fxProp );

	fxProp.SetupEnumBool( "TranslucentLight", true, eCurve_None, "For translucent objects, this determines if lighting should be approximated or if it should be fullbright" );
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("System Behavior");
	pList->AddTail(fxProp);

	fxProp.SetupEnumBool( "PlayerView", false, eCurve_None, "Determines if the sprite should be rendered in the player view, which means that it should have its Z values adjusted to not be clipped into nearby walls");
	pList->AddTail( fxProp );	

	fxProp.SetupEnum( "InSky", SKY_PROP_DEFAULT, SKY_PROP_ENUM, eCurve_None, SKY_PROP_DESCRIPTION);
	pList->AddTail( fxProp );

	fxProp.SetupEnumBool( "MoveParticlesWithSystem", false, eCurve_None, "If this is enabled, the particles will move along with the emitter. This will cause the particle positions, velocity, and additional acceleration to all be specified in object space." );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMin( "GroupCreationInterval", 0.0f, 0.0f, eCurve_None, "This indicates the amount of time that will elapse before a new group is created for the particles to be placed within. This should be set to zero to disable creation of multiple groups");
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Emission");
	pList->AddTail(fxProp);

	fxProp.SetupFloat( "EmissionInterval", 0.1f, eCurve_None, "This is the rate that batches of particles will be emitted from the particle system. This is measured in seconds, so .1 will emit every .1 seconds, or 10 times a second. This should be set to zero if only a single emission should occur." );
	pList->AddTail( fxProp );

	fxProp.SetupIntMin( "ParticlesPerEmission", 5, 0, eCurve_Linear, "Indicates the number of particles that will be emitted per batch." );
	pList->AddTail( fxProp );

	fxProp.SetupEnum( "EmissionType", "Sphere", "Sphere, Point, Cone, Cylinder, Box", eCurve_None, "The primitive to use for emitting the particles." );
	pList->AddTail( fxProp );

	fxProp.SetupVector( "EmissionDir", vY, eCurve_None, "The direction to aim the emission primitive. This is used for cone and cylinder to aim the direction of them." );
	pList->AddTail( fxProp );

	fxProp.SetupVector( "EmissionOffset", vZero, eCurve_Linear, "An additional offset from the position of the object that will be applied to where particles are emitted. For example, if a particle system is attached to a model, but should be offset in the Y direction this can be used to offset the point of emission." );
	pList->AddTail( fxProp );

	fxProp.SetupVectorMin( "EmissionDims", vZero, 0.0f, eCurve_Linear, "This indicates the dimensions of the area to emit in. For box all three are used to determine the half dimensions of the box, for cylinder and cone though, the Y component is used to indicate the height." );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMin( "EmissionMinRadius", 0.0f, 0.0f, eCurve_Linear, "The minimum radius to use for the sphere, cone, and cylinder emission types." );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMin( "EmissionMaxRadius", 10.0f, 0.0f, eCurve_Linear, "The maximum radius to use for the sphere, cone, and cylinder emission types." );
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Properties");
	pList->AddTail(fxProp);

	fxProp.SetupColor( "ParticleColor", 0xFFFFFFFF, eCurve_Linear, "The color of the particles over the course of each particle's lifetime." );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMin("ParticleScale", 10.0f, 0.0f, eCurve_Linear, "This controls the size of the particles over the course of each particle's lifetime");
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Lifetime");
	pList->AddTail(fxProp);

	fxProp.SetupFloatMin( "MinParticleLifeSpan", 2.0f, 0.0f, eCurve_Linear, "The minimum length of time that a particle will live for, measured in seconds. Ignored if the particles have infinite life." );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMin( "MaxParticleLifeSpan", 3.0f, 0.0f, eCurve_Linear, "The maximum length of time that a particle will live for, measured in seconds. Ignored if the particles have infinite life." );
	pList->AddTail( fxProp );

	fxProp.SetupEnumBool( "InfiniteLife", false, eCurve_None, "Specifies whether or not the particles created should last until the end of the effect, or disappear when their lifetime expires" );
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Gravity");
	pList->AddTail(fxProp);

	fxProp.SetupFloat( "GravityScale", 1.0f, eCurve_Linear, "Indicates how much gravity will influence the particles. Zero indicates that gravity will not effect the system, and one indicates that gravity will have normal effect. Values outside of this range can be used for other effects such as negative gravity, or exceptionally fast gravity" );
	pList->AddTail( fxProp );

	fxProp.SetupVector( "AdditionalAcceleration", vZero, eCurve_Linear, "Indicates an additional acceleration to apply to the particles. This acts very much like additional gravity, but can be specified in any direction and can change over time." );
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Velocity");
	pList->AddTail(fxProp);

	fxProp.SetupEnum( "VelocityType", "Random", "Random, FromCenter", eCurve_None, "The method to use when determining the initial linear velocity to use for the particles. Random will pick a random value within the range specified below, while FromCenter will use the direction from the center as the velocity direction, and the X component of the below values to determine the speed" );
	pList->AddTail( fxProp );

	fxProp.SetupVector( "MinParticleVelocity", vY, eCurve_Linear, "The minimum range for the velocities to use when randomly determining the particle velocity. This is in cm per second, and only the X is used for FromCenter" );
	pList->AddTail( fxProp );

	fxProp.SetupVector( "MaxParticleVelocity", vY, eCurve_Linear, "The maximum range for the velocities to use when randomly determining the particle velocity. This is in cm per second, and only the X is used for FromCenter" );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMinMax( "Drag", 0.0f, 0.0f, 1.0f, eCurve_Linear, "Indicates the amount of drag on the particles. This ranges from zero to one, where zero means no drag, and one means full drag, stopping the particles from moving." );
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Rotation");
	pList->AddTail(fxProp);

	fxProp.SetupEnumBool( "RotateParticles", false, eCurve_None, "Determines whether or not the particles will rotate. This cannot be used with streaks and does incur some additional cost." );
	pList->AddTail( fxProp );

	fxProp.SetupFloat( "MinAngularVelocity", 0.0f, eCurve_None, "If RotateParticles is enabled, this will indicate the minimum rotational velocity of the particles in radians per second." );
	pList->AddTail( fxProp );

	fxProp.SetupFloat( "MaxAngularVelocity", 360.0f, eCurve_None, "If RotateParticles is enabled, this will indicate the maximum rotational velocity of the particles in radians per second." );
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Streaks");
	pList->AddTail(fxProp);

	fxProp.SetupEnumBool( "Streak", false, eCurve_None, "Determines if the particles should be streaked based upon their current velocity. This cannot be used with rotating particles." );
	pList->AddTail( fxProp );

	fxProp.SetupFloat( "StreakScale", 1.0f, eCurve_None, "The scale of the streak to apply. The larger this number, the more the particles will streak. At 1.0, a particle going 1 cm/s will stream one unit, so setting this to 10 will make it streak ten times as large and so on.");
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Bounce");
	pList->AddTail(fxProp);

	fxProp.SetupEnumBool( "EnableBounceScale", true, eCurve_None, "Determines whether or not the global scaling of particle bouncing should be applied to the bounce and splat scales specified for this particle system." );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMinMax( "PercentToBounce", 0.0f, 0.0f, 100.0f, eCurve_Linear, "Indicates the percentage of particles that should bounce when they impact a surface. This can range from 0 to 100 where 0 means none bounce, and 100 means all bounce." );
	pList->AddTail( fxProp );

	fxProp.SetupFloatMin( "BounceStrength", 0.75f, 0.0f, eCurve_None, "Specifies the amount of energy left when bouncing. 1 means an object will bounce as high as it was dropped, and 0 means it will not bounce at all" );
	pList->AddTail( fxProp );

	//------------------------------------------------------------
	fxProp.SetupTextLine("Particle Splat");
	pList->AddTail(fxProp);

	fxProp.SetupFloatMinMax( "SplatPercent", 0.0f, 0.0f, 100.0f, eCurve_Linear, "Indicates the percentage of particles that will create the impact effect named below when they impact a surface. This can range from 0 to 100 where 0 means none will create effects, and 100 means all will create effects." );
	pList->AddTail( fxProp );

	fxProp.SetupClientFXRef( "SplatEffect", "", eCurve_None, "The name of the impact effect to create when a particle impacts a surface.");
	pList->AddTail( fxProp );

}
Ejemplo n.º 9
0
//---------------------------------------------------------
//---------------------------------------------------------
void CNPC_Dog::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{

	case TASK_DOG_PICKUP_ITEM:
	{
		 PullObject( false );
	}
	break;

	case TASK_DOG_GET_PATH_TO_PHYSOBJ:
		{
			//Check this cause our object might have been deleted.
			if ( m_hPhysicsEnt == NULL )
				 FindPhysicsObject( NULL );

			//And if we still can't find anything, then just go away.
			if ( m_hPhysicsEnt == NULL )
			{
				TaskFail( "Can't find an object I like!" );
				return;
			}
	
			IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject();
			
			Vector vecGoalPos;
			Vector vecDir;

			vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
			VectorNormalize(vecDir);
			vecDir.z = 0;
		
			if ( m_hPhysicsEnt->GetOwnerEntity() == NULL )
				 m_hPhysicsEnt->SetOwnerEntity( this );
		
			if ( pPhysicsObject )
				 pPhysicsObject->RecheckCollisionFilter();

			vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

			bool bBuiltRoute = false;

			//If I'm near my goal, then just walk to it.
			Activity aActivity = ACT_RUN;

			if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
				 aActivity = ACT_WALK;

			bBuiltRoute = GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL );

			if ( bBuiltRoute == true )
				 TaskComplete();
			else
			{
				m_flTimeToCatch = gpGlobals->curtime + 0.1;
				m_flNextRouteTime = gpGlobals->curtime + 0.3;
				m_flNextSwat = gpGlobals->curtime + 0.1;

				if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 )
					 m_hUnreachableObjects.AddToTail( m_hPhysicsEnt );
								
				m_hPhysicsEnt = NULL;

				GetNavigator()->ClearGoal();
			}
		}
		break;

	case TASK_WAIT:
	{
		if ( IsWaitFinished() )
		{
			TaskComplete();
		}

		if ( m_hPhysicsEnt )
		{
			if ( m_bHasObject == false )
			{
				GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() );
				GetMotor()->UpdateYaw();
			}
		}

		break;
	}

	case TASK_DOG_LAUNCH_ITEM:
		if( IsActivityFinished() )
		{
			if ( m_hPhysicsEnt )
			{
				m_hPhysicsEnt->SetOwnerEntity( NULL );
			}

			TaskComplete();
		}
		break;

	case TASK_DOG_WAIT_FOR_TARGET_TO_FACE:
	{
		if ( CanTargetSeeMe() )
			 TaskComplete();
	}
		break;

	case TASK_WAIT_FOR_MOVEMENT:
		{
			if ( GetState() == NPC_STATE_SCRIPT || IsInAScript() )
			{
			  	 BaseClass::RunTask( pTask );
				 return;
			}

			if ( m_hPhysicsEnt != NULL )
			{
				IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();
					
				if ( !pPhysObj )
				{
					Warning( "npc_dog TASK_WAIT_FOR_MOVEMENT with NULL m_hPhysicsEnt->VPhysicsGetObject\n" );
				}

				if ( pPhysObj && pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
					 TaskFail( "Player picked it up!" );

				//If the object is moving then my old goal might not be valid
				//cancel the schedule and make it restart again in a bit.
				if ( pPhysObj && pPhysObj->IsAsleep() == false && GetNavigator()->IsGoalActive() == false )
				{
					Vector vecGoalPos;
					Vector vecDir;
				
					vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
					VectorNormalize(vecDir);
					vecDir.z = 0;
									
					vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

					GetNavigator()->ClearGoal();

					float flDistance = (vecGoalPos - GetLocalOrigin()).Length();

					//If I'm near my goal, then just walk to it.
					Activity aActivity = ACT_RUN;

					if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
						 aActivity = ACT_WALK;

				    GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL );

					if ( flDistance <= DOG_PHYSOBJ_MOVE_TO_DIST )
					{
						TaskComplete();
						GetNavigator()->StopMoving();
					}
				}
			}
			
			BaseClass::RunTask( pTask );
		}
		break;

	case TASK_DOG_WAIT_FOR_OBJECT:
		{
			if ( m_hPhysicsEnt != NULL )
			{
				if ( FVisible( m_hPhysicsEnt ) == false )
				{
					m_flTimeToCatch = 0.0f;
					ClearBeams();
					TaskFail( "Lost sight of the object!" );
					m_hPhysicsEnt->SetOwnerEntity( NULL );
					return;
				}

				m_hPhysicsEnt->SetOwnerEntity( this );

				Vector vForward;
				AngleVectors( GetAbsAngles(), &vForward );


				Vector vGunPos;
				GetAttachment( m_iPhysGunAttachment, vGunPos );

				Vector vToObject = m_hPhysicsEnt->WorldSpaceCenter() - vGunPos;
				float flDistance = vToObject.Length();

				VectorNormalize( vToObject );

				SetAim( m_hPhysicsEnt->WorldSpaceCenter() - GetAbsOrigin() );

				#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
					CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this); 
				#else
					CBasePlayer *pPlayer = AI_GetSinglePlayer();
				#endif //SecobMod__Enable_Fixed_Multiplayer_AI

				float flDistanceToPlayer = flDistance;

				if ( pPlayer )
				{
					flDistanceToPlayer = (pPlayer->GetAbsOrigin() - m_hPhysicsEnt->WorldSpaceCenter()).Length();
				}
			
				IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();
				if ( !pPhysObj )
				{
					Warning( "npc_dog:  TASK_DOG_WAIT_FOR_OBJECT with m_hPhysicsEnt->VPhysicsGetObject == NULL\n" );
				}
					
				if ( pPhysObj && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) && flDistanceToPlayer > ( flDistance * 2 ) )
				{
					if ( m_flTimeToPull <= gpGlobals->curtime )
					{
						Vector vCurrentVel;
						float flCurrentVel;
						AngularImpulse vCurrentAI;

						pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI );

						flCurrentVel = vCurrentVel.Length();
						VectorNormalize( vCurrentVel );

						if ( pPhysObj && flDistance <= DOG_PULL_DISTANCE )
						{
							Vector vDir = ( vGunPos -  m_hPhysicsEnt->WorldSpaceCenter() );
								
							VectorNormalize( vDir );

							vCurrentVel = vCurrentVel * ( flCurrentVel * DOG_PULL_VELOCITY_MOD );

							vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD;
							pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI );

							vDir = vDir * flDistance * DOG_PULL_TO_GUN_VEL_MOD;

							Vector vAngle( 0, 0, 0 );
							pPhysObj->AddVelocity( &vDir, &vAngle );
							
							CreateBeams();
						}
					
						float flDot = DotProduct( vCurrentVel, vForward );

						if ( flDistance >= DOG_PULL_DISTANCE && flDistance <= ( DOG_PULL_DISTANCE * 2 ) && flDot > -0.3 )
						{
							if ( pPhysObj->IsAsleep() == false && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) )
							{
								Vector vecGoalPos;
								Vector vecDir;

								vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
								VectorNormalize(vecDir);
								vecDir.z = 0;
												
								vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

								GetNavigator()->ClearGoal();

								//If I'm near my goal, then just walk to it.
								Activity aActivity = ACT_RUN;

								if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
									 aActivity = ACT_WALK;
									 
								GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ),  AIN_NO_PATH_TASK_FAIL );
							}
						}
					}
				}


				float flDirDot = DotProduct( vToObject, vForward );

				if ( flDirDot < 0.2 )
				{
					GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() );
					GetMotor()->UpdateYaw();
				}

				if ( m_flTimeToCatch < gpGlobals->curtime && m_bDoWaitforObjectBehavior == false ) 
				{
					m_hPhysicsEnt->SetOwnerEntity( NULL );
					m_flTimeToCatch = 0.0f;
					ClearBeams();
					TaskFail( "Done waiting!" );
				}
				else if ( pPhysObj && ( flDistance <= DOG_CATCH_DISTANCE && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) )
				{
					AngularImpulse vZero( 0, 0, 0 );
					pPhysObj->SetVelocity( &vec3_origin, &vZero );

					GetNavigator()->StopMoving();

					//Fire Output!
					m_OnCatch.FireOutput( this, this );
					m_bHasObject = true;
					ClearBeams();
					TaskComplete();
				}
			}
			else
			{
				GetNavigator()->StopMoving();

				ClearBeams();
				TaskFail("No Physics Object!");
			}
			
		}
		break;

	case TASK_DOG_CATCH_OBJECT:
		if( IsActivityFinished() )
		{
			m_flTimeToCatch = 0.0f;
			TaskComplete();
		}
		break;
	default:
		BaseClass::RunTask( pTask );
		break;
	}
}
Ejemplo n.º 10
0
LTBOOL CFireFX::CreateObject(ILTClient* pClientDE)
{
    if (!CSpecialFX::CreateObject(pClientDE) || !g_pGameClientShell) return LTFALSE;

	CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr();
    if (!psfxMgr) return LTFALSE;

    LTVector vZero(0, 0, 0), vOffset(0, 0, 0);
	CString str;
    uint32 dwFlags;

	// Get our initial pos...

	if (m_cs.vPos.Equals(vZero) && m_hServerObject)
    {
        g_pLTClient->GetObjectPos(m_hServerObject, &(m_cs.vPos));
	}


	SMCREATESTRUCT sm;
	sm.hServerObj		= m_hServerObject;
    sm.bRelToCameraPos  = LTTRUE;
	sm.fInnerCamRadius	= FFX_INNER_CAM_RADIUS;
	sm.fOuterCamRadius	= FFX_INNER_CAM_RADIUS + (FFX_CAM_FALLOFF_RANGE * m_fSizeAdjust);

	// Create the smoke particles...

	if (m_cs.bCreateSmoke)
	{
		vOffset.Init(0, 20.0f * m_fSizeAdjust, 0);
		vOffset.y = vOffset.y > 50.0f ? 50.0f : vOffset.y;

		sm.vColor1.Init(100.0f, 100.0f, 100.0f);
		sm.vColor2.Init(150.0f, 150.0f, 150.0f);
		sm.vMinDriftVel.Init(-2.0f, 15.0f, -2.0f);
		sm.vMaxDriftVel.Init(2.0f, 50.0f, 2.0f);
		sm.fVolumeRadius		= 5.0f * (1.5f * m_fSizeAdjust);
		sm.fLifeTime			= 100000.0f;
		sm.fRadius				= FFX_DEFAULT_SMOKE_PARTICLE_RADIUS * m_fSizeAdjust;
		sm.fParticleCreateDelta	= 0.25f;
		sm.fMinParticleLife		= 2.0f * m_fSizeAdjust;
		sm.fMaxParticleLife		= 4.0f * m_fSizeAdjust;
		sm.nNumParticles		= 2;
		//sm.bMultiply			= m_cs.bBlackSmoke;
        sm.bIgnoreWind          = LTFALSE;
		sm.vPos					= m_cs.vPos + vOffset;

        sm.bAdjustParticleScale = LTTRUE;
		sm.fStartParticleScale	= 1.0f;
		sm.fEndParticleScale	= 0.5f;
        sm.bAdjustParticleAlpha = LTTRUE;
		sm.fStartParticleAlpha	= 1.0f;
		sm.fEndParticleAlpha	= 0.0f;

		sm.fMinParticleLife	= sm.fMinParticleLife < FFX_MIN_SMOKE_PARTICLE_LIFETIME ? FFX_MIN_SMOKE_PARTICLE_LIFETIME :
			(sm.fMinParticleLife > FFX_MAX_SMOKE_PARTICLE_LIFETIME ? FFX_MAX_SMOKE_PARTICLE_LIFETIME : sm.fMinParticleLife);
		sm.fMaxParticleLife	= sm.fMaxParticleLife > FFX_MAX_SMOKE_PARTICLE_LIFETIME ? FFX_MAX_SMOKE_PARTICLE_LIFETIME :
			(sm.fMaxParticleLife < FFX_MIN_SMOKE_PARTICLE_LIFETIME ? FFX_MIN_SMOKE_PARTICLE_LIFETIME : sm.fMaxParticleLife);
		sm.fRadius = sm.fRadius > FFX_MAX_SMOKE_PARTICLE_RADIUS ? FFX_MAX_SMOKE_PARTICLE_RADIUS : sm.fRadius;

		str = g_pClientButeMgr->GetSpecialFXAttributeString("FireSmokeTex");
        if (str.IsEmpty()) return LTFALSE;

        sm.hstrTexture = g_pLTClient->CreateString((char *)(LPCSTR)str);

		if (!m_Smoke1.Init(&sm) || !m_Smoke1.CreateObject(m_pClientDE))
		{
            return LTFALSE;
		}
        g_pLTClient->FreeString(sm.hstrTexture);

        dwFlags = g_pLTClient->GetObjectFlags(m_Smoke1.GetObject());
        g_pLTClient->SetObjectFlags(m_Smoke1.GetObject(), dwFlags | FLAG_NOGLOBALLIGHTSCALE);

		m_Smoke1.Update();
	}

	// Create the fire particles...

	if (!m_cs.bSmokeOnly)
	{
        LTFLOAT fVolumeAdjust = m_fSizeAdjust < 1.0 ? m_fSizeAdjust / 1.5f : m_fSizeAdjust * 1.5f;

		sm.vColor1.Init(100.0f, 100.0f, 100.0f);
		sm.vColor2.Init(150.0f, 150.0f, 150.0f);
		sm.vMinDriftVel.Init(-2.0f, 8.0f, -2.0f);
		sm.vMaxDriftVel.Init(2.0f, 15.0f, 2.0f);
		sm.fVolumeRadius		= 10.0f * fVolumeAdjust;
		sm.fLifeTime			= 100000.0f;
		sm.fRadius				= FFX_DEFAULT_FIRE_PARTICLE_RADIUS * m_fSizeAdjust;
		sm.fParticleCreateDelta	= 0.1f;
		sm.fMinParticleLife		= 1.0f * m_fSizeAdjust;
		sm.fMaxParticleLife		= 2.0f * m_fSizeAdjust;
		sm.nNumParticles		= 3;
        sm.bAdditive            = LTTRUE;
		sm.vPos					= m_cs.vPos;

		//sm.fStartParticleScale	= 1.0f;
		//sm.fEndParticleScale	= 0.0f;

		sm.fMinParticleLife	= sm.fMinParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME :
			(sm.fMinParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME : sm.fMinParticleLife);
		sm.fMaxParticleLife	= sm.fMaxParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME :
			(sm.fMaxParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME : sm.fMaxParticleLife);
		sm.fRadius = sm.fRadius > FFX_MAX_FIRE_PARTICLE_RADIUS ? FFX_MAX_FIRE_PARTICLE_RADIUS : sm.fRadius;

		str = g_pClientButeMgr->GetSpecialFXAttributeString("FireTex");
        if (str.IsEmpty()) return LTFALSE;

        sm.hstrTexture = g_pLTClient->CreateString((char *)(LPCSTR)str);

		if (!m_Fire1.Init(&sm) || !m_Fire1.CreateObject(m_pClientDE))
		{
            return LTFALSE;
		}

        dwFlags = g_pLTClient->GetObjectFlags(m_Fire1.GetObject());
        g_pLTClient->SetObjectFlags(m_Fire1.GetObject(), dwFlags | FLAG_NOGLOBALLIGHTSCALE);

		m_Fire1.Update();
        g_pLTClient->FreeString(sm.hstrTexture);


		// Create inner fire particles...

		sm.vColor1.Init(100.0f, 100.0f, 100.0f);
		sm.vColor2.Init(150.0f, 150.0f, 150.0f);
		sm.vMinDriftVel.Init(-2.0f, 25.0f, -2.0f);
		sm.vMaxDriftVel.Init(2.0f, 35.0f, 2.0f);
		sm.fRadius			= FFX_DEFAULT_FIRE_PARTICLE_RADIUS * 0.75f * m_fSizeAdjust;
		sm.nNumParticles	= 5;
		sm.fVolumeRadius	= 5.0f * fVolumeAdjust;
		sm.fLifeTime		= 100000.0f;
		sm.fMinParticleLife	= 0.5f * m_fSizeAdjust;
		sm.fMaxParticleLife	= 1.25f * m_fSizeAdjust;

		//sm.fStartParticleScale	= 1.0f;
		//sm.fEndParticleScale	= 0.5f;

		sm.fMinParticleLife	= sm.fMinParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME :
			(sm.fMinParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME : sm.fMinParticleLife);
		sm.fMaxParticleLife	= sm.fMaxParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME :
			(sm.fMaxParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME : sm.fMaxParticleLife);
		sm.fRadius = sm.fRadius > FFX_MAX_FIRE_PARTICLE_RADIUS ? FFX_MAX_FIRE_PARTICLE_RADIUS : sm.fRadius;

		str = g_pClientButeMgr->GetSpecialFXAttributeString("FireTex2");
        if (str.IsEmpty()) return LTFALSE;

        sm.hstrTexture = g_pLTClient->CreateString((char *)(LPCSTR)str);

		if (!m_Fire2.Init(&sm) || !m_Fire2.CreateObject(m_pClientDE))
		{
            return LTFALSE;
		}

        dwFlags = g_pLTClient->GetObjectFlags(m_Fire2.GetObject());
        g_pLTClient->SetObjectFlags(m_Fire2.GetObject(), dwFlags | FLAG_NOGLOBALLIGHTSCALE);

		m_Fire2.Update();
        g_pLTClient->FreeString(sm.hstrTexture);


		// Create the sound...

		if (m_cs.bCreateSound)
		{
			str = g_pClientButeMgr->GetSpecialFXAttributeString("FireSnd");

			m_hSound = g_pClientSoundMgr->PlaySoundFromPos(m_cs.vPos, (char*)(LPCSTR)str,
				m_cs.fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, PLAYSOUND_GETHANDLE | PLAYSOUND_LOOP);
		}


		// Create the dynamic light...

		if (m_cs.bCreateLight)
		{
			LIGHTCREATESTRUCT light;

            LTFLOAT fRadiusMin = m_cs.fLightRadius;
			fRadiusMin = fRadiusMin < 20.0f ? 20.0f : (fRadiusMin > FFX_MAX_LIGHT_RADIUS ? FFX_MAX_LIGHT_RADIUS : fRadiusMin);

			light.vColor				= m_cs.vLightColor;
			light.hServerObj			= m_hServerObject;
			light.vOffset				= m_cs.vLightOffset;
			light.dwLightFlags			= FLAG_DONTLIGHTBACKFACING;
			light.fIntensityMin			= 1.0f;
			light.fIntensityMax			= 1.0f;
			light.nIntensityWaveform	= WAVE_NONE;
			light.fIntensityFreq		= 1.0f;
			light.fIntensityPhase		= 0.0f;
			light.fRadiusMin			= fRadiusMin;
			light.fRadiusMax			= fRadiusMin * 1.1f;
			light.nRadiusWaveform		= WAVE_FLICKER2;
			light.fRadiusFreq			= m_cs.fLightFreq;
			light.fRadiusPhase			= m_cs.fLightPhase;
			light.m_hLightAnim			= INVALID_LIGHT_ANIM;

			if (!m_Light.Init(&light) || !m_Light.CreateObject(m_pClientDE))
			{
                return LTFALSE;
			}
		}
	}

    return LTTRUE;
}
// 计算顶点法线量
void C3DSModel::ComputeNormals(void)
{
	Vector3 v1,v2, vNormal,vPoly[3];

	// 如果没有3ds对象则直接返回
	if (m_3DModel.numOfObjects <= 0)
		return;

	t3DObject *obj;
	int		  *index;

	for(int nOfObj=0; nOfObj<m_3DModel.numOfObjects; nOfObj++)
	{
		obj = &m_3DModel.pObject[nOfObj];
		Vector3 *pNormals		= new Vector3 [obj->numOfFaces];
		Vector3 *pTempNormals	= new Vector3 [obj->numOfFaces];
		obj->pNormals			= new Vector3 [obj->numOfVerts];

		for(int nOfFace=0; nOfFace<obj->numOfFaces; nOfFace++)
		{
			index = obj->pFaces[nOfFace].vertIndex;
			// 三角形的3个顶点
			vPoly[0] = obj->pVerts[index[0]];
			vPoly[1] = obj->pVerts[index[1]];
			vPoly[2] = obj->pVerts[index[2]];
			// 计算这个三角形的法线量
			v1 = vPoly[0]-vPoly[1];
			v2 = vPoly[2]-vPoly[1];
			vNormal  = Cross(v1, v2);

			pTempNormals[nOfFace] = vNormal;					// 保存未单位化的法向量
			vNormal  = Normalize(vNormal);						// 单位化法向量
			pNormals[nOfFace] = vNormal;						// 增加到法向量数组列表
		}
		Vector3 vSum(0.0, 0.0, 0.0);
		Vector3 vZero(0.0, 0.0, 0.0);
		int shared=0;

		for (int nOfVert = 0; nOfVert < obj->numOfVerts; nOfVert++)			// 遍历所有顶点
		{
			for (int nOfFace = 0; nOfFace < obj->numOfFaces; nOfFace++)		// 遍历包含该顶点的面
			{
				if (obj->pFaces[nOfFace].vertIndex[0] == nOfVert || 
					obj->pFaces[nOfFace].vertIndex[1] == nOfVert || 
					obj->pFaces[nOfFace].vertIndex[2] == nOfVert)
				{
					vSum = vSum+pTempNormals[nOfFace];
					shared++;
				}
			}      
			
			obj->pNormals[nOfVert] = vSum/float(-shared);

			obj->pNormals[nOfVert] = Normalize(obj->pNormals[nOfVert]);	

			vSum = vZero;
			shared = 0;
		}
	
		delete [] pTempNormals;
		delete [] pNormals;
	}

}