예제 #1
0
	bool LineAreaChecker::isPointInsideLineArea(const VC3 &point, 
		const VC3 &lineStart, const VC3 &lineEnd, float lineWidth)
	{
		VC3 projPos = lineEnd - lineStart;
		float projPosLenSq = projPos.GetSquareLength();
		VC3 projPosNorm = VC3(0,0,0);
		if (projPosLenSq > 0.00001f)
		{
			projPosNorm = projPos.GetNormalized();
		}

		VC3 chkpos = point - lineStart;
		float chkposLen = chkpos.GetLength();

		VC3 hitAndUnitDiff = chkpos - projPos;
		float hitAndUnitDiffLenSq = hitAndUnitDiff.GetSquareLength();

		float lineRadiusSq = (float)(lineWidth * lineWidth);

		if (hitAndUnitDiffLenSq < lineRadiusSq)
		{
			return true;
		}

		if (chkposLen * chkposLen < projPosLenSq)
		{
			VC3 pipedPos = projPosNorm * chkposLen;
			VC3 posdiff = chkpos - pipedPos;

			if (posdiff.GetSquareLength() < lineRadiusSq)
			{
				return true;
			}
		}

		return false;
	}
예제 #2
0
void GravityPointParticleForce::calcForce(Vector& force, const Vector& pos, const Vector& vel) {
	VC3 diff = pos - m_point;
	VC3 diffNorm = diff.GetNormalized();
	float diffLenSq = diff.GetSquareLength();
	if (fabsf(diffLenSq) < 0.01f)
	{
		force.x = 0.0f;
		force.y = 0.0f;
		force.z = 0.0f;
	} else {
		// realistic gravity (bad)
		//force = -diffNorm * 0.001f * m_gravity / diffLenSq;
		// unrealisic gravity (better)
		float diffLen = sqrtf(diffLenSq);
		force = -diffNorm * 0.001f * m_gravity / diffLen;
	}
}
void ParticlePhysics::physicsExplosion(const VC3 &explosionPosition, float forceFactor, float radius)
{
	// added support for radius parameter --jpk
	// TODO: this implementation does not take radius into account when calculating forces... (probably should)
	float radiusSq = radius * radius;

	for(PhysicsActorList::iterator it = data->physicsActorList.begin(); it != data->physicsActorList.end(); ++it)
	{
		PhysicsActor *actor = *it;
		if(!actor)
			continue;

		VC3 velocity;
		if(actor->actor)
			actor->actor->getMassCenterPosition(velocity);
		else
			velocity = actor->position;

		velocity -= explosionPosition;
		float len = velocity.GetSquareLength();
		if(len > radiusSq)
			continue;
		len = sqrtf(len);

		velocity.y *= 1.3f;
		velocity.y += 1.0f;

		if(len > 0.01f)
		{
			velocity /= len;

			if(len < 1.5f)
				len = 1.5f;

			velocity /= len;
		}
		else
			velocity.y = 1.f;

		velocity *= 7.5f * forceFactor;
		//actor->sleepCounter = 1;
		actor->force += velocity;
		actor->forceUpdate = true;
	}
}
예제 #4
0
	void ProgressBar::run(const VC3 &playerPosition, float playerAngle,
		bool continueKeyPressed, bool interruptKeyPressed)
	{
		if (isProgressing())
		{
			// has player moved/rotated too much to interrupt the progress
			bool playerInterrupted = interruptKeyPressed;

			if (!continueKeyPressed)
				playerInterrupted = true;

			VC3 moved = playerPosition - this->progressPosition;
			if (moved.GetSquareLength() > PROGRESSBAR_PLAYER_MOVE_TRESHOLD*PROGRESSBAR_PLAYER_MOVE_TRESHOLD)
				playerInterrupted = true;

			float rotAngle = util::AngleRotationCalculator::getFactoredRotationForAngles(playerAngle, this->progressAngle, 0.0f);
			if (fabs(rotAngle) > PROGRESSBAR_PLAYER_ROTATE_TRESHOLD)
				playerInterrupted = true;

			if (playerInterrupted)
			{
				progressing = false;
				triggerInterrupted = true;
				visibilityLeftCounter = PROGRESSBAR_VISIBLE_AFTER_STOP;
			}

			if (!isDone())
			{
				timeDone++;
			} else {
				progressing = false;
				visibilityLeftCounter = PROGRESSBAR_VISIBLE_AFTER_STOP;
			}
		} else {
			if (visibilityLeftCounter > 0)
			{
				visibilityLeftCounter--;
				if (visibilityLeftCounter == 0)
				{
					visible = false;
				}
			}
		}
	}
예제 #5
0
		void run(const VC3 &playerPosition)
		{
			// not enabled? then return
			if (!this->enabled)
				return;

			// still some manual delay set until next spawn? then return
			if (this->nextSpawnDelay > 0)
			{
				this->nextSpawnDelay--;
				return;
			}

			this->currentTime++;

			// is this a spawn interval tick? if not, then return
			if ((this->currentTime % this->spawnInterval) != 0)
				return;


			float closestDistSq = ALIENSPAWNER_MAX_SPAWN_RANGE * ALIENSPAWNER_MAX_SPAWN_RANGE;
			int closestId = -1;

#ifdef PROJECT_SURVIVOR
			
			// get random spawn point
			int temp_count = 0;
			int max_random = ALIENSPAWNER_MAX_SPAWNPOINTS;
			while( temp_count <= ALIENSPAWNER_MAX_SPAWNPOINTS && closestId == -1 )
			{
				temp_count++;
				int i = 0;
				if( i != 0 )
					i = game->gameRandom->nextInt() % max_random;

				if( spawnPoint[i].spawnerScriptId != 0 )
				{
					if( scriptEnabled[spawnPoint[i].spawnerScriptId] )
					{
						closestId = i;
					}
				}
				else
				{
					if( i < max_random )
						max_random = i;
				}
			}					
#else
			// TODO: more efficient datastructure
			for (int i = 0; i < ALIENSPAWNER_MAX_SPAWNPOINTS; i++)
			{
				if (spawnPoint[i].spawnerScriptId != 0)
				{
					if (scriptEnabled[spawnPoint[i].spawnerScriptId])
					{
						VC3 diffVec = spawnPoint[i].position - playerPosition;
						float distSq = diffVec.GetSquareLength();
						if (distSq < closestDistSq
							&& distSq > ALIENSPAWNER_MIN_SPAWN_RANGE * ALIENSPAWNER_MIN_SPAWN_RANGE)
						{
							closestId = i;
							closestDistSq = distSq;

							float d = sqrtf(closestDistSq) + ALIENSPAWNER_SPAWN_RANGE_RAND * float(game->gameRandom->nextInt() % 101) / 100.0f;
							closestDistSq = d * d;
						}
					}
				} else {
					break;
				}
			}
#endif
			if (closestId != -1)
			{
				game->gameScripting->runOtherScript(spawnerScripts[spawnPoint[closestId].spawnerScriptId].c_str(), "spawn", NULL, spawnPoint[closestId].position);
			}

		}
