bool ParticleEmitterPressure::stepEmissionSite(
	SiteData& siteData,
	ParticleData& spawnData,
	PxU32& spawnNum, 
	const PxU32 spawnMax,
	const PxVec3 &sitePos, 
	const PxVec3 &siteVel,
	const PxReal dt)
{
	PxReal maxDistanceMoved = 5.0f * mSpacingZ;	// don't generate long particle beams

	/**
	 * Find displacement vector of the particle's motion this frame
	 * this is not necessarily v*stepSize because a collision might have occured
	 */
	PxVec3 displacement = siteData.position - sitePos;
	PxVec3 normal = displacement;
	PxReal distanceMoved = normal.normalize();

	if (distanceMoved > maxDistanceMoved)
		distanceMoved = maxDistanceMoved;
	
	/**
	 * Place particles along line between emission point and new position
	 * starting backwards from the new position
	 * spacing between the particles is the rest spacing of the fluid 
	 */
	PxReal lastPlaced = 0.0f;
	while((lastPlaced + mSpacingZ) <= distanceMoved)
	{
		PxVec3 pos = sitePos + normal * (distanceMoved - (lastPlaced + mSpacingZ));

		PxVec3 posNoise;
		posNoise.x = randInRange(-mRandomPos.x, mRandomPos.x);
		posNoise.y = randInRange(-mRandomPos.y, mRandomPos.y);		
		
		pos += mAxisX*posNoise.x + mAxisY*posNoise.y;

		bool isSpawned = spawnParticle(spawnData, spawnNum, spawnMax, pos, siteVel);
		if(isSpawned)
		{
			updatePredecessor(siteData, pos, siteVel);
			lastPlaced += mSpacingZ;
		}
		else
		{
			return false;
		}
	}
	return true;
}
Beispiel #2
0
LaneSettings::LaneSettings(ProjectSettings *projectSettings, SettingsElement *parentSettingsElement, Lane *lane)
    : SettingsElement(projectSettings, parentSettingsElement, lane)
    , ui(new Ui::LaneSettings)
    , lane_(lane)
    , init_(false)
    , roadSystemItemPolyGraph_(NULL)
    , insertWidthSectionHandle_(NULL)
    , lswItem_(NULL)
{
    ui->setupUi(this);

	activateWidthGroupBox(false);
	activateInsertGroupBox(false);
	connect(ui->insertPushButton, SIGNAL(clicked(bool)), this, SLOT(activateInsertGroupBox(bool)));
	connect(ui->editPushButton, SIGNAL(clicked(bool)), this, SLOT(activateWidthGroupBox(bool)));

    // List //
    //
    QStringList typeNames;
    typeNames << Lane::parseLaneTypeBack(Lane::LT_NONE)
              << Lane::parseLaneTypeBack(Lane::LT_DRIVING)
              << Lane::parseLaneTypeBack(Lane::LT_STOP)
              << Lane::parseLaneTypeBack(Lane::LT_SHOULDER)
              << Lane::parseLaneTypeBack(Lane::LT_BIKING)
              << Lane::parseLaneTypeBack(Lane::LT_SIDEWALK)
              << Lane::parseLaneTypeBack(Lane::LT_BORDER)
              << Lane::parseLaneTypeBack(Lane::LT_RESTRICTED)
              << Lane::parseLaneTypeBack(Lane::LT_PARKING)
              << Lane::parseLaneTypeBack(Lane::LT_MWYENTRY)
              << Lane::parseLaneTypeBack(Lane::LT_MWYEXIT)
              << Lane::parseLaneTypeBack(Lane::LT_SPECIAL1)
              << Lane::parseLaneTypeBack(Lane::LT_SPECIAL2)
              << Lane::parseLaneTypeBack(Lane::LT_SPECIAL3);
    ui->typeBox->addItems(typeNames);

    /*heightGraph_ = new ProfileGraph(projectSettings->getProjectWidget(), projectSettings->getProjectData());
	heightGraph_->setParent(ui->widthGroup);
	ui->horizontalLayout_3->insertWidget(0,heightGraph_);
	//heightGraph_->getView()->setDragMode(QGraphicsView::ScrollHandDrag);
	//QGraphicsScene* pScene = new NoDeselectScene(this); 
    //heightGraph_->getView()->setScene(pScene);
	heightGraph_->getScene()->doDeselect(false);// we don't want to deselect ourselves if we click on the background, otherwise we delete ourselves--> chrash and it would not be practical anyway
	*/

    heightGraph_ = projectSettings->getProjectWidget()->getHeightGraph();

    laneEditor_ = dynamic_cast<LaneEditor *>(projectSettings->getProjectWidget()->getProjectEditor());
    if (!laneEditor_)
    {
        return; // another editor is active
    }

    roadSystemItemPolyGraph_ = new LaneWidthRoadSystemItem(heightGraph_, projectSettings->getProjectData()->getRoadSystem());
    heightGraph_->getScene()->addItem(roadSystemItemPolyGraph_);

    // Section Handle //
    //
    //insertWidthSectionHandle_ = new SectionHandle(roadSystemItemPolyGraph_);
    //insertWidthSectionHandle_->hide();
    roadSystemItemPolyGraph_->setSettings(this);
    roadSystemItemPolyGraph_->setAcceptHoverEvents(true);
    // Activate Road in ProfileGraph //
    //
    lswItem_ = new LaneSectionWidthItem(roadSystemItemPolyGraph_, lane_);
    //selectedElevationRoadItems_.insert(road, roadItem);

    // Fit View //
    //
    QRectF boundingBox = lswItem_->boundingRect();
    if (boundingBox.width() < 15.0)
    {
        boundingBox.setWidth(15.0);
    }
    if (boundingBox.height() < 10.0)
    {
        boundingBox.setHeight(10.0);
    }

    heightGraph_->getView()->fitInView(boundingBox);
    heightGraph_->getView()->zoomOut(Qt::Horizontal | Qt::Vertical);

    //ui->horizontalLayout_3->insertWidget(0,heightGraph_);
    //heightGraph_->show();
    // Initial Values //
    //
    updateId();
    updateType();
    updateLevel();
    updatePredecessor();
    updateSuccessor();
    updateWidth();

    // Done //
    //
    init_ = true;
}
void ParticleEmitterPressure::stepInternal(ParticleData& particles, PxReal dt, const PxVec3& externalAcceleration, PxReal maxParticleVelocity)
{
	PX_ASSERT(mNumX > 0 && mNumY > 0);
	
	mSimulationAcceleration = externalAcceleration;
	mSimulationMaxVelocity = maxParticleVelocity;
	
	PxU32 numEmittedParticles = 0;

	PxU32 maxParticlesPerStep = (PxU32)physx::shdfnd::floor(mMaxRate*dt);
	PxU32 maxParticles = PxMin(particles.maxParticles - particles.numParticles, maxParticlesPerStep);

	PxU32 siteNr = 0;	
	for(PxU32 y = 0; y != mNumY; y++)
	{
		PxReal offset = 0.0f;
		if (y%2) offset = mSpacingX * 0.5f;

		for(PxU32 x = 0; x != mNumX; x++)
		{
			if (isOutsideShape(x,y,offset))
				continue;

			SiteData& siteData = mSites[siteNr];

			//position noise
			PxVec3 posNoise;
			posNoise.x = randInRange(-mRandomPos.x, mRandomPos.x);
			posNoise.y = randInRange(-mRandomPos.y, mRandomPos.y);
			
			//special code for Z noise 
			if (!siteData.predecessor) 
				siteData.noiseZ = randInRange(-mRandomPos.z, mRandomPos.z);
			else
			{
				PxReal noiseZOffset = PxMin(mMaxZNoiseOffset, mRandomPos.z);
				siteData.noiseZ += randInRange(-noiseZOffset, noiseZOffset);
				siteData.noiseZ = PxClamp(siteData.noiseZ, mRandomPos.z, -mRandomPos.z);
			}

			posNoise.z = siteData.noiseZ;

			//set position
			PxVec3 sitePos = mBasePos + mAxisX*(offset+mSpacingX*x) + mAxisY*(mSpacingY*y) + mAxisZ*siteData.noiseZ;
			PxVec3 particlePos = sitePos + mAxisX*posNoise.x + mAxisY*posNoise.y;

			PxVec3 siteVel;
			computeSiteVelocity(siteVel, particlePos);

			if (siteData.predecessor)
			{
				predictPredecessorPos(siteData, dt);
			}
			else			{
				bool isSpawned = spawnParticle(particles, numEmittedParticles, maxParticles, particlePos, siteVel);
				if(isSpawned)
				{
					updatePredecessor(siteData, particlePos, siteVel);
				}
				else
				{
					siteData.predecessor = false;
					return;
				}
			}
			
			bool allSpawned = stepEmissionSite(siteData, particles, numEmittedParticles, maxParticles, sitePos, siteVel, dt);
			if(!allSpawned)
				return;

			siteNr++;
		}
	}
}