Ejemplo n.º 1
0
void ClothDemo::InitializeDebugGui()
{
	stiffness = 1;
	restlength = 3;
	tearlength = 10;
	frameSolvesPerFrame = 1;

	this->gridDisplay->ClickAndDrag = true;

	VerticalDebugMenu::WatchFloatSlider("Rest Length", &restlength, 0.5f, 10.0f);
	VerticalDebugMenu::WatchFloatSlider("Stiffness", &stiffness, 0.0f, 1.25f);
	VerticalDebugMenu::WatchFloatSlider("Solves/Frame", &frameSolvesPerFrame, 1, 4);

	Delegate f = Delegate();
	f.bind(this, &ClothDemo::ResetParticles);
	VerticalDebugMenu::WatchButton("Reset", f);

	
	for(uint r = 0; r < DIMENSION; r++)
	{
		for(uint c = 0; c < DIMENSION; c++)
		{
			points[r][c] = ClothP();

			if(r > 0) links_up[r][c] = ClothLink(&points[r - 1][c], &points[r][c], &restlength, &tearlength, &stiffness);
			if(c > 0) links_left[r][c] = ClothLink(&points[r][c - 1], &points[r][c], &restlength, &tearlength, &stiffness);

			DemoWindow::WatchPoint(&points[r][c].position, &points[r][c].imass, Qt::red);
		}
	}

	ResetParticles();
}
Ejemplo n.º 2
0
void
Buttons( int id )
{
	cl_int status;
	switch( id )
	{
		case GO:
			GLUI_Master.set_glutIdleFunc( Animate );
			break;

		case RESET:
			Reset( );
			ResetParticles( );
			status = clEnqueueWriteBuffer( CmdQueue, dVel, CL_FALSE, 0, 4*sizeof(float)*NUM_PARTICLES, hVel, 0, NULL, NULL );
			PrintCLError( status, "clEneueueWriteBuffer: " );
			GLUI_Master.set_glutIdleFunc( NULL );
			Glui->sync_live( );
			glutSetWindow( MainWindow );
			glutPostRedisplay( );
			break;

		case QUIT:
			Quit( );
			break;

		default:
			fprintf( stderr, "Don't know what to do with Button ID %d\n", id );
	}

}
Ejemplo n.º 3
0
void
InitCL( )
{
	// see if we can even open the opencl Kernel Program
	// (no point going on if we can't):

	FILE *fp = fopen( CL_FILE_NAME, "r" );
	if( fp == NULL )
	{
		fprintf( stderr, "Cannot open OpenCL source file '%s'\n", CL_FILE_NAME );
		return;
	}

	// 2. allocate the host memory buffers:

	cl_int status;		// returned status from opencl calls
				// test against CL_SUCCESS

	// get the platform id:

	status = clGetPlatformIDs( 1, &Platform, NULL );
	PrintCLError( status, "clGetPlatformIDs: " );

	// get the device id:

	status = clGetDeviceIDs( Platform, CL_DEVICE_TYPE_GPU, 1, &Device, NULL );
	PrintCLError( status, "clGetDeviceIDs: " );


	// since this is an opengl interoperability program,
	// check if the opengl sharing extension is supported,
	// (no point going on if it isn't):
	// (we need the Device in order to ask, so can't do it any sooner than here)

	if(  IsCLExtensionSupported( "cl_khr_gl_sharing" )  )
	{
		fprintf( stderr, "cl_khr_gl_sharing is supported.\n" );
	}
	else
	{
		fprintf( stderr, "cl_khr_gl_sharing is not supported -- sorry.\n" );
		return;
	}



	// 3. create an opencl context based on the opengl context:

	cl_context_properties props[ ] =
	{
		CL_GL_CONTEXT_KHR,		(cl_context_properties) wglGetCurrentContext( ),
		CL_WGL_HDC_KHR,			(cl_context_properties) wglGetCurrentDC( ),
		CL_CONTEXT_PLATFORM,		(cl_context_properties) Platform,
		0
	};

	cl_context Context = clCreateContext( props, 1, &Device, NULL, NULL, &status );
	PrintCLError( status, "clCreateContext: " );

	// 4. create an opencl command queue:

	CmdQueue = clCreateCommandQueue( Context, Device, 0, &status );
	if( status != CL_SUCCESS )
		fprintf( stderr, "clCreateCommandQueue failed\n" );

	// create the velocity array and the opengl vertex array buffer and color array buffer:

	delete [ ] hVel;
	hVel = new struct xyzw [ NUM_PARTICLES ];

	glGenBuffers( 1, &hPobj );
	glBindBuffer( GL_ARRAY_BUFFER, hPobj );
	glBufferData( GL_ARRAY_BUFFER, 4 * NUM_PARTICLES * sizeof(float), NULL, GL_STATIC_DRAW );

	glGenBuffers( 1, &hCobj );
	glBindBuffer( GL_ARRAY_BUFFER, hCobj );
	glBufferData( GL_ARRAY_BUFFER, 4 * NUM_PARTICLES * sizeof(float), NULL, GL_STATIC_DRAW );

	glBindBuffer( GL_ARRAY_BUFFER, 0 );	// unbind the buffer

	// fill those arrays and buffers:

	ResetParticles( );

	// 5. create the opencl version of the opengl buffers:

	dPobj = clCreateFromGLBuffer( Context, 0, hPobj, &status );
	PrintCLError( status, "clCreateFromGLBuffer (1)" );

	dCobj = clCreateFromGLBuffer( Context, 0, hCobj, &status );
	PrintCLError( status, "clCreateFromGLBuffer (2)" );

	// 5. create the opencl version of the velocity array:

	dVel = clCreateBuffer( Context, CL_MEM_READ_WRITE, 4*sizeof(float)*NUM_PARTICLES, NULL, &status );
	PrintCLError( status, "clCreateBuffer: " );

	// 6. enqueue the command to write the data from the host buffers to the Device buffers:

	status = clEnqueueWriteBuffer( CmdQueue, dVel, CL_FALSE, 0, 4*sizeof(float)*NUM_PARTICLES, hVel, 0, NULL, NULL );
	PrintCLError( status, "clEneueueWriteBuffer: " );

	// 7. read the Kernel code from a file:

	fseek( fp, 0, SEEK_END );
	size_t fileSize = ftell( fp );
	fseek( fp, 0, SEEK_SET );
	char *clProgramText = new char[ fileSize+1 ];		// leave room for '\0'
	for(int k = 0; k < fileSize; ++k)
		clProgramText[k] = ' '; // ugly hack to fix random charactor insertion problem
	size_t n = fread( clProgramText, 1, fileSize, fp );
	clProgramText[fileSize] = '\0';
	fclose( fp );

	// create the text for the Kernel Program:

	char *strings[1];
	strings[0] = clProgramText;
	Program = clCreateProgramWithSource( Context, 1, (const char **)strings, NULL, &status );
	if( status != CL_SUCCESS )
		fprintf( stderr, "clCreateProgramWithSource failed\n" );
	delete [ ] clProgramText;

	// 8. compile and link the Kernel code:

	char *options = { "" };
	status = clBuildProgram( Program, 1, &Device, options, NULL, NULL );
	if( status != CL_SUCCESS )
	{
		size_t size;
		clGetProgramBuildInfo( Program, Device, CL_PROGRAM_BUILD_LOG, 0, NULL, &size );
		cl_char *log = new cl_char[ size ];
		clGetProgramBuildInfo( Program, Device, CL_PROGRAM_BUILD_LOG, size, log, NULL );
		fprintf( stderr, "clBuildProgram failed:\n%s\n", log );
		delete [ ] log;
	}

	// 9. create the Kernel object:

	Kernel = clCreateKernel( Program, "Particle", &status );
	PrintCLError( status, "clCreateKernel failed: " );


	// 10. setup the arguments to the Kernel object:

	status = clSetKernelArg( Kernel, 0, sizeof(cl_mem), &dPobj );
	PrintCLError( status, "clSetKernelArg (1): " );

	status = clSetKernelArg( Kernel, 1, sizeof(cl_mem), &dVel );
	PrintCLError( status, "clSetKernelArg (2): " );

	status = clSetKernelArg( Kernel, 2, sizeof(cl_mem), &dCobj );
	PrintCLError( status, "clSetKernelArg (3): " );
}
Ejemplo n.º 4
0
//------------------------------------------------------------------------
void CVehicleMovementStdBoat::UpdateSurfaceEffects(const float deltaTime)
{
  FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

  if (0 == g_pGameCVars->v_pa_surface)
  {
    ResetParticles();
    return;
  }
  
  IEntity* pEntity = m_pVehicle->GetEntity();
  const Matrix34& worldTM = pEntity->GetWorldTM();
  
  float distSq = worldTM.GetTranslation().GetSquaredDistance(gEnv->pRenderer->GetCamera().GetPosition());
  if (distSq > sqr(300.f) || (distSq > sqr(50.f) && !m_pVehicle->GetGameObject()->IsProbablyVisible()))
    return;

  Matrix34 worldTMInv = worldTM.GetInverted();
  const SVehicleStatus& status = m_pVehicle->GetStatus();    
  float velDot = status.vel * worldTM.GetColumn1();  
  float powerNorm = min(abs(m_movementAction.power), 1.f);

  SEnvironmentParticles* envParams = m_pPaParams->GetEnvironmentParticles();

  SEnvParticleStatus::TEnvEmitters::iterator end = m_paStats.envStats.emitters.end();
  for (SEnvParticleStatus::TEnvEmitters::iterator emitterIt = m_paStats.envStats.emitters.begin(); emitterIt!=end; ++emitterIt)  
  { 
    if (emitterIt->layer < 0)
    {
      assert(0);
      continue;
    }

    const SEnvironmentLayer& layer = envParams->GetLayer(emitterIt->layer);
    
    SEntitySlotInfo info;        
    info.pParticleEmitter = 0;
    pEntity->GetSlotInfo(emitterIt->slot, info);        

    float countScale = 1.f;
    float sizeScale = 1.f;
		float speedScale = 1.f;
    float speed = 0.f;

    // check if helper position is beneath water level      
                
    Vec3 emitterWorldPos = worldTM * emitterIt->quatT.t;
    float waterLevel = gEnv->p3DEngine->GetWaterLevel(&emitterWorldPos);
    int matId = 0;
    
    if (emitterWorldPos.z <= waterLevel+0.1f && m_physStatus[k_mainThread].submergedFraction<0.999f)
    {
      matId = gEnv->pPhysicalWorld->GetWaterMat();
      speed = status.speed;

      bool spray = !strcmp(layer.GetName(), "spray");        
      
      if (spray)
      {
        // slip based          
        speed -= abs(velDot);
      }

      GetParticleScale(layer, speed, powerNorm, countScale, sizeScale, speedScale);
    }
    else
    {
      countScale = 0.f;
    }
    
    if (matId && matId != emitterIt->matId)
    {
      // change effect       
      IParticleEffect* pEff = 0;                
      const char* effect = GetEffectByIndex( matId, layer.GetName() );

      if (effect && (pEff = gEnv->pParticleManager->FindEffect(effect)))
      {  
#if ENABLE_VEHICLE_DEBUG
        if (DebugParticles())              
					CryLog("%s changes water sfx to %s (slot %i)", pEntity->GetName(), effect, emitterIt->slot);
#endif

        if (info.pParticleEmitter)
        {
          info.pParticleEmitter->Activate(false);
          pEntity->FreeSlot(emitterIt->slot);                  
        }

        emitterIt->slot = pEntity->LoadParticleEmitter(emitterIt->slot, pEff);

        if (emitterIt->slot != -1)
          pEntity->SetSlotLocalTM(emitterIt->slot, Matrix34(emitterIt->quatT));

        info.pParticleEmitter = 0;
        pEntity->GetSlotInfo(emitterIt->slot, info);
      }
      else
        countScale = 0.f;
    }

    if (matId)
      emitterIt->matId = matId;

    if (info.pParticleEmitter)
    {
      SpawnParams sp;
      sp.fSizeScale = sizeScale;
      sp.fCountScale = countScale;    
			sp.fSpeedScale = speedScale;
      info.pParticleEmitter->SetSpawnParams(sp);

      if (layer.alignToWater && countScale > 0.f)
      {          
        Vec3 worldPos(emitterWorldPos.x, emitterWorldPos.y, waterLevel+0.05f);

        Matrix34 localTM(emitterIt->quatT);
        localTM.SetTranslation(worldTMInv * worldPos);
        pEntity->SetSlotLocalTM(emitterIt->slot, localTM);           
      }
    }

#if ENABLE_VEHICLE_DEBUG
    if (DebugParticles() && m_pVehicle->IsPlayerDriving())
    {          
      float color[] = {1,1,1,1};
      ColorB red(255,0,0,255);
      IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
      
      const char* effect = info.pParticleEmitter ? info.pParticleEmitter->GetName() : "";
      const Matrix34& slotTM = m_pEntity->GetSlotWorldTM(emitterIt->slot);
      Vec3 ppos = slotTM.GetTranslation();
      
      pAuxGeom->DrawSphere(ppos, 0.2f, red);
      pAuxGeom->DrawCone(ppos, slotTM.GetColumn1(), 0.1f, 0.5f, red);
      gEnv->pRenderer->Draw2dLabel(50.f, (float)(400+10*emitterIt->slot), 1.2f, color, false, "<%s> water fx: slot %i [%s], speed %.1f, sizeScale %.2f, countScale %.2f (pos %.0f,%0.f,%0.f)", pEntity->GetName(), emitterIt->slot, effect, speed, sizeScale, countScale, ppos.x, ppos.y, ppos.z);        
    }  
#endif
  }

  // generate water splashes
	Vec3 wakePos;
	if(m_pSplashPos)
	{
		wakePos = m_pSplashPos->GetWorldSpaceTranslation();
	}
	else
	{
		wakePos = worldTM.GetTranslation();
	}
  float wakeWaterLevel = gEnv->p3DEngine->GetWaterLevel(&wakePos);

  const Vec3& localW = m_localSpeed;
  if (localW.x >= 0.f)
    m_diving = false;
      
  if (!m_diving && localW.x < -0.03f && status.speed > 10.f && wakePos.z < m_lastWakePos.z && wakeWaterLevel+0.1f >= wakePos.z)
  {
    float speedRatio = min(1.f, status.speed/(m_maxSpeed*m_factorMaxSpeed)); 
    m_diving = true;              
    
    if (m_pWaveEffect)
    {
      if (IParticleEmitter* pEmitter = pEntity->GetParticleEmitter(m_wakeSlot))
      {
        pEmitter->Activate(false);
        pEntity->FreeSlot(m_wakeSlot);
        m_wakeSlot = -1;
      }

      SpawnParams spawnParams;
      spawnParams.fSizeScale = spawnParams.fCountScale = 0.5f + 0.25f*speedRatio;
      spawnParams.fSizeScale  += 0.4f*m_waveRandomMult;
      spawnParams.fCountScale += cry_random(0.0f, 0.4f);

      m_wakeSlot = pEntity->LoadParticleEmitter(m_wakeSlot, m_pWaveEffect, &spawnParams);        
    }

    // handle splash sound  
    ExecuteTrigger(eSID_Splash);
    SetSoundParam(eSID_Splash, "intensity", 0.2f*speedRatio + 0.5f*m_waveRandomMult);     

    if (m_rpmPitchDir == 0)
    {
      m_rpmPitchDir = -1;
      m_waveSoundPitch = 0.f;
      m_waveSoundAmount = 0.02f + m_waveRandomMult*0.08f;
    }      
  }  

  if (m_wakeSlot != -1)
  { 
    // update emitter local pos to short above waterlevel
    Matrix34 tm;
		if(m_pSplashPos)
			m_pSplashPos->GetVehicleTM(tm);
		else
			tm.SetIdentity();

    Vec3 pos = tm.GetTranslation();
    pos.z = worldTMInv.TransformPoint(Vec3(wakePos.x,wakePos.y,wakeWaterLevel)).z + 0.2f;
    tm.SetTranslation(pos);
    pEntity->SetSlotLocalTM(m_wakeSlot, tm);

#if ENABLE_VEHICLE_DEBUG
    if (IsProfilingMovement())
    {
      Vec3 wPos = worldTM * tm.GetTranslation();
      ColorB col(128, 128, 0, 200);
      gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(wPos, 0.4f, col);
      gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(wPos, col, wPos+Vec3(0,0,1.5f), col);
    }          
#endif
  } 

  m_lastWakePos = wakePos;
}
Ejemplo n.º 5
0
bool FireBallParticles::Update(FXMVECTOR newPos, float fireballRadius, float dt, ID3D11DeviceContext* context)
{
	if (!mProperties.isFire || mIsAllParticlesDead)
	{
		return true;
	}

	XMVECTOR nPos = newPos;
	if (mTweenPoints.size() > 0)
	{
		nPos = XMLoadFloat3(&mCurrTweenPoint);
		UpdateCurrentTweenPoint(dt);
	}

	XMFLOAT3 fVel3;
	float pSize;
	bool isParticleStillAlive = false;
	for (int i = 0; i < mFireBallParticles.size(); ++i)
	{
		XMVECTOR pos = XMLoadFloat3(&mFireBallParticles[i].pos);
		XMVECTOR vel = XMLoadFloat3(&mFireBallParticles[i].vel);

		mFireBallParticles[i].age += dt;
		if (mProperties.isOneShot && (mFireBallParticles[i].age >= mFireBallParticles[i].lifetime))
		{
			continue;
		}
		else if (mFireBallParticles[i].age <= mFireBallParticles[i].lifetime)
		{
			isParticleStillAlive = true;
		}
		else if (!mProperties.isOneShot && (mFireBallParticles[i].age >= mFireBallParticles[i].lifetime))
		{
			isParticleStillAlive = true;
			vel = XMVector3Normalize(XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f)) * fireballRadius;
			XMStoreFloat3(&mFireBallParticles[i].pos, nPos + vel);
			fVel3 = GetVelocity();
			vel = XMVector3Normalize(XMVectorSet(fVel3.x, fVel3.y, fVel3.z, 0.0f));
			float speedMult = GetSpeedMultiplier();
			if (MathHelper::RandF() > 0.50f)
			{
				if (MathHelper::RandF() > 0.50f)
				{
					vel.m128_f32[0] += MathHelper::RandF(-0.4f, 0.4f);
					//vel.m128_f32[0] *= MathHelper::RandF(-0.06f, 0.06f);
					//vel.m128_f32[2] *= MathHelper::RandF(-0.06f, 0.06f);
				}
				else
				{
					vel.m128_f32[2] += MathHelper::RandF(-0.4f, 0.4f);
					//vel.m128_f32[0] *= MathHelper::RandF(-0.06f, 0.06f);
					//vel.m128_f32[2] *= MathHelper::RandF(-0.06f, 0.06f);
				}
			}
			XMStoreFloat3(&mFireBallParticles[i].vel, vel * speedMult);
			pSize = GetSize();
			mFireBallParticles[i].size.x = pSize;
			mFireBallParticles[i].size.y = pSize;
			mFireBallParticles[i].age = 0.0f;
			mFireBallParticles[i].lifetime = GetLifetime();
			pos = XMLoadFloat3(&mFireBallParticles[i].pos);
			vel = XMLoadFloat3(&mFireBallParticles[i].vel);
		}
		if (pos.m128_f32[1] < (nPos.m128_f32[1] + (fireballRadius * 0.60f)))
		{
			XMVECTOR s1Center = nPos;
			float s1Radius = fireballRadius;
			float currOverLap = 0.0f;
			XMVECTOR correction = XMVectorZero();

			XMVECTOR d = s1Center - pos;

			float distance = sqrt((d.m128_f32[0] * d.m128_f32[0]) /*+ (d.m128_f32[1] * d.m128_f32[1])*/ + (d.m128_f32[2] * d.m128_f32[2])); //Magnitude of the difference

			float overLap = s1Radius - distance;

			if (overLap > currOverLap) // Have Collision
			{
				currOverLap = overLap;

				correction = XMVector3Normalize(d) * currOverLap; //correct collision by moving sphere out of box
			}
			pos += correction;
		}
		pos = pos + vel;
		XMStoreFloat3(&mFireBallParticles[i].pos, pos);
	}

	if (isParticleStillAlive)
	{
		UpdateFireBallParticleVB(context);
	}
	else
	{
		mIsAllParticlesDead = true;
		if (mProperties.isOneShot)
		{
			ResetParticles();
		}
	}
	return false;
}