예제 #6
0
void PhysicsLib::updateVisualization(const VC3 &cameraPosition, float range, bool forceUpdate)
{
	bool visualizeCollisionShapes = data->featureMap[PhysicsLib::VISUALIZE_COLLISION_SHAPES];
	bool visualizeDynamic = data->featureMap[PhysicsLib::VISUALIZE_DYNAMIC];
	bool visualizeStatic = data->featureMap[PhysicsLib::VISUALIZE_STATIC];
	bool visualizeCollisionContacts = data->featureMap[PhysicsLib::VISUALIZE_COLLISION_CONTACTS];
	bool visualizeFluids = data->featureMap[PhysicsLib::VISUALIZE_FLUIDS];
	bool visualizeJoints = data->featureMap[PhysicsLib::VISUALIZE_JOINTS];
	bool visualizeCCD = data->featureMap[PhysicsLib::VISUALIZE_CCD];

	if (forceUpdate
		|| visualizeCollisionShapes
		|| visualizeDynamic
		|| visualizeStatic
		|| visualizeCollisionContacts
		|| visualizeFluids
		|| visualizeJoints
		|| visualizeCCD)
	{
		// (do the update)
	} else {
		// do not unnecessarily do this stuff!
		return;
	}

	float rangeSq = range * range;

	int actorAmount = data->scene->getNbActors();
	NxActor **actorArray = data->scene->getActors();

	if(visualizeCollisionShapes || visualizeStatic || visualizeCollisionContacts)
		data->sdk->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
	else
		data->sdk->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 0);

	if(visualizeDynamic)
		data->sdk->setParameter(NX_VISUALIZE_BODY_MASS_AXES, 1);
	else
		data->sdk->setParameter(NX_VISUALIZE_BODY_MASS_AXES, 0);

	data->sdk->setParameter(NX_VISUALIZE_CONTACT_NORMAL, visualizeCollisionContacts);
	data->sdk->setParameter(NX_VISUALIZE_CONTACT_FORCE, visualizeCollisionContacts);
	data->sdk->setParameter(NX_VISUALIZE_CONTACT_POINT, visualizeCollisionContacts);

	data->sdk->setParameter(NX_VISUALIZE_COLLISION_SKELETONS, visualizeCCD);	

	for(int i = 0; i < actorAmount; ++i)
	{
		NxActor *actor = actorArray[i];
		if(!actor)
			continue;

		NxVec3 nxpos = actor->getGlobalPosition();
		VC3 pos(nxpos.x, nxpos.y, nxpos.z);
		VC3 diff = (pos - cameraPosition);
		diff.y = 0; // ignore height

		bool inRange = false;		
		if (diff.GetSquareLength() < rangeSq)
			inRange = true;

		if(actor->isDynamic())
		{
			//if(visualizeDynamic && inRange)
			if(visualizeDynamic)
				actor->raiseBodyFlag(NX_BF_VISUALIZATION);
			else
				actor->clearBodyFlag(NX_BF_VISUALIZATION);
		}

		int shapeAmount = actor->getNbShapes();
		NxShape *const*shapes = actor->getShapes();

		while(shapeAmount--)
		{
			NxShape *shape = shapes[shapeAmount];

			if(actor->isDynamic())
			{
				//if(visualizeCollisionShapes && inRange)
				if(visualizeCollisionShapes)
					shape->setFlag(NX_SF_VISUALIZATION, true);
				else
					shape->setFlag(NX_SF_VISUALIZATION, false);
			}
			else
			{
				if(visualizeStatic && !shape->isHeightField() && inRange)
					shape->setFlag(NX_SF_VISUALIZATION, true);
				else
					shape->setFlag(NX_SF_VISUALIZATION, false);
			}
		}
	}
}
예제 #7
0
	void CameraScripting::process(util::ScriptProcess *sp, 
		int command, floatint intFloat, char *stringData, ScriptLastValueType *lastValue,
		GameScriptData *gsd, Game *game)
	{
		int intData = intFloat.i;
		switch(command)
		{
		case GS_CMD_CAMERAPOSITION:
			// TODO: proper handling of players in netgame
			gsd->position = game->gameUI->getGameCamera()->getPosition();

#ifdef LEGACY_FILES
			// ok
#else
			sp->warning("CameraScripting::process - cameraPosition deprecated, use actualCameraPosition instead.");
#endif
			break;

		case GS_CMD_LISTENERPOSITION:
			// TODO: proper handling of players in netgame
			
			// TODO: real listener position, this is just an approximation...
			// (that is, using camera position as the camera position for now)
			//gsd->position = game->gameUI->getGameCamera()->getPosition();
			gsd->position = game->gameUI->getListenerPosition();
			break;

		case GS_CMD_SETCAMERAPOSITIONNEAR:
			// TODO: proper handling of players in netgame
			game->gameUI->getGameCamera()->setPositionNear(gsd->position.x, gsd->position.z);
			break;

		case GS_CMD_SETCAMERAPOSITION:
			{
				// new: global offsetting via 2 pivots and rotation around the nwe "pivot".
				VC3 pos = gsd->position;

				pos -= Ani::getGlobalOffsetSource();
				float angle = Ani::getGlobalRotation();

				float tmpX = pos.x;
				pos.x = pos.x * cosf(UNIT_ANGLE_TO_RAD(angle)) + pos.z * sinf(UNIT_ANGLE_TO_RAD(angle));
				pos.z = pos.z * cosf(UNIT_ANGLE_TO_RAD(angle)) - tmpX * sinf(UNIT_ANGLE_TO_RAD(angle));

				pos += Ani::getGlobalOffsetTarget();

				game->gameUI->getGameCamera()->setPosition(pos);
				game->gameUI->getGameCamera()->doMovement(1);
			}
			break;

		case GS_CMD_rotateCameraAroundPosition:
			game->gameUI->getGameCamera()->rotateAroundPosition(gsd->position, *lastValue);
			game->gameUI->getGameCamera()->doMovement(1);
			break;

		case GS_CMD_SETCAMERAANGLE:
			// TODO: proper handling of players in netgame
			if (intData >= 0 || intData < 360)
			{
				float angle = (float)intData;
				angle += Ani::getGlobalRotation();
				if (angle < 0) angle += 360.0f;
				if (angle > 360.0f) angle -= 360.0f;

				game->gameUI->getGameCamera()->setAngleY(angle);
			} else {
				sp->error("GameScripting::process - setCameraAngle parameter bad.");
			}
			game->gameUI->getGameCamera()->doMovement(1);
			break;
		case GS_CMD_SETCAMERAANGLEFLOAT:
			{
				float floatData = intFloat.f;
				if (floatData >= 0.0f || floatData < 360.0f)
				{
					floatData -= Ani::getGlobalRotation();
					if (floatData < 0) floatData += 360.0f;
					if (floatData > 360.0f) floatData -= 360.0f;

					game->gameUI->getGameCamera()->setAngleY(floatData);
				} else {
					sp->error("GameScripting::process - setCameraAngleFloat parameter bad.");
				}
				game->gameUI->getGameCamera()->doMovement(1);
			}
			break;

		case GS_CMD_SETCAMERAANGLETOVALUE:
			game->gameUI->getGameCamera()->setAngleY((float)(90 - *lastValue));
			game->gameUI->getGameCamera()->doMovement(1);
			break;

		case GS_CMD_GETCAMERAANGLE:
			{
				*lastValue = (int)game->gameUI->getGameCamera()->getAngleY();
				*lastValue = 270 - *lastValue;
				if (*lastValue < 0) *lastValue += 360;
			}
			break;

		case GS_CMD_GETCAMERABETAANGLE:
			{
				*lastValue = (int)game->gameUI->getGameCamera()->getBetaAngle();
			}
			break;

		case GS_CMD_SETCAMERABETAANGLE:
			// TODO: proper handling of players in netgame
			if (intData >= -180 || intData < 180)
			{
				game->gameUI->getGameCamera()->setBetaAngle((float)intData);
			} else {
				sp->error("GameScripting::process - setCameraBetaAngle parameter bad.");
			}
			game->gameUI->getGameCamera()->doMovement(1);
			break;

		case GS_CMD_SETCAMERABETAANGLEFLOAT:
			{
				float floatData = intFloat.f;
				if (floatData >= -180 || floatData < 180)
				{
					game->gameUI->getGameCamera()->setBetaAngle(floatData);
				} else {
					sp->error("GameScripting::process - setCameraBetaAngleFloat parameter bad.");
				}
				game->gameUI->getGameCamera()->doMovement(1);
			}
			break;

		case GS_CMD_SETCAMERAZOOM:
			// TODO: proper handling of players in netgame
			game->gameUI->getGameCamera()->setZoom((float)intData);
			game->gameUI->getGameCamera()->doMovement(1);
			break;

		case GS_CMD_SETCAMERAFLOATZOOM:
			if (stringData != NULL)
			{
				game->gameUI->getGameCamera()->setZoom((float)atof(stringData));
				game->gameUI->getGameCamera()->doMovement(1);
			} else {
				sp->error("GameScripting::process - setCameraFloatZoom parameter missing.");
			}
			break;

		case GS_CMD_SELECTCAMERA:
			if (stringData != NULL)
			{
				// oh yeah! copy & paste programming ahead...
				if (strncmp(stringData, "cinematic1,", 11) == 0)
				{
					GameCamera *curcam = game->gameUI->getGameCamera();
					game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC1);
					int itime = str2int(&stringData[11]);
					if (itime != 0)
						game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime);
					else
						game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0);
					game->gameUI->getGameCamera()->doMovement(1);
					break;
				}
				if (strncmp(stringData, "cinematic2,", 11) == 0)
				{
					GameCamera *curcam = game->gameUI->getGameCamera();
					game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC2);
					int itime = str2int(&stringData[11]);
					if (itime != 0)
						game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime);
					else
						game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0);
					game->gameUI->getGameCamera()->doMovement(1);
					break;
				}
				if (strncmp(stringData, "normal,", 7) == 0)
				{
					GameCamera *curcam = game->gameUI->getGameCamera();
					game->gameUI->selectCamera(GAMEUI_CAMERA_NORMAL);
					int itime = str2int(&stringData[7]);
					if (itime != 0)
						game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime);
					else
						game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0);
					game->gameUI->getGameCamera()->doMovement(1);
					break;
				}
				if (strncmp(stringData, "tactical,", 9) == 0)
				{
					GameCamera *curcam = game->gameUI->getGameCamera();
					game->gameUI->selectCamera(GAMEUI_CAMERA_TACTICAL);
					int itime = str2int(&stringData[9]);
					if (itime != 0)
						game->gameUI->getGameCamera()->interpolateFrom(curcam, (float)itime);
					else
						game->gameUI->getGameCamera()->interpolateFrom(game->gameUI->getGameCamera(), 0);
					game->gameUI->getGameCamera()->doMovement(1);
					break;
				}
				sp->error("GameScripting::process - selectCamera parameter bad.");
			} else {
				sp->error("GameScripting::process - selectCamera parameter expected.");
			}
			break;
			
		case GS_CMD_SETCAMERAMOVEMENTON:
			// TODO: proper handling of players in netgame
			if (stringData != NULL)
			{
				GameCamera::CAMERA_MOVE moveNum = GameCamera::getCameraMoveByName(stringData);
				if (moveNum != GameCamera::CAMERA_MOVE_INVALID)
				{
					game->gameUI->getGameCamera()->setMovement(moveNum, true);
				} else {
					sp->error("GameScripting::process - setCameraMovementOn parameter invalid.");
				}
			} else {
				sp->error("GameScripting::process - setCameraMovementOn parameter missing.");
			}
			break;

		case GS_CMD_SETCAMERAMOVEMENTOFF:
			// TODO: proper handling of players in netgame
			if (stringData != NULL)
			{
				GameCamera::CAMERA_MOVE moveNum = GameCamera::getCameraMoveByName(stringData);
				if (moveNum != GameCamera::CAMERA_MOVE_INVALID)
				{
					game->gameUI->getGameCamera()->setMovement(moveNum, false);
				} else {
					sp->error("GameScripting::process - setCameraMovementOff parameter invalid.");
				}
			} else {
				sp->error("GameScripting::process - setCameraMovementOff parameter missing.");
			}
			break;

		case GS_CMD_SETCAMERAMODE:
			// TODO: proper handling of players in netgame
			if (stringData != NULL)
			{
				GameCamera::CAMERA_MODE modeNum = GameCamera::getCameraModeByName(stringData);
				if (modeNum != GameCamera::CAMERA_MODE_INVALID)
				{
					game->gameUI->getGameCamera()->setMode(modeNum);
					game->gameUI->getGameCamera()->doMovement(1);
				} else {
					sp->error("GameScripting::process - setCameraMode parameter invalid.");
				}
			} else {
				sp->error("GameScripting::process - setCameraMode parameter missing.");
			}
			break;

		case GS_CMD_SETCAMERATIMEFACTOR:
			if (stringData != NULL)
			{
				float timeFactor = (float)atof(stringData);
				if (timeFactor < 0.1f) timeFactor = 0.1f;
				if (timeFactor > 10.0f) timeFactor = 10.0f;
				game->gameUI->setCameraTimeFactor(timeFactor);
			} else {
				sp->error("GameScripting::process - setCameraTimeFactor parameter missing.");
			}
			break;

		case GS_CMD_ISCAMERAZOOMLESSTHAN:
			if (game->gameUI->getGameCamera()->getZoom() < (float)intData)
			{
				*lastValue = 1;
			} else {
				*lastValue = 0;
			}
			break;

		case GS_CMD_ISCAMERAZOOMGREATERTHAN:
			if (game->gameUI->getGameCamera()->getZoom() > (float)intData)
			{
				*lastValue = 1;
			} else {
				*lastValue = 0;
			}
			break;

		case GS_CMD_SETCAMERAFOV:
			game->gameUI->getGameCamera()->setFOV((float)intData);
			break;

		case GS_CMD_setCameraFOVFloat:
			{
				float floatData = intFloat.f;
				game->gameUI->getGameCamera()->setFOV(floatData);
			}
			break;

		case GS_CMD_COPYCAMERATO:
			if (stringData != NULL)
			{
				int curnum = game->gameUI->getCameraNumber();
				GameCamera *curcam = game->gameUI->getGameCamera();
				bool paramok = false;
				if (strcmp(stringData, "cinematic1") == 0)
				{
					game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC1);
					paramok = true;
				}
				if (strcmp(stringData, "cinematic2") == 0)
				{
					game->gameUI->selectCamera(GAMEUI_CAMERA_CINEMATIC2);
					paramok = true;
				}
				if (strcmp(stringData, "normal") == 0)
				{
					game->gameUI->selectCamera(GAMEUI_CAMERA_NORMAL);
					paramok = true;
				}
				if (strcmp(stringData, "tactical") == 0)
				{
					game->gameUI->selectCamera(GAMEUI_CAMERA_TACTICAL);
					paramok = true;
				}
				game->gameUI->getGameCamera()->copyFrom(curcam);
				game->gameUI->selectCamera(curnum);
				game->gameUI->getGameCamera()->doMovement(1);
				if (!paramok)
				{
					sp->error("GameScripting::process - selectCamera parameter bad.");
				}
			} else {
				sp->error("GameScripting::process - selectCamera parameter expected.");
			}
			break;

		case GS_CMD_setMapView:
			{

				bool showMap = stringData != NULL ? true : false;

				if(strcmp("stringData", "0") == 0)
					showMap = false;

				IStorm3D *storm = game->getGameUI()->getStorm3D();

				int dummy1 = 0, dummy2 = 0;

				if(showMap)
				{
					game->gameScripting->runSingleSimpleStringCommand( "hideGUI", "", &dummy1, &dummy2 );
					game->gameScripting->runSingleSimpleStringCommand( "hideAllUnits", "", &dummy1, &dummy2 );

					game->getEnvironmentalEffectManager()->enableSunlight();
					game->getEnvironmentalEffectManager()->setSunlightDirection ( VC3( 1,-1, 1) );
					game->getEnvironmentalEffectManager()->setSunlightColor ( COL(1,1,1) );

				} else
				{
					game->gameScripting->runSingleSimpleStringCommand( "showAllUnits", "", &dummy1, &dummy2 );
					game->gameScripting->runSingleSimpleStringCommand( "showGUI", "", &dummy1, &dummy2 );
					game->getEnvironmentalEffectManager()->disableSunlight();
				}

				if(showMap)
				{

					float scrAspect;
					if(storm->getRenderTarget(0))
						scrAspect = (float)storm->getRenderTarget(0)->getWidth() / storm->getRenderTarget(0)->getHeight();
					else
						scrAspect = (float)storm->GetScreenSize().width / storm->GetScreenSize().height;

					int areaX = -1, areaY = -1;
					// if stringData is in form NxN, where N is a number...
					if(  strlen(stringData) == 3 &&
						( stringData[0] >='1' && stringData[0] <='9' ) &&
						( stringData[1] == 'x' ) &&
						( stringData[2] >='1' && stringData[2] <='9' ) )
					{
						areaX = stringData[0] - '1';
						areaY = stringData[2] - '1';
					}

					game->gameUI->getGameCamera()->setForceMapView(true, areaX, areaY, 1024, 1024, scrAspect );

				}
				else
					game->gameUI->getGameCamera()->setForceMapView(false);

			}
			break;

		case GS_CMD_ROTATECAMERATOWARDUNIT:
			if (gsd->unit != NULL)
			{
				VC3 upos = gsd->unit->getPosition();
				VC3 campos = game->gameUI->getGameCamera()->getPosition();
				VC3 midpos(0,0,0);
				VC3 rotation(0,0,0);
				float scale;
				
				util::ObjectStretchingCalculator::calculateStretchValues(
					campos, upos, &midpos, &rotation, &scale);

				rotation.y = 270 - rotation.y;
				if (rotation.y < 0) rotation.y += 360;
				game->gameUI->getGameCamera()->setAngleY(rotation.y);
				game->gameUI->getGameCamera()->setBetaAngle(-rotation.x);
				game->gameUI->getGameCamera()->doMovement(1);

			} else {
				sp->warning("GameScripting::process - Attempt to rotateCameraTowardUnit for null unit.");
			} 					
			break;

		case GS_CMD_SETCAMERAHEIGHT:
			// TODO: proper handling of players in netgame
			game->gameUI->getGameCamera()->setHeight((float)intData);
			game->gameUI->getGameCamera()->doMovement(1);
			break;

		case GS_CMD_SHAKECAMERANEARPOSITIONSHORT:
			game->gameUI->getGameCamera()->setShakeEffect(intData, 500, gsd->position);
			break;

		case GS_CMD_SHAKECAMERANEARPOSITIONMEDIUM:
			game->gameUI->getGameCamera()->setShakeEffect(intData, 2500, gsd->position);
			break;

		case GS_CMD_SHAKECAMERANEARPOSITIONLONG:
			game->gameUI->getGameCamera()->setShakeEffect(intData, 8000, gsd->position);
			break;

		case GS_CMD_SETCAMERAINTERPOLATIONTYPE:
			if (stringData != NULL)
			{
				if (strcmp(stringData, "sinwave") == 0)
				{
					game->gameUI->getGameCamera()->setSmoothCameraInterpolation(true);
				}
				else if (strcmp(stringData, "linear") == 0)
				{
					game->gameUI->getGameCamera()->setSmoothCameraInterpolation(false);
				} 
				else 
				{
					sp->error("GameScripting::process - setCameraInterpolationType parameter bad.");
				}
			} else {
				// TODO: error
			}
			break;

		case GS_CMD_SETCAMERARANGE:
			if (intData > 0)
			{
				game->gameUI->setCameraRange((float)intData);
			} else {
				sp->error("GameScripting::process - setCameraRange parameter out of range (positive range value expected).");
			}
			break;

		case GS_CMD_GETCAMERARANGE:
			*lastValue = (int)game->gameUI->getCameraRange();
			break;

		case GS_CMD_RESTORECAMERARANGE:
			game->gameUI->restoreCameraRange();
			break;

		case GS_CMD_SETCAMERATARGETDISTANCE:
			if (game->inCombat)
			{
				game->gameUI->getGameCamera()->setTargetDistance((float)intData);
			}
			break;

		case GS_CMD_RESTORECAMERATARGETDISTANCE:
			if (game->inCombat)
			{
				game->gameUI->getGameCamera()->restoreDefaultTargetDistance();
			}
			break;

		case GS_CMD_setCameraAutozoomIndoor:
			if (game->inCombat)
			{
				float floatData = intFloat.f;
				ui::CameraAutozoomer::setAreaZoom(ui::CameraAutozoomer::CAMERA_AUTOZOOMER_AREA_INDOOR, floatData);
			}
			break;

		case GS_CMD_setCameraAutozoomOutdoor:
			if (game->inCombat)
			{
				float floatData = intFloat.f;
				ui::CameraAutozoomer::setAreaZoom(ui::CameraAutozoomer::CAMERA_AUTOZOOMER_AREA_OUTDOOR, floatData);
			}
			break;

		case GS_CMD_saveCameraAutozoom:
			if (game->inCombat)
			{
				ui::CameraAutozoomer::saveCheckpointState();
			}
			break;

		case GS_CMD_loadCameraAutozoom:
			if (game->inCombat)
			{
				ui::CameraAutozoomer::loadCheckpointState();
			}
			break;

		case GS_CMD_setCameraUpVector:
			if (stringData != NULL)
			{
				VC3 upvec = VC3(0,0,0);
				if (gs_tricoord_param(stringData, &upvec))
				{
					if (!(upvec.GetSquareLength() > 0.99f * 0.99f
						&& upvec.GetSquareLength() < 1.01f * 1.01f))
					{
						sp->warning("CameraScripting::process - setCameraUpVector parameter is not a normalized vector (will be normalized).");
					}
					if (!(upvec.GetSquareLength() > 0.001f * 0.001f))
					{
						sp->warning("CameraScripting::process - setCameraUpVector parameter is a zero length or invalid vector (falling back to default).");
						upvec = VC3(0,1,0);
					}
					upvec.Normalize();
					game->gameUI->getGameCamera()->setUpVector(upvec);
				} else {
					sp->error("CameraScripting::process - setCameraUpVector parameter invalid (expected vector in format x,y,z).");
				}
			} else {
				sp->error("CameraScripting::process - setCameraUpVector parameter missing (expected vector in format x,y,z).");
			}
			break;

		case GS_CMD_setCameraNearClipValue:
			{
				float floatData = intFloat.f;
				if( game && game->gameScene && game->gameScene->getStormScene() && game->gameScene->getStormScene()->GetCamera() )
					game->gameScene->getStormScene()->GetCamera()->SetZNear( floatData );
			}
			break;

		case GS_CMD_setCameraNearClipDefault:
			if( game && game->gameScene && game->gameScene->getStormScene() && game->gameScene->getStormScene()->GetCamera() )
				game->gameScene->getStormScene()->GetCamera()->SetZNearDefault();
			break;

		case GS_CMD_setCameraPositionOffsetXToFloatValue:
			if (game->inCombat)
			{
				VC3 tmp = game->gameUI->getGameCamera()->getPositionOffset();
				tmp.x = gsd->floatValue;
				game->gameUI->getGameCamera()->setPositionOffset(tmp);
			}
			break;

		case GS_CMD_setCameraPositionOffsetYToFloatValue:
			if (game->inCombat)
			{
				VC3 tmp = game->gameUI->getGameCamera()->getPositionOffset();
				tmp.y = gsd->floatValue;
				game->gameUI->getGameCamera()->setPositionOffset(tmp);
			}			
			break;

		case GS_CMD_setCameraPositionOffsetZToFloatValue:
			if (game->inCombat)
			{
				VC3 tmp = game->gameUI->getGameCamera()->getPositionOffset();
				tmp.z = gsd->floatValue;
				game->gameUI->getGameCamera()->setPositionOffset(tmp);
			}						
			break;

		case GS_CMD_setCameraTargetOffsetXToFloatValue:
			if (game->inCombat)
			{
				VC3 tmp = game->gameUI->getGameCamera()->getTargetOffset();
				tmp.x = gsd->floatValue;
				game->gameUI->getGameCamera()->setTargetOffset(tmp);
			}
			break;

		case GS_CMD_setCameraTargetOffsetYToFloatValue:
			if (game->inCombat)
			{
				VC3 tmp = game->gameUI->getGameCamera()->getTargetOffset();
				tmp.y = gsd->floatValue;
				game->gameUI->getGameCamera()->setTargetOffset(tmp);
			}			
			break;

		case GS_CMD_setCameraTargetOffsetZToFloatValue:
			if (game->inCombat)
			{
				VC3 tmp = game->gameUI->getGameCamera()->getTargetOffset();
				tmp.z = gsd->floatValue;
				game->gameUI->getGameCamera()->setTargetOffset(tmp);
			}						
			break;

		case GS_CMD_setCameraTargetOffsetAtPosition:
			if (game->inCombat)
			{
				VC3 targpos = game->gameUI->getGameCamera()->getTargetPosition();
				VC3 diff = gsd->position - targpos;
				game->gameUI->getGameCamera()->setTargetOffset(diff);
			}						
			break;

		case GS_CMD_setCameraPositionOffsetAtPosition:
			if (game->inCombat)
			{
				VC3 campos = game->gameUI->getGameCamera()->getPosition();
				VC3 diff = gsd->position - campos;
				game->gameUI->getGameCamera()->setPositionOffset(diff);
			}						
			break;

		case GS_CMD_disableDirectCameraControls:
			if (game->inCombat)
			{
				game->gameUI->getGameCamera()->setDirectControlsEnabled(false);
			}
			break;

		case GS_CMD_enableDirectCameraControls:
			if (game->inCombat)
			{
				game->gameUI->getGameCamera()->setDirectControlsEnabled(true);
			}						
			break;

		case GS_CMD_updateCamera:
			{
				game->gameUI->getGameCamera()->doMovement(0);
			}
			break;

		case GS_CMD_setCameraAreaType:
			{
				cameraAreaParameters.type = intData;
			}
			break;

		case GS_CMD_setCameraAreaCorner1ToPosition:
			{
				VC3 pos = gsd->position;
				cameraAreaParameters.corner[0] = pos;				
			}
			break;

		case GS_CMD_setCameraAreaCorner2ToPosition:
			{
				VC3 pos = gsd->position;
				cameraAreaParameters.corner[1] = pos;				
			}
			break;

		case GS_CMD_setCameraAreaCorner3ToPosition:
			{
				VC3 pos = gsd->position;
				cameraAreaParameters.corner[2] = pos;				
			}
			break;

		case GS_CMD_setCameraAreaCorner4ToPosition:
			{
				VC3 pos = gsd->position;
				cameraAreaParameters.corner[3] = pos;				
			}
			break;

		case GS_CMD_setCameraAreaFOV:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.FOV = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaAngle:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.angle = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaBetaAngle:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.betaAngle = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaBank:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.bank = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaOffsetX:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.offset.x = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaOffsetY:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.offset.y = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaOffsetZ:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.offset.z = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaFollowX:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.follow.x = floatData*0.01f;			
			}
			break;

		case GS_CMD_setCameraAreaFollowY:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.follow.y = floatData*0.01f;			
			}
			break;

		case GS_CMD_setCameraAreaFollowZ:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.follow.z = floatData*0.01f;			
			}
			break;

		case GS_CMD_setCameraAreaTargetToPosition:
			{
				VC3 pos = gsd->position;
				cameraAreaParameters.target = pos;				
			}
			break;

		case GS_CMD_setCameraAreaAnimation:
			{
				cameraAreaParameters.animation = stringData;				
			}
			break;

		case GS_CMD_setCameraAreaGroup:
			{
				cameraAreaParameters.group = intData;
			}
			break;

		case GS_CMD_addCameraArea:
			{
				game->getGameUI()->getCameraSystem()->addCameraArea(new CameraAreaStreet(cameraAreaParameters.name, cameraAreaParameters.group, cameraAreaParameters.collision, cameraAreaParameters.corner[0], cameraAreaParameters.corner[1], cameraAreaParameters.corner[2], cameraAreaParameters.corner[3], cameraAreaParameters.angle, cameraAreaParameters.betaAngle, cameraAreaParameters.bank, cameraAreaParameters.distance, cameraAreaParameters.FOV, cameraAreaParameters.target, cameraAreaParameters.offset, cameraAreaParameters.follow, cameraAreaParameters.animation));
//				initializeCameraAreaParameters();
			}
			break;

		case GS_CMD_setCameraAreaAngleToValue:
			{
				float floatData = (float)(*lastValue);
				cameraAreaParameters.angle = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaName:
			{
				cameraAreaParameters.name = stringData;				
			}
			break;

		case GS_CMD_setCameraAreaDistance:
			{
				float floatData = intFloat.f;
				cameraAreaParameters.distance = floatData;			
			}
			break;

		case GS_CMD_setCameraAreaCollision:
			{
				cameraAreaParameters.type = intData;
			}
			break;

		case GS_CMD_actualCameraPosition:
			gsd->position = game->gameUI->getGameCamera()->getActualInterpolatedPosition();
			break;

		case GS_CMD_moveCameraAngle:
			{
				float floatData = intFloat.f;
				game->getGameUI()->getCameraSystem()->moveCameraAngle(floatData);			
			}
			break;

		case GS_CMD_moveCameraBetaAngle:
			{
				float floatData = intFloat.f;
				game->getGameUI()->getCameraSystem()->moveCameraBetaAngle(floatData);			
			}
			break;

		case GS_CMD_moveCameraBank:
			{
				float floatData = intFloat.f;
				game->getGameUI()->getCameraSystem()->moveCameraBank(floatData);			
			}
			break;

		case GS_CMD_moveCameraDistance:
			{
				float floatData = intFloat.f;
				game->getGameUI()->getCameraSystem()->moveCameraDistance(floatData);			
			}
			break;

		case GS_CMD_moveCameraFOV:
			{
				float floatData = intFloat.f;
				game->getGameUI()->getCameraSystem()->moveCameraFOV(floatData);			
			}
			break;

		case GS_CMD_clearCameraAreas:
			{
				game->getGameUI()->getCameraSystem()->clearCameraAreas();			
			}
			break;

			
		case GS_CMD_isCameraSelected:
			if (stringData != NULL)
			{
				// oh yeah! copy & paste programming ahead...
				if (strncmp(stringData, "cinematic1", 10) == 0)
				{
					*lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_CINEMATIC1 ? 1 : 0;
					break;
				}
				if (strncmp(stringData, "cinematic2", 10) == 0)
				{
					*lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_CINEMATIC2 ? 1 : 0;
					break;
				}
				if (strncmp(stringData, "normal", 6) == 0)
				{
					*lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_NORMAL ? 1 : 0;
					break;
				}
				if (strncmp(stringData, "tactical", 8) == 0)
				{
					*lastValue = game->gameUI->getCameraNumber() == GAMEUI_CAMERA_TACTICAL ? 1 : 0;
					break;
				}
				*lastValue = 0;
				sp->error("GameScripting::process - isCameraSelected parameter bad.");
			} else {
				*lastValue = 0;
				sp->error("GameScripting::process - isCameraSelected parameter expected.");
			}
			break;

		default:
			sp->error("CameraScripting::process - Unknown command.");
			assert(0);
		}
	}
	void PhysicsContactEffectManager::physicsContact(const PhysicsContact &contact)
	{
		// WARNING: unsafe IGamePhysicsObject -> AbstractPhysicsObject casts!
		AbstractPhysicsObject *o1 = (AbstractPhysicsObject *)contact.obj1;
		AbstractPhysicsObject *o2 = (AbstractPhysicsObject *)contact.obj2;
		//assert(o1 != NULL);
		//assert(o2 != NULL);
		assert(contact.physicsObject1);
		assert(contact.physicsObject2);

#ifdef PHYSICS_PHYSX
		int sm1 = contact.physicsObject1->getIntData();
		int sm2 = contact.physicsObject2->getIntData();
		if(sm1 == SOUNDMATERIALPARSER_NO_SOUND_INDEX || sm2 == SOUNDMATERIALPARSER_NO_SOUND_INDEX)
		{
			return;
		}
#else
		if (o1->getSoundMaterial() == SOUNDMATERIALPARSER_NO_SOUND_INDEX
			|| o2->getSoundMaterial() == SOUNDMATERIALPARSER_NO_SOUND_INDEX)
		{
			return;
		}
#endif

		const util::SoundMaterialParser::SoundMaterialList &smlist = impl->soundmp->getSoundMaterials();
		for (int i = 0; i < 2; i++)
		{
			AbstractPhysicsObject *o = o1;
			if (i == 1) 
			{
				o = o2;
			}
#ifdef PHYSICS_PHYSX
			int smindex = sm1;
			if (i == 1) 
			{
				smindex = sm2;
			}
			assert(smindex >= 0 && smindex < (int)smlist.size());
#else
			int smindex = o->getSoundMaterial();
#endif

			bool makeEffect = false;
			VC3 effectpos;

			if(o)
			{
				if(contact.contactForceLen >= smlist[smindex].requiredEffectForce)
				{
					effectpos = contact.contactPosition;

					VC3 accel = o->getAcceleration();
					VC3 angaccel = o->getAngularAcceleration();

					if (accel.GetSquareLength() >= smlist[smindex].requiredEffectAcceleration * smlist[smindex].requiredEffectAcceleration
						|| angaccel.GetSquareLength() >= smlist[smindex].requiredEffectAngularAcceleration * smlist[smindex].requiredEffectAngularAcceleration)
					{
						makeEffect = true;
					}

				}
			}
			else
			{
				if(contact.contactForceLen >= smlist[smindex].requiredEffectForce)
				{
					makeEffect = true;
					effectpos = contact.contactPosition;
				}
			}

			if(makeEffect)
			{
				if (o)
				{
					if (impl->game->gameTimer < o->getLastEffectTick() + (smlist[smindex].effectMaxRate / GAME_TICK_MSEC))
					{
						makeEffect = false;
					} else {
						o->setLastEffectTick(impl->game->gameTimer);
					}
				}
			}

			if(makeEffect)
			{
				std::vector<std::string> effectlist = smlist[smindex].effects;
				if (effectlist.size() > 0)
				{
					float effectFactor = 1.0f;
					if (smlist[smindex].requiredEffectForce > 0.0f)
					{
						// 0% - 100% effect factor (100% required force - 200% required force)
						effectFactor = (contact.contactForceLen / smlist[smindex].requiredEffectForce) - 1.0f;
						if (effectFactor > 1.0f)
							effectFactor = 1.0f;

						assert(effectFactor >= 0.0f);
						assert(effectFactor <= 1.0f);
					}

					int effnum = (int)(effectFactor * (effectlist.size() - 1));
					if (effnum < 0) effnum = 0;
					if (effnum >= (int)effectlist.size()) effnum = (int)effectlist.size() - 1;
					const char *effname = effectlist[effnum].c_str();

					ui::VisualEffectManager *vefman = impl->game->gameUI->getVisualEffectManager();
					if (vefman != NULL)
					{
						assert(effname != NULL);

						// TODO: optimize this!!!
						int visualEffId = vefman->getVisualEffectIdByName(effname);

						if (visualEffId != -1)
						{
							// TODO: proper lifetime
							int lifetime = GAME_TICKS_PER_SECOND / 2;
							VisualEffect *vef = vefman->createNewManagedVisualEffect(visualEffId, lifetime, NULL, NULL,
								effectpos, effectpos, VC3(0,0,0), VC3(0,0,0), impl->game);

							if (vef == NULL)
							{
								Logger::getInstance()->error("PhysicsContactEffectManager::physicsContact - Failed to create visual effect.");
								Logger::getInstance()->debug(effname);
							}
						} else {
							Logger::getInstance()->error("PhysicsContactEffectManager::physicsContact - Given visual effect name not found.");
							Logger::getInstance()->debug(effname);
						}
					}
				}
			}
		}
	}
예제 #9
0
VC3 AlignUnits::getMovedPosition(const VC3 &position, IStorm3D_Camera &camera, bool *updated) const
{
	VC3 result = position;
	float factor = .005f;
	bool useGrid = false;

	if((GetKeyState(VK_SHIFT) & 0x80))
		factor = .2f;

	if((GetKeyState(VK_CONTROL) & 0x80) == 0)
		useGrid = true;

	factor *= getTimeDelta();

	VC3 y = camera.GetTarget() - camera.GetPosition();
	y.y = 0;
	y.Normalize();
	VC3 x = VC3(0.f, 1.f, 0.f).GetCrossWith(y);

#ifdef PROJECT_AOV
	x = VC3(1, 0, 0);
	y = VC3(0, 0, 1);
#endif

	y *= 40.f;
	x *= 40.f;

	// new: if ctrl was not down, use grid to move objects
	static int lastGridMoveTime = 0;
	long curTime = timeGetTime();

	if (useGrid)
	{
		if (fabsf(x.x) > fabsf(x.z))
		{
			x = VC3(x.x,0,0);
			y = VC3(0,0,y.z);
		} else {
			x = VC3(0,0,x.z);
			y = VC3(y.x,0,0);
		}
		if (x.GetSquareLength() > 0.0001f)
		{
			x.Normalize();
			x *= data->gridX;
		} else {
			x = VC3(0,0,0);
		}
		if (y.GetSquareLength() > 0.0001f)
		{
			y.Normalize();
			y *= data->gridY;
		} else {
			y = VC3(0,0,0);
		}

		if((GetKeyState(VK_SHIFT) & 0x80))
		{
//#ifdef PROJECT_AOV
//			x *= 10.0f; 
//			y *= 10.0f; 
//#else
			x *= 10.0f; 
			y *= 10.0f; 
//#endif
		}

		if (curTime < lastGridMoveTime + 100)
		{
			factor = 0.0f;
		} else {
			factor = 1.0f;
		}
	}
	// end of new grid thingy

	if(updated)
		*updated = false;

	if (factor != 0.0f)
	{
		if((GetKeyState(VK_UP) & 0x80))
		{
			result += y * factor;
			if(updated)
				*updated = true;
			lastGridMoveTime = curTime;
		}
		if((GetKeyState(VK_DOWN) & 0x80))
		{
			result -= y * factor;
			if(updated)
				*updated = true;
			lastGridMoveTime = curTime;
		}
		if((GetKeyState(VK_RIGHT) & 0x80))
		{
			result += x * factor;
			if(updated)
				*updated = true;
			lastGridMoveTime = curTime;
		}
		if((GetKeyState(VK_LEFT) & 0x80))
		{
			result -= x * factor;
			if(updated)
				*updated = true;
			lastGridMoveTime = curTime;
		}
	}

	return result;
}
	void PhysicsContactSoundManager::physicsContact(const PhysicsContact &contact)
	{
		// WARNING: unsafe IGamePhysicsObject -> AbstractPhysicsObject casts!
		AbstractPhysicsObject *o1 = (AbstractPhysicsObject *)contact.obj1;
		AbstractPhysicsObject *o2 = (AbstractPhysicsObject *)contact.obj2;
		//assert(o1 != NULL);
		//assert(o2 != NULL);
		assert(contact.physicsObject1);
		assert(contact.physicsObject2);

#ifdef PHYSICS_PHYSX
		int sm1 = contact.physicsObject1->getIntData();
		int sm2 = contact.physicsObject2->getIntData();

		// int claw_material = impl->soundmp->getMaterialIndexByName( "claw" );
		// int claw_body_material = impl->soundmp->getMaterialIndexByName( "claw_body" );

		if(sm1 == SOUNDMATERIALPARSER_NO_SOUND_INDEX || sm2 == SOUNDMATERIALPARSER_NO_SOUND_INDEX)
		{
			return;
		}
#else
		if (o1->getSoundMaterial() == SOUNDMATERIALPARSER_NO_SOUND_INDEX
			|| o2->getSoundMaterial() == SOUNDMATERIALPARSER_NO_SOUND_INDEX)
		{
			return;
		}
#endif

		const util::SoundMaterialParser::SoundMaterialList &smlist = impl->soundmp->getSoundMaterials();
		for (int i = 0; i < 2; i++)
		{
			AbstractPhysicsObject *o = o1;
			if (i == 1) 
			{
				o = o2;
			}
#ifdef PHYSICS_PHYSX
			int smindex = sm1;
			if (i == 1) 
			{
				smindex = sm2;
			}
			assert(smindex >= 0 && smindex < (int)smlist.size());
#else
			int smindex = o->getSoundMaterial();
#endif

			bool makeSound = false;
			VC3 soundpos;

			if(o)
			{
				/*
				// debug logging
				if( contact.contactForceLen > 1.0f && smlist[smindex].sounds.empty() == false )
				{
					VC3 accel = o->getAcceleration();
					VC3 angaccel = o->getAngularAcceleration();

					std::stringstream ss;
					ss << contact.contactForceLen << ", " << accel.GetLength() << ", " << angaccel.GetLength() << std::endl;
					Logger::getInstance()->error( ss.str().c_str() );
				}
				*/

				if(contact.contactForceLen >= smlist[smindex].requiredForce)
				{
					// TODO: use contact position instead of object's position.
					soundpos = o->getPosition();

					VC3 accel = o->getAcceleration();
					VC3 angaccel = o->getAngularAcceleration();

					

					

					if (accel.GetSquareLength() >= smlist[smindex].requiredAcceleration * smlist[smindex].requiredAcceleration
						|| angaccel.GetSquareLength() >= smlist[smindex].requiredAngularAcceleration * smlist[smindex].requiredAngularAcceleration)
					{
						makeSound = true;

						/*
						std::vector<std::string> soundlist = smlist[smindex].sounds;
						if (soundlist.size() > 0)
						{
							// TODO: some better pseudo-random logic here maybe...
							int sndnum = rand() % soundlist.size();
							const char *soundfile = soundlist[sndnum].c_str();

							float volumeFactor = 1.0f;
							if (smlist[smindex].requiredForce > 0.0f)
							{
								// 40% - 100% volume factor (100% required force - 200% required force)
								volumeFactor = (contact.contactForceLen / smlist[smindex].requiredForce) - 1.0f;
								volumeFactor *= 0.6f;
								volumeFactor += 0.4f;
								if (volumeFactor > 1.0f)
									volumeFactor = 1.0f;

								assert(volumeFactor >= 0.4f);
								assert(volumeFactor <= 1.0f);
							}

							impl->gameUI->playSoundEffect(soundfile, soundpos.x, soundpos.y, soundpos.z, 
								false, (int)(DEFAULT_SOUND_EFFECT_VOLUME * volumeFactor), DEFAULT_SOUND_RANGE, DEFAULT_SOUND_PRIORITY_NORMAL);
						}
						*/
					}

				}

				// not to repeat the effect too frequently
				if( o != NULL && makeSound && ( impl->gameUI->game->gameTimer - o->getLastEffectSoundTick() ) > ( 200 / GAME_TICK_MSEC ) )
				{
					o->setLastEffectSoundTick( impl->gameUI->game->gameTimer ); 
				}
				else
				{
					makeSound = false;
				}
			}
			else
			{
				if(contact.contactForceLen >= smlist[smindex].requiredForce)
				{
					makeSound = true;

#ifdef PHYSICS_PHYSX
					if(i == 0)
						contact.physicsObject1->getPosition(soundpos);
					else
						contact.physicsObject2->getPosition(soundpos);
#endif
				}
			}

			if(makeSound)
			{
				std::vector<std::string> soundlist = smlist[smindex].sounds;
				if (soundlist.size() > 0)
				{
					// TODO: some better pseudo-random logic here maybe...
					int sndnum = rand() % soundlist.size();
					// const char *soundfile = soundlist[sndnum].c_str();
					
					float volumeFactor = 1.0f;
					std::string soundfile = soundlist[sndnum];

					if (smlist[smindex].requiredForce > 0.0f)
					{
						// 100% required force - 500% required force
						float contactFactor = contact.contactForceLen / ( smlist[smindex].requiredForce * 5.0f );
						if( contactFactor > 1.0f ) 
							contactFactor = 1.0f;

						int sndnum = (int)((float)( soundlist.size() - 1 ) * contactFactor + 0.5f);
						sndnum += ( rand() % 3 ) - 1;

						if( sndnum < 0 ) 
							sndnum = 0;
						
						if( sndnum > (signed)( soundlist.size() - 1 ) ) 
							sndnum = (signed)( soundlist.size() - 1 );
						
						soundfile = soundlist[sndnum];
						/*
						// 40% - 100% volume factor (100% required force - 200% required force)
						volumeFactor = (contact.contactForceLen / smlist[smindex].requiredForce) - 1.0f;
						volumeFactor *= 0.6f;
						volumeFactor += 0.4f;
						if (volumeFactor > 1.0f)
							volumeFactor = 1.0f;

						assert(volumeFactor >= 0.4f);
						assert(volumeFactor <= 1.0f);
						*/
					}

					impl->gameUI->playSoundEffect(soundfile.c_str(), soundpos.x, soundpos.y, soundpos.z, 
						false, (int)(DEFAULT_SOUND_EFFECT_VOLUME * volumeFactor), DEFAULT_SOUND_RANGE, DEFAULT_SOUND_PRIORITY_NORMAL);
				}
			}
		}
	}
예제 #11
0
void ClawUnitActor::actDirectClawControls(Unit *unit)
{
	int weapTypeNum = 0;
	static int rotating = 0;
  static bool claw_near = true;

	UnitType *unitType = unit->getUnitType();

	if (rotating) rotating--;

	// For longer claw -> 5.5, 5.0

	const game::ControlSettings &controlSettings = game->getClawController()->getControlSettings();
	if(game->getClawController()->hasActor())
	{
		if(game->getClawController()->getTargetPosition(TARGET_ADVANCE_TICKS).GetRangeTo(unit->getPosition()) > controlSettings.animationSwitchFarPoseRange) 
		 claw_near = false;
    if(game->getClawController()->getTargetPosition(TARGET_ADVANCE_TICKS).GetRangeTo(unit->getPosition()) < controlSettings.animationSwitchNearPoseRange && !rotating) 
		 claw_near = true;
	}
	else
	{
    if(game->getClawController()->getTargetPosition(TARGET_ADVANCE_TICKS).GetRangeTo(unit->getPosition()) > controlSettings.animationSwitchFarPoseRange) 
		 claw_near = false;
    if(game->getClawController()->getTargetPosition(TARGET_ADVANCE_TICKS).GetRangeTo(unit->getPosition()) < controlSettings.animationSwitchNearPoseRange && !rotating) 
		 claw_near = true;
	}

	//bool sprint_key = game->gameUI->isLocalPlayerDirectControlOn(DIRECT_CTRL_SPRINT, unit);

	bool sprint = false;
	// TODO: ask the clawcontroller if we should sprint - if claw (= pad aiming/mouse) is not moving?
	// if sprint key is pressed, then force the claw not to move

static int thefoocounter = 0;

	if (!game->getClawController()->hasActor()
		&& !game->getClawController()->isClawMoving())
	{
		thefoocounter++;
		if (thefoocounter > 67)
		{
			sprint = true;
		}
	} else {
		thefoocounter = 0;
	}

// SPRINT DISABLED FOR NOW!
sprint = false;

	if (game->getClawController()->getPrepareAction() != ClawController::ActionNone)
	{
		weapTypeNum = 6;
	} else
	{
		if(sprint)
		{
			weapTypeNum = 5;
		} else {
			if(!claw_near)
			{
				if(game->getClawController()->hasActor())
				{
					weapTypeNum = 4;
				}
				else
				{
					weapTypeNum = 2;
				}
			}
			else
			{
				if(game->getClawController()->hasActor())
				{
					weapTypeNum = 3;
				}
				else
				{
					weapTypeNum = 1;
				}
			}
		}
	}

	bool weaponAnimationTypeChanged = false;

	// HACK: hack hack hack static!
	static int lastWeapTypeNum = -1;
	static int weaponChanging = 0;
	if (weapTypeNum != lastWeapTypeNum)
	{
		lastWeapTypeNum = weapTypeNum;
		weaponAnimationTypeChanged = true;
		weaponChanging = GAME_TICKS_PER_SECOND;
	}
  if (weaponChanging) weaponChanging--;
	int anim = ANIM_STAND_TYPE0 + weapTypeNum;

	// get the controls...
	bool up = game->gameUI->isLocalPlayerDirectControlOn(DIRECT_CTRL_FORWARD, unit);
	bool left = game->gameUI->isLocalPlayerDirectControlOn(DIRECT_CTRL_LEFT, unit);
	bool right = game->gameUI->isLocalPlayerDirectControlOn(DIRECT_CTRL_RIGHT, unit);
	bool down = game->gameUI->isLocalPlayerDirectControlOn(DIRECT_CTRL_BACKWARD, unit);

	// initial control coord system (controls in camera coord sys)
	VC3 upvec = VC3(0,1,0);
	VC3 controlFrontVec = VC3(0,0,-1);
	VC3 controlSideVec = controlFrontVec.GetCrossWith(upvec);

	// HACK: hack hack hack static!
	// (if we haven't moved, this is the last moved direction)
	static VC3 controlDirVec = VC3(1,0,0);
	bool doMovement = false;

	if (up || down || left || right)
	{
		VC3 newControlDirVec = VC3(0,0,0);
		if(!game::SimpleOptions::getBool(DH_OPT_B_CLAW_MOUSE))
		{
			int jx = 0;
			int jy = 0;
			Keyb3_ReadJoystick(0, &jx, &jy, 0, 0, 0, 0);
			//if(abs(jx) < 4)
			//	jx = 0;
			//if(abs(jy) < 4)
			//	jy = 0;

			newControlDirVec -= controlSideVec * float(jx);
			newControlDirVec -= controlFrontVec * float(jy);
		}
		else
		{
			if (up)
				newControlDirVec += controlFrontVec;
			if (down)
				newControlDirVec -= controlFrontVec;
			if (left)
				newControlDirVec += controlSideVec;
			if (right)
				newControlDirVec -= controlSideVec;
		}

		if (newControlDirVec.x != 0 || newControlDirVec.y != 0 || newControlDirVec.z != 0)
		{
			newControlDirVec.Normalize();
			controlDirVec = newControlDirVec;
			doMovement = true;
		}
	}

	// camera front/side vectors (height is flattened off)
	VC3 cameraFrontVec = game->gameUI->getGameCamera()->getTargetPosition() - game->gameUI->getGameCamera()->getPosition();
	cameraFrontVec.y = 0.0f;
	if (cameraFrontVec.GetSquareLength() < 0.0001f)
	{
		cameraFrontVec = controlFrontVec;
	}
	cameraFrontVec.Normalize();
	VC3 cameraSideVec = cameraFrontVec.GetCrossWith(upvec);

	// translate movement direction from camera coord system to global ocoord. system	
	// this is the actual movement direction vector.
	VC3 globalDirVec = (cameraFrontVec * controlDirVec.GetDotWith(controlFrontVec)) + (cameraSideVec * controlDirVec.GetDotWith(controlSideVec));

	VC3 velocity = unit->getVelocity();

	// move
	if (doMovement)
	{
		float accel = unitType->getAcceleration() / GAME_TICKS_PER_SECOND;
		velocity += globalDirVec * accel;

		float maxspeed = unitType->getMaxSpeed() / GAME_TICKS_PER_SECOND;
		if (sprint)
		{
			maxspeed = unitType->getSprintSpeed() / GAME_TICKS_PER_SECOND;
		}
		if (weapTypeNum == 6)  maxspeed = unitType->getSlowSpeed() / GAME_TICKS_PER_SECOND;
		float velTotalSq = velocity.GetSquareLength();
		if (velTotalSq > maxspeed*maxspeed)
		{
			velocity *= maxspeed / (float)sqrtf(velTotalSq);
		}

	}

	// friction...
	frictionVelocity(&velocity, unitType->getFriction() * GAME_TICK_MSEC);

	unit->setVelocity(velocity);

	// where do we move to?
	float moveAngle = util::PositionDirectionCalculator::calculateDirection(VC3(0,0,0), globalDirVec);
	float rotateToAngle = moveAngle;



	bool doStrafeLeftAnim = false;
	bool doStrafeRightAnim = false;
	bool doStrafeBackAnim = false;

	static float standAngle = 0;
	
	// where do we aim?
	float aimDestAngle = moveAngle;
	char *aimBone = unitType->getAimBone();
	if (aimBone != NULL)
	{
		VC3 unitPos = unit->getPosition();

		
/*		static VC3 aimPos = VC3(0,0,0);
		VC3 aimDiff = game->getClawController()->getClawPosition() - unitPos;
		if (aimDiff.GetSquareLength() > 2.0f * 2.0f)
		{
			aimPos = game->getClawController()->getClawPosition();
		}*/
		
//		VC3 aimPos = game->getClawController()->getClawPosition();
		VC3 aimPos = game->getClawController()->getTargetPosition(TARGET_ADVANCE_TICKS);

		aimDestAngle = util::PositionDirectionCalculator::calculateDirection(unitPos, aimPos);

		if (doMovement)
		{
			// --- THE HORRIBLE STRAFE LOGIC BEGINS ---
			float insideFwd = util::AngleRotationCalculator::getRotationForAngles(moveAngle, aimDestAngle, 45.0f);
			if (insideFwd == 0)
			{
				rotateToAngle = moveAngle;
			} else {
				float insideFwdDiag = util::AngleRotationCalculator::getRotationForAngles(moveAngle, aimDestAngle, 90.0f+45.0f);
				if (insideFwdDiag == 0)
				{
					if (insideFwd < 0)
					{
						rotateToAngle = moveAngle - 90.0f;
						if (rotateToAngle < 0.0f) rotateToAngle += 360.0f;
						doStrafeRightAnim = true;
					} else {
						rotateToAngle = moveAngle + 90.0f;
						if (rotateToAngle >= 360.0f) rotateToAngle -= 360.0f;
						doStrafeLeftAnim = true;
					}
				} else {
					rotateToAngle = moveAngle + 180.0f;
					if (rotateToAngle >= 360.0f) rotateToAngle -= 360.0f;
					doStrafeBackAnim = true;
				}
			}
			// --- THE HORRIBLE STRAFE LOGIC ENDS ---

		} else {
			if (weaponAnimationTypeChanged)
			{
				standAngle = aimDestAngle;
			}
			rotateToAngle = standAngle;

			// HACK: ...
			float maxTwist = 45.0f;
			if (weapTypeNum == 6)
			{
				maxTwist = 10.0f;
			}

			while (true)
			{
				float tooFarTwist = util::AngleRotationCalculator::getRotationForAngles(rotateToAngle, aimDestAngle, maxTwist+10);
				if (tooFarTwist > 0)
				{
					rotateToAngle += maxTwist*2;
					if (rotateToAngle >= 360.0f) rotateToAngle -= 360.0f;
				}
				else if (tooFarTwist < 0)
				{
					rotateToAngle -= maxTwist*2;
					if (rotateToAngle < 0.0f) rotateToAngle += 360.0f;
				} else {
					break;
				}
			}
		}
	}

	// When aiming, force rotation to dest.
	if (weapTypeNum == 6)
	{
		rotateToAngle = util::PositionDirectionCalculator::calculateDirection(
			unit->getPosition(),
			game->getClawController()->getTargetPosition(0));
	}

	if (doMovement)
	{
		standAngle = moveAngle;
		weaponChanging = GAME_TICKS_PER_SECOND / 4;
	}

	// rotate towards movement/strafe/whatever we just decided
	VC3 rot = unit->getRotation();

	float turnAccuracy = unitType->getTurningAccuracy();
	float turnSpeed = unitType->getTurning();
  // HACK, if unit is walking, slow it's turning speed down
	if (doMovement) {
		turnSpeed *= 0.7f;
	}

	float turnDir = util::AngleRotationCalculator::getRotationForAngles(rot.y, rotateToAngle, turnAccuracy);
//Logger::getInstance()->error(int2str((int)turnDir));
	rot.y += turnSpeed / GAME_TICKS_PER_SECOND * turnDir;
//	Logger::getInstance()->warning(int2str(rot.y));
//	Logger::getInstance()->warning(int2str(aimDestAngle));
	if (rotateToAngle - rot.y < -180) rotateToAngle +=360;
	if (rotateToAngle - rot.y > 180) rotateToAngle -=360;
	if (turnDir > 0 && rot.y > rotateToAngle)
	{
		rot.y = rotateToAngle;
	}
	if (turnDir < 0 && rot.y < rotateToAngle)
	{
		rot.y = rotateToAngle;
	}
	if (rot.y >= 360.0f) rot.y -= 360.0f;
	if (rot.y < 0.0f) rot.y += 360.0f;

	unit->setRotation(rot.x, rot.y, rot.z);

	// aim towards final aim direction...
	if (aimBone != NULL)
	{
		float aimAngle = aimDestAngle - rot.y;
		if (aimAngle < 0) aimAngle += 360.0f;

		unit->setLastBoneAimDirection(aimAngle);
		if (unit->getVisualObject() != NULL)
		{
			unit->getVisualObject()->rotateBone(aimBone, aimAngle, 0);
		}
	}

	// TODO: select correct animation
	if (doMovement)
	{
		if (doStrafeLeftAnim)
		{
			anim = ANIM_STRAFE_LEFT_TYPE0 + weapTypeNum;
		}
		else if (doStrafeRightAnim)
		{
			anim = ANIM_STRAFE_RIGHT_TYPE0 + weapTypeNum;
		}
		else if (doStrafeBackAnim)
		{
			anim = ANIM_RUN_BACKWARD_TYPE0 + weapTypeNum;
		} else {
			anim = ANIM_RUN_TYPE0 + weapTypeNum;
		}
	} else if (!weaponChanging) {

		// HACK: ... total hack!
		bool nappi = game->gameUI->getController(0)->isKeyDown(DH_CTRL_ATTACK_SECONDARY);

		if (turnDir < 0)
		{
			if (nappi && weapTypeNum == 4)
			{
				anim = ANIM_SPECIAL2;
			} else {
				anim = ANIM_TURN_LEFT_TYPE0 + weapTypeNum;
			}
			rotating = int(0.5*GAME_TICKS_PER_SECOND);
		}
		if (turnDir > 0)
		{
			if (nappi && weapTypeNum == 4)
			{
				anim = ANIM_SPECIAL1;
			} else {
				anim = ANIM_TURN_RIGHT_TYPE0 + weapTypeNum;
			}
			rotating = int(0.5*GAME_TICKS_PER_SECOND);
		}
	}

//Logger::getInstance()->error(int2str(anim));
	// apply the animation...
	if (unit->getAnimationSet() != NULL)
	{
		if (unit->getAnimationSet()->isAnimationInSet(anim))
		{
			unit->getAnimationSet()->animate(unit, anim);
			if (unit->getAnimationSet()->isAnimationStaticFactored(anim))
			{
				float fact = unit->getAnimationSet()->getAnimationStaticFactor(anim);
				ui::Animator::setAnimationSpeedFactor(unit, fact);
			} else {
				ui::Animator::setAnimationSpeedFactor(unit, 1.0f);
			}
		}	else {
			Logger::getInstance()->warning("ClawUnitActor::actDirectClawControls - Requested anim not found in animation set.");
			Logger::getInstance()->debug("anim id number follows:");
			Logger::getInstance()->debug(int2str(anim));
		}
	} else {
		Logger::getInstance()->warning("ClawUnitActor::actDirectClawControls - Unit has null animation set.");
	}
}
void ParticlePhysics::update()
{
	if(!data->physics)
		return;

	data->actorBaseList.clear();
	data->fluidBaseList.clear();

	// Update physics actors
	{
		for(PhysicsActorList::iterator it = data->physicsActorList.begin(); it != data->physicsActorList.end(); ++it)
		{
			PhysicsActor *actor = *it;
			if(!actor->actor)
				continue;

			/*
			if(actor->actor)
			{
				VC3 velocity;
				actor->actor->getVelocity(velocity);

				float len = velocity.GetLength();
				if(len > 1)
				{
					velocity /= len;
					actor->actor->setVelocity(velocity);
				}
			}
			*/

#ifndef PHYSX_GRAVITY
			if(actor->force.GetSquareLength() > 0.01f)
			{
				if(!actor->forceUpdate && ++actor->sleepCounter % 10 == 0)
				{
					VC3 currentPos;
					actor->getPosition(currentPos);
					VC3 currentAngular;
					actor->actor->getAngularVelocity(currentAngular);

					if(
						currentPos.GetSquareRangeTo(actor->lastPosition1) < 0.00001f
						||
						currentAngular.GetSquareRangeTo(actor->lastAngular1) < 0.00001f
						||
						currentPos.GetSquareRangeTo(actor->lastPosition2) < 0.00001f
						||
						currentAngular.GetSquareRangeTo(actor->lastAngular2) < 0.00001f)
					{
						if(!actor->actor->isSleeping())
							actor->actor->putToSleep();
					}

					actor->lastPosition2 = actor->lastPosition1;
					actor->lastAngular2 = actor->lastAngular1;

					actor->lastPosition1 = currentPos;
					actor->lastAngular1 = currentAngular;
				}
	
				if(actor->forceUpdate || !actor->actor->isSleeping())
					actor->actor->addVelocityChange(actor->force);

				actor->force = VC3();
			}
#else
			if(actor->forceUpdate)
			{
				VC3 base;
				actor->actor->getVelocity(base);

				VC3 newForce = base;
				newForce += actor->force;

				float len = newForce.GetSquareLength();
				if(len > MAX_VELOCITY * MAX_VELOCITY)
				{
					len = sqrtf(len);
					newForce /= len;

					newForce *= MAX_VELOCITY;
				}

				newForce -= base;
				actor->actor->addVelocityChange(newForce);

				{
					QUAT rot;
					rotateToward(VC3(0, 1.f, 0), actor->force.GetNormalized(), rot);

					VC3 test(rot.x, rot.y, rot.z);
					test.x += ((float)(rand() - RAND_MAX/2) / (float)RAND_MAX/2);
					test.z += ((float)(rand() - RAND_MAX/2) / (float)RAND_MAX/2);

					if(test.GetSquareLength() > 0.001f)
						test.Normalize();

					test *= 2.f;
					actor->actor->setAngularVelocity(test * 2.f);
				}

				actor->force = VC3();
			}
#endif

			actor->forceUpdate = false;
		}

		physics::resetFluidParticleCount();
		for(FluidActorList::iterator it = data->fluidActorList.begin(); it != data->fluidActorList.end(); ++it)
		{
			PhysicsFluid *fluid = *it;
			if(!fluid->fluid)
				continue;

			if(fluid->addAmount)
			{
				fluid->fluid->addParticles(&fluid->buffer[0], fluid->addAmount);
				fluid->buffer.clear();
				fluid->addAmount = 0;
			}

			fluid->fluid->setAcceleration(fluid->acceleration);
			fluid->fluid->update();
			//fluid->renderFlag = false;
		}
	}

	/*
	// Meshes
	{
		for(MeshList::iterator it = data->meshList.begin(); it != data->meshList.end(); ++it)
		{
			MeshData &convex = *it;
			boost::shared_ptr<PhysicsMesh> mesh = convex.mesh.lock();
			if(!mesh)
				continue;

			filesystem::FB_FILE *fp = filesystem::fb_fopen(convex.filename.c_str(), "rb");
			if(!fp)
			{
				physics::Cooker cooker;
				cooker.cookApproxConvex(convex.filename.c_str(), convex.object);
			}
			else
				filesystem::fb_fclose(fp);

			mesh->mesh = data->physics->createConvexMesh(convex.filename.c_str());
		}

		data->meshList.clear();
	}
	*/

	// Actors
	{
		/*
		if(actorList.size() + physicsActorList.size() > MAX_ACTOR_AMOUNT)
		{
			boost::shared_ptr<PhysicsActor> nullActor;
			return nullActor;
		}
		*/

		bool sort = false;

		int createAmount = data->actorList.size();
		if(createAmount > data->maxParticleSpawnAmount)
		{
			createAmount = data->maxParticleSpawnAmount;
			sort = true;
		}
		if(createAmount + data->createdActors > data->maxParticleAmount)
		{
			sort = true;
			createAmount = data->maxParticleAmount - data->createdActors;
		}

		if(sort)
			std::sort(data->actorList.begin(), data->actorList.end(), ActorListSorter());

		// For collision test
#ifdef PHYSX_SPAWN_TEST
		std::vector<BoxStruct> previousBoxes;
#endif

		int index = 0;
		for(ActorList::iterator it = data->actorList.begin(); it != data->actorList.end(); ++it)
		{
			ActorData &convex = *it;
			if(convex.createDelayCounter++ >= MAX_WAIT_FOR_CREATE)
				continue;

			boost::shared_ptr<PhysicsActor> actor = convex.actor.lock();
			if(!actor)
				continue;

			boost::shared_ptr<PhysicsMesh> mesh = convex.mesh.lock();
			if(!mesh)
				continue;

			/*
			//VC3 boxCenter = mesh->localPosition + actor->position;
			VC3 boxCenter = mesh->localPosition;
			actor->rotation.RotateVector(boxCenter);
			boxCenter += actor->position;

			// Test to previous tick physics
			if(data->physics->checkOverlapOBB(boxCenter, mesh->size, actor->rotation, physics::PhysicsLib::CollisionStatic))
			{
				convex.actor.reset();
				convex.mesh.reset();
				continue;
			}
			*/

#ifdef PHYSX_SPAWN_TEST
			BoxStruct currentBox;
			currentBox.center.set(boxCenter.x, boxCenter.y, boxCenter.z);
			currentBox.extents.set(mesh->size.x, mesh->size.y, mesh->size.z);
			QUAT r = actor->rotation.GetInverse();
			NxQuat quat;
			quat.setXYZW(r.x, r.y, r.z, r.w);
			currentBox.rotation.fromQuat(quat);

			// Test to previous tick physics
			if(data->physics->checkOverlapOBB(boxCenter, mesh->size, actor->rotation))
				continue;

			bool hit = false;
			for(unsigned int i = 0; i < previousBoxes.size(); ++i)
			{
				const BoxStruct &b = previousBoxes[i];
				if(NxBoxBoxIntersect(currentBox.extents, currentBox.center, currentBox.rotation, b.extents, b.center, b.rotation, true))
				{
					hit = true;
					break;
				}
			}

			if(hit)
				continue;
#endif

			// Don't create too many particles
			if(index++ >= createAmount)
				break;

			/*
			boost::shared_ptr<physics::ConvexActor> convexActor = data->physics->createConvexActor(mesh->mesh, actor->position);
			if(convexActor)
			{
				convexActor->setRotation(actor->rotation);
				convexActor->setVelocity(convex.velocity);
				convexActor->setAngularVelocity(convex.angularVelocity);
				convexActor->setMass(convex.mass);
				convexActor->setCollisionGroup(2);
				//convexActor->enableFeature(physics::ActorBase::DISABLE_GRAVITY, true);
				actor->actor = convexActor;
			}
			*/

			boost::shared_ptr<physics::BoxActor> boxActor = data->physics->createBoxActor(mesh->size, actor->position, mesh->localPosition);
			if(boxActor)
			{
				++data->createdActors;

				boxActor->setRotation(actor->rotation);
				boxActor->setVelocity(convex.velocity);
				boxActor->setAngularVelocity(convex.angularVelocity);
				boxActor->setMass(convex.mass);
				boxActor->setCollisionGroup(convex.collisionGroup);

#ifndef PHYSX_GRAVITY
				boxActor->enableFeature(physics::ActorBase::DISABLE_GRAVITY, true);
#endif

				boxActor->setIntData(convex.soundGroup);
				actor->actor = boxActor;

#ifdef PHYSX_SPAWN_TEST
				previousBoxes.push_back(currentBox);
#endif
			}
		}

		int size = data->actorList.size();
		for(int i = index; i < size; ++i)
		{
			data->actorList[i].createDelayCounter++;
		}

		if(index < size)
		{
			for(int i = 0; i < size - index; ++i)
				data->actorList[i] = data->actorList[i + index];

			data->actorList.resize(size - index);
		}
		else 
			data->actorList.clear();
	}

	// Fluids
	{
		for(FluidList::iterator it = data->fluidList.begin(); it != data->fluidList.end(); ++it)
		{
			FluidData &fluidData = *it;
			boost::shared_ptr<PhysicsFluid> fluid = fluidData.fluid.lock();
			if(!fluid)
				continue;

			boost::shared_ptr<physics::Fluid> fluidActor = data->physics->createFluid(physics::PhysicsLib::FluidType(fluidData.type), fluidData.maxParticles, fluidData.fluidStaticRestitution, fluidData.fluidStaticAdhesion, fluidData.fluidDynamicRestitution, fluidData.fluidDynamicAdhesion, fluidData.fluidDamping, fluidData.fluidStiffness, fluidData.fluidViscosity, fluidData.fluidKernelRadiusMultiplier, fluidData.fluidRestParticlesPerMeter, fluidData.fluidRestDensity, fluidData.fluidMotionLimit, fluidData.fluidPacketSizeMultiplier, fluidData.collisionGroup);
			fluid->fluid = fluidActor;
			fluid->lib = data;
		}

		data->fluidList.clear();
	}
}
	void DebugTerrainObjectVisualizer::visualizeTerrainObject(game::Game *game, UnifiedHandle terrainObject, const VC3 &cameraPosition, DebugTerrainObjectVisFlags visFlags)
	{
		char textbuf[128];

		assert(VALIDATE_UNIFIED_HANDLE_BITS(terrainObject));

		if (!game->unifiedHandleManager->doesObjectExist(terrainObject))
		{
			return;
		}

		VC3 cullpos = game->unifiedHandleManager->getObjectPosition(terrainObject);
		VC3 distToCamVec = cullpos - cameraPosition;
		// 2D RANGE
		distToCamVec.y = 0;
		float distToCamSq = distToCamVec.GetSquareLength();
		if (distToCamSq < (DEBUGTERRAINOBJECTVISUALIZER_MAX_DIST * DEBUGTERRAINOBJECTVISUALIZER_MAX_DIST))
		{
			// ok
		} else {
			return;
		}

		std::string fname = game->gameUI->getTerrain()->getTypeFilenameByUnifiedHandle(terrainObject);
		std::string fnamecut;
		for (int i = (int)fname.length() - 1; i >= 0; i--)
		{
			if (fname[i] == '\\')
			{
				fname[i] = '/';
			}
			if (fname[i] == '/')
			{
				if (fnamecut.empty())
				{
					fnamecut = fname.substr(i + 1, fname.length() - (i + 1));
				}
			}
		}

		const char *totypename = game::SimpleOptions::getString(DH_OPT_S_DEBUG_VISUALIZE_TERRAINOBJECTS_OF_NAME);
		if (totypename != NULL
			&& totypename[0] != '\0')
		{
			if (strstr(fname.c_str(), totypename) != NULL)
			{
				// ok
			} else {
				return;
			}
		}

		COL col = COL(0.5f,0.5f,1.0f);

		if (visFlags & DEBUGTERRAINOBJECTVISUALIZER_FLAG_SELECTED)
		{
			// ok with that color?
		} else {
			col.r = col.r / 2.0f;
			col.g = col.g / 2.0f;
			col.b = col.b / 2.0f;
		}

		/*
		VC3 pos = game->unifiedHandleManager->getObjectPosition(terrainObject);
		pos.y += 0.03f;

		VC3 sizes = VC3(1.00f, 1.00f, 1.00f);

		VC3 c1 = VC3(pos.x - sizes.x, pos.y + sizes.y, pos.z - sizes.z);
		VC3 c2 = VC3(pos.x + sizes.x, pos.y + sizes.y, pos.z - sizes.z);
		VC3 c3 = VC3(pos.x + sizes.x, pos.y + sizes.y, pos.z + sizes.z);
		VC3 c4 = VC3(pos.x - sizes.x, pos.y + sizes.y, pos.z + sizes.z);
		VC3 cb1 = VC3(pos.x - sizes.x, pos.y - sizes.y, pos.z - sizes.z);
		VC3 cb2 = VC3(pos.x + sizes.x, pos.y - sizes.y, pos.z - sizes.z);
		VC3 cb3 = VC3(pos.x + sizes.x, pos.y - sizes.y, pos.z + sizes.z);
		VC3 cb4 = VC3(pos.x - sizes.x, pos.y - sizes.y, pos.z + sizes.z);
		*/

		OOBB oobb = game->gameUI->getTerrain()->getOOBB(terrainObject);

		VC3 pos = oobb.center;

		VC3 c1 = pos - (oobb.axes[0] * oobb.extents.x) + (oobb.axes[1] * oobb.extents.y) - (oobb.axes[2] * oobb.extents.z);
		VC3 c2 = pos + (oobb.axes[0] * oobb.extents.x) + (oobb.axes[1] * oobb.extents.y) - (oobb.axes[2] * oobb.extents.z);
		VC3 c3 = pos + (oobb.axes[0] * oobb.extents.x) + (oobb.axes[1] * oobb.extents.y) + (oobb.axes[2] * oobb.extents.z);
		VC3 c4 = pos - (oobb.axes[0] * oobb.extents.x) + (oobb.axes[1] * oobb.extents.y) + (oobb.axes[2] * oobb.extents.z);
		VC3 cb1 = pos - (oobb.axes[0] * oobb.extents.x) - (oobb.axes[1] * oobb.extents.y) - (oobb.axes[2] * oobb.extents.z);
		VC3 cb2 = pos + (oobb.axes[0] * oobb.extents.x) - (oobb.axes[1] * oobb.extents.y) - (oobb.axes[2] * oobb.extents.z);
		VC3 cb3 = pos + (oobb.axes[0] * oobb.extents.x) - (oobb.axes[1] * oobb.extents.y) + (oobb.axes[2] * oobb.extents.z);
		VC3 cb4 = pos - (oobb.axes[0] * oobb.extents.x) - (oobb.axes[1] * oobb.extents.y) + (oobb.axes[2] * oobb.extents.z);

		/*
		VC3 pos = game->unifiedHandleManager->getObjectPosition(terrainObject);
		OOBB oobb = game->gameUI->getTerrain()->getOOBB(terrainObject);

		pos = oobb.center;

		VC3 sizes = oobb.extents;

		VC3 c1 = VC3(pos.x - sizes.x, pos.y + sizes.y, pos.z - sizes.z);
		VC3 c2 = VC3(pos.x + sizes.x, pos.y + sizes.y, pos.z - sizes.z);
		VC3 c3 = VC3(pos.x + sizes.x, pos.y + sizes.y, pos.z + sizes.z);
		VC3 c4 = VC3(pos.x - sizes.x, pos.y + sizes.y, pos.z + sizes.z);
		VC3 cb1 = VC3(pos.x - sizes.x, pos.y - sizes.y, pos.z - sizes.z);
		VC3 cb2 = VC3(pos.x + sizes.x, pos.y - sizes.y, pos.z - sizes.z);
		VC3 cb3 = VC3(pos.x + sizes.x, pos.y - sizes.y, pos.z + sizes.z);
		VC3 cb4 = VC3(pos.x - sizes.x, pos.y - sizes.y, pos.z + sizes.z);
		*/

		disposable_scene->AddLine(c1, c2, col);
		disposable_scene->AddLine(c2, c3, col);
		disposable_scene->AddLine(c3, c4, col);
		disposable_scene->AddLine(c4, c1, col);
		disposable_scene->AddLine(cb1, cb2, col);
		disposable_scene->AddLine(cb2, cb3, col);
		disposable_scene->AddLine(cb3, cb4, col);
		disposable_scene->AddLine(cb4, cb1, col);
		disposable_scene->AddLine(c1, cb1, col);
		disposable_scene->AddLine(c2, cb2, col);
		disposable_scene->AddLine(c3, cb3, col);
		disposable_scene->AddLine(c4, cb4, col);
		disposable_scene->AddLine(c4, cb4, col);

		int textoffy = 0;

		if (game::SimpleOptions::getBool(DH_OPT_B_DEBUG_VISUALIZE_TERRAINOBJECTS_EXTENDED)
			&& distToCamSq < (DEBUGTERRAINOBJECTVISUALIZER_EXTENDED_MAX_DIST * DEBUGTERRAINOBJECTVISUALIZER_EXTENDED_MAX_DIST))
		{
			sprintf(textbuf, "uh: %d", terrainObject);
			DebugVisualizerTextUtil::renderText(pos, 0, textoffy, textbuf);
			textoffy += 16;

			sprintf(textbuf, "filename: %s", fnamecut.c_str());
			DebugVisualizerTextUtil::renderText(pos, 0, textoffy, textbuf);
			textoffy += 16;
		}

	}