void init(IStorm3D* s3d, IStorm3D_Scene* scene) {
				
		GenParticleSystem::init(s3d, scene);
		
		std::string fileName;
		m_pb->getValue(PB_POINT_ARRAY_MODEL_FILE, fileName);
		if(fileName.empty())
			return;
		
		IStorm3D_Model* model = s3d->CreateNewModel();
		if(model->LoadS3D(fileName.c_str())) 
		{
			Iterator<IStorm3D_Model_Object*>* obj = model->ITObject->Begin();
			IStorm3D_Mesh* mesh = obj->GetCurrent()->GetMesh();
			if(mesh) {
				boost::shared_ptr<ParticleMesh> pm(new ParticleMesh());
				pm->verts.resize(mesh->GetVertexCount());
				pm->normals.resize(mesh->GetVertexCount());
				Storm3D_Vertex* v = mesh->GetVertexBuffer();
				for(int i = 0; i < mesh->GetVertexCount(); i++) {
					pm->verts[i] = v[i].position;
					pm->normals[i] = v[i].normal;
				}
				m_mesh.swap(pm);
			}
			delete obj;
		}
		delete model;

	}
void PointArrayParticleSystem::init(IStorm3D* s3d, IStorm3D_Scene* scene)
{
    defaultInit(s3d, scene, *m_eds);

    std::string fileName = m_eds->modelFile;
    if(fileName.empty())
        return;

    Matrix sm;
    Matrix rm;
    QUAT q;
    q.MakeFromAngles(m_eds->rotation.x, m_eds->rotation.y, m_eds->rotation.z);
    rm.CreateRotationMatrix(q);
    sm.CreateScaleMatrix(m_eds->scale);
    sm.Multiply(rm);
    IStorm3D_Model* model = s3d->CreateNewModel();
    assert(model != NULL);

    if(model->LoadS3D(fileName.c_str()))
    {
        Iterator<IStorm3D_Model_Object*>* obj = model->ITObject->Begin();
        assert(obj != NULL);

        boost::shared_ptr<PointArray> pm(new PointArray());
        for(; !obj->IsEnd(); obj->Next())
        {
            IStorm3D_Mesh* mesh = obj->GetCurrent()->GetMesh();
            VC3 opos = obj->GetCurrent()->GetPosition();

            if(mesh)
            {
                int base = pm->verts.size();
                pm->verts.resize(base + mesh->GetVertexCount());
                pm->normals.resize(base + mesh->GetVertexCount());

                Storm3D_Vertex *v = mesh->GetVertexBuffer();
                for(int i = 0; i < mesh->GetVertexCount(); i++)
                {
                    Vector pos = v[i].position + opos;
                    Vector nor = v[i].normal;
                    sm.TransformVector(pos);
                    rm.RotateVector(nor);

                    pm->verts[base + i] = pos;
                    pm->normals[base + i] = nor;
                }
            }
        }

        m_parray.swap(pm);
        if(m_eds->firstVertex < 0)
            m_eds->firstVertex = 0;
        if(m_eds->lastVertex >= (int)m_parray->verts.size())
            m_eds->lastVertex = m_parray->verts.size()-1;

        delete obj;
    }
    delete model;
}
Example #3
0
  void Decoration::parseBoundingQuadSize(const char* modelFileName) 
  {
	 boundingQuadSizeX = 0.0f;
	 boundingQuadSizeY = 0.0f;

	  if(visualObject)
	  {
			IStorm3D_Model *model = visualObject->getStormModel();
			if(model)
			{
				const AABB &aabb = model->GetBoundingBox();

				boundingQuadSizeX = (aabb.mmax.x - aabb.mmin.x) * .5f;
				boundingQuadSizeY = (aabb.mmax.z - aabb.mmin.z) * .5f;
			}
	  }
	  /*
	  // damn this would be ALOT easier with stl :)
	  char xSize[16];
	  char ySize[16];
	  memset(xSize, 0, sizeof(xSize));
	  memset(ySize, 0, sizeof(ySize));
	  int len = strlen(modelFileName) - 1;
	  int i;
	  for(i = len; i > 0; i--) {
		if(modelFileName[i] == '_')
			break;
	  }
	  if(i == 0) {
		 // decoration model file name doesn't have boundaries
		 boundingQuadSizeX = 0.0f;
		 boundingQuadSizeY = 0.0f;
		 return;
	  }
	  i++; // skip _
	  int a = 0;
	  for(i; i < len; i++) {
		if((modelFileName[i] == 'x') || (modelFileName[i] == 'X'))
			break;
		xSize[a++] = modelFileName[i];
	  }
	  if(i == len) {
		 // decoration model file name doesn't have Y boundaries
		 boundingQuadSizeX = 0.0f;
		 boundingQuadSizeY = 0.0f;
		 return;	  
	  }
	  i++; // skip x
	  a = 0;
	  for(i; i < len; i++) {
		if((modelFileName[i] == '.'))
			break;
		ySize[a++] = modelFileName[i];
	  }
	  boundingQuadSizeX = static_cast<float>(atof(xSize));
	  boundingQuadSizeY = static_cast<float>(atof(ySize));
	  */
  }
void TargetDisplayWindowUpdator::risingMessage( game::Unit* unit, const std::string& text, int style )
{
	if( unit == NULL )
	{
		Logger::getInstance()->error( "TargetDisplayWindowUpdator::risingMessage() - could not create a message for a null unit" );
		return;
	}

	std::list< Unit* >::iterator i = std::find( risingMessages.begin(), risingMessages.end(), unit );
	if( i == risingMessages.end() )
	{
		float updateDistance = updateItemsInsideDistance * updateItemsInsideDistance;

		float distance = calculateDistance( unit->getPosition(), game );
		if( distance < updateDistance )
		{
			if(unit && unit->getVisualObject() && unit->getVisualObject()->getStormModel())
			{
				
				IStorm3D_Model *m = unit->getVisualObject()->getStormModel();
				Rect rect = getScreenArea(m->GetBoundingBox(), game);

				// hack: allow rising messages on units with highlight
				void *p = ((char *)unit) + 1;
				if(window->setRisingText( p, rect.x, rect.y, rect.w, rect.h, ( distance / updateDistance ), style ) )
				{
					window->setText(p, text );	
				}

				risingMessages.push_back( unit );
			}
		}

	}
	else
	{
		// TODO log a warning message
		// Logger::getInstance()->Warning( );
	}
}
  void BuildingAdder::createVisualForBuilding(Game *game, Building *building)
  {
    // another quick haxor

    // maybe should check that the visual does not already exist

    //VisualObjectModel *vom = new VisualObjectModel(building->getModelFilename());
		VisualObjectModel *vom = game->visualObjectModelStorage->getVisualObjectModel(building->getModelFilename());

    VisualObject *vo = vom->getNewObjectInstance();
    building->setVisualObject(vo);
    vo->setInScene(true);
    vo->setDataObject(building);

		// disable collision to "firethrough" collision layer...
		IStorm3D_Model *model = vo->getStormModel();
		if(model)
		{
			const VC3 &sunDir = game->getGameUI()->getTerrain()->getSunDirection();
			model->SetDirectional(sunDir, 1.f);
		}

		Iterator<IStorm3D_Model_Object *> *objectIterator;
		for(objectIterator = model->ITObject->Begin(); !objectIterator->IsEnd(); objectIterator->Next())
		{
			IStorm3D_Model_Object *object = objectIterator->GetCurrent();

			const char *name = object->GetName();

			if (strstr(name, "FireThrough") != NULL)
			{
				object->SetNoCollision(true);
			}
		}

		delete objectIterator;

		// add building for self-illum (lightmap brightness) changes...
		game->gameUI->getLightManager()->getSelfIlluminationChanger()->addModel(vo->getStormModel());
  }
Example #6
0
		void set(Fader &fader, IStorm3D_BoneAnimation *a, int time)
		{
			if(a == previous)
				return;

			if(previous)
				fader.addFadeOut(previous, model, time, 2 * time);

			if(a)
			{
				float blendFactor = 0.95f + (array->getMaxAmplitude() / 1550.f);
				if(blendFactor > 1.f)
					blendFactor = 1.f;

				model->BlendWithAnimationIn(0, a, time, false, blendFactor);
				previous = a;
			}
		}
void TargetDisplayWindowUpdator::update()
{
	TargetDisplayButtonManager *manager = window->getManager();
	// rect tmp = getTargetScreenRect( game );
	// window->setRect( 0, tmp.x, tmp.y, tmp.w, tmp.h );
	
	{
		float updateDistance = itemDistance * itemDistance;

		std::list< Item* >::iterator it;
		for( it = itemsToBeUpdated.begin(); it != itemsToBeUpdated.end(); ++it )
		{
			//Point tmp = convertVC3toScreen( (*it)->getPosition(), game );
			Item *item = *it;

			float distance = calculateDistance( item->getPosition(), game );
			if( distance < updateDistance )
			{

				if(item && item->getVisualObject() && item->getVisualObject()->getStormModel())
				{
					IStorm3D_Model *m = item->getVisualObject()->getStormModel();
					Rect rect = getScreenArea(m->GetBoundingBox(), game);

					if(window->setRect(item, rect.x, rect.y, rect.w, rect.h, ( distance / updateDistance ), item->getHighlightStyle()))
					{
						if(item->hasHighlightText())
							window->setText(item, item->getHighlightText());
					}

					if( false ) // items cant have health thus they cant have the health bar
						window->setSliderValue( item, 1.0f, 1.0f );
				}

				/*
				if( window->setRect( (*it), tmp.x - 12, tmp.y - 8, 35, 35, (int)( ( distance / updateDistance ) * 100.0f ), (*it)->getStyle() ) )
				{
					if( (*it)->hasStyleText() )
						window->setText( (*it), (*it)->getStyleText() );	
				}
				*/
			}
		}
	}

	{
		float updateDistance = unitDistance * unitDistance;

		std::list< Unit* >::iterator it;
		for( it = unitsToBeUpdated.begin(); it != unitsToBeUpdated.end(); ++it )
		{
			//point tmp = convertVC3toScreen( (*it)->getPosition(), game );
			float distance = calculateDistance( (*it)->getPosition(), game );
			if( distance < updateDistance )
			{
				Unit *unit = *it;
				if(unit && unit->getVisualObject() && unit->getVisualObject()->getStormModel())
				{				
					UnitType *ut = unit->getUnitType();

					IStorm3D_Model *m = unit->getVisualObject()->getStormModel();
					Rect rect;

					// two rects, one for highlight and another for target lock rect
					for(int i = 0; i < 2; i++)
					{
						void *p = unit;
						int style = unit->getHighlightStyle();
						float rect_scale = 1.0f;
						const char *text = NULL;
						
						// target lock rect
						if(i == 1)
						{
							int max = unit->getTargetLockCounterMax();
							if(unit->getTargetLockCounter() <= 0)
							{
								// no target lock
								continue;
							}
							else if(unit->getTargetLockCounter() < max)
							{
								style = 5;
								rect_scale = 2.0f - 1.0f * (unit->getTargetLockCounter() / (float) max);
								text = NULL;
							}
							else
							{
								style = 6;
								rect_scale = 1.0f;
								text = "gui_target_locked";
							}

							p = ((char *)unit) + 2;
						}

						const TargetDisplayButtonManager::ButtonCreator &bc = window->getManager()->getButtonStyle( style );
						if(bc.rect_style == 0)
						{
							rect = getScreenArea(m->GetBoundingBox(), game);
						}
						else if(bc.rect_style == 1)
						{
							// unit size based rect
							//
							IStorm3D_Scene *scene = game->getGameScene()->getStormScene();
							IStorm3D_Camera *cam = scene->GetCamera();

							VC3 pos = m->GetPosition() + VC3(0, ut->getSize() * ut->getTargetRectHeightScale(), 0);
							VC3 pos_screen = VC3(0,0,0);
							VC3 pos_screen2 = VC3(0,0,0);
							float rhw = 0;
							float real_z = 0;
							bool visible = cam->GetTransformedToScreen(pos, pos_screen, rhw, real_z); 
							if(!visible)
								continue;

							pos += cam->GetUpVecReal() * ut->getSize() * 0.5f;
							visible = cam->GetTransformedToScreen(pos, pos_screen2, rhw, real_z); 
							if(!visible)
								continue;

							VC3 diff = pos_screen - pos_screen2;
							float radius = rect_scale * ut->getTargetRectScale() * sqrtf(diff.x * diff.x + diff.y * diff.y);

							pos_screen.x *= 1024.0f;
							pos_screen.y *= 768.0f;

							rect.x = (int)(pos_screen.x - radius * 1024.0f);
							rect.y = (int)(pos_screen.y - radius * 768.0f);
							rect.w = (int)(radius * 1024.0f * 2.0f);
							rect.h = (int)(radius * 768.0f * 2.0f);
						}

						if(window->setRect(p, rect.x, rect.y, rect.w, rect.h, ( distance / updateDistance ), style ))
						{
							if(unit->hasHighlightText() )
								window->setText(p, unit->getHighlightText() );	
							if(text)
								window->setText(p, text );	

						}

						window->setSliderValue(p, ( (float)unit->getHP() / (float)unit->getMaxHP() ), unit->getUnitType()->getHealthSliderScale() );
					}

				}
			}
		}
	}
	
	{
		float updateDistance = itemDistance * itemDistance;

		std::list< Unit* >::iterator it;
		for( it = risingMessages.begin(); it != risingMessages.end(); )
		{
			Unit *unit = *it;
			float distance = calculateDistance( unit->getPosition(), game );
			if(unit && unit->getVisualObject() && unit->getVisualObject()->getStormModel()
				&& distance < updateDistance)
			{
				IStorm3D_Model *m = unit->getVisualObject()->getStormModel();
				Rect rect = getScreenArea(m->GetBoundingBox(), game);

				// hack: allow rising messages on units with highlight
				void *p = ((char *)unit) + 1;
				if(window->setRect(p, rect.x, rect.y, rect.w, rect.h, ( distance / updateDistance ), risingMessageStyle ))
				{
					/*if(unit->hasHighlightText() )
						window->setText(p, unit->getHighlightText() );	
						*/
				}
			}
			else
			{
				// keep rising message visible even if unit was blown up
				// hack: allow rising messages on units with highlight
				void *p = ((char *)unit) + 1;
				window->updateRect(p);
			}

			// hack: allow rising messages on units with highlight
			void *p = ((char *)(*it)) + 1;
			if( window->hasEnded( p ) == false )
			{
				++it;
			}
			else
			{
				std::list< Unit* >::iterator remove = it;
				++it;
				risingMessages.erase( remove );
			}
		}
		
	}

	
	currentFrame++;

	if( currentFrame >= removeUnnessary )
	{
		currentFrame = 0;
		window->removeRest();
	}
	else
	{
		window->hideRest();
	}

	if( currentFrame%updateTargets == 0 )
		updateUpdatables();



}
Example #8
0
	VisualObject *VisualObjectModel::getNewObjectInstance()
	{
		if (visualStorm == NULL)
		{
			// must initialize first
			abort();
		}

		// DEBUG
		//Logger::getInstance()->error("Creating model:");
		//Logger::getInstance()->error(filename);
		//Timer::update();
		//int starttime = Timer::getTime();

		if (sharedModel == NULL)
		{
			Logger::getInstance()->debug("Creating a shared model.");
			Logger::getInstance()->debug(filename);

			sharedModel = visualStorm->CreateNewModel();
			if (filename != NULL)
			{
				// ubermagic...
				int slen = strlen(filename);
				bool hasObjectName = false;
				int objNamePart = 0;
				for (int i = 0; i < slen; i++)
				{
					if (filename[i] == ':')
					{
						hasObjectName = true;
						objNamePart = i;
						break;	
					}
				}

				// do some magic :)
				if (slen > 4 && strcmp(&filename[slen - 4], ".b3d") == 0)
				{
					// bones should not have object name.
					if (hasObjectName)
					{
						Logger::getInstance()->error("VisualObjectModel::getNewObjectInstance - Bonefilename cannot specify object.");
						return NULL;
					}
					if (!sharedModel->LoadBones(filename))
					{
						Logger::getInstance()->error("VisualObjectModel::getNewObjectInstance - Failed to load bones.");
						Logger::getInstance()->debug(filename);
					}
				} else {
					char real_fname[256];
					if (slen < 256)
					{
						strcpy(real_fname, filename);
					}
					if (hasObjectName)
					{
						if (objNamePart > 0)
							real_fname[objNamePart] = '\0';
						// else assert(0);
					}

					if (!sharedModel->LoadS3D(real_fname))
					{
						Logger::getInstance()->error("VisualObjectModel::getNewObjectInstance - Failed to load model.");
						Logger::getInstance()->debug(real_fname);
					}

					if (hasObjectName)
					{
						// delete all objects except the one we want...
						LinkedList objlist;
						Iterator<IStorm3D_Model_Object *> *object_iterator;
						for(object_iterator = sharedModel->ITObject->Begin(); !object_iterator->IsEnd(); object_iterator->Next())
						{
							IStorm3D_Model_Object *object = object_iterator->GetCurrent();
							objlist.append(object);
						}
						delete object_iterator;
						objlist.resetIterate();
						bool foundObject = false;
						while (objlist.iterateAvailable())
						{
							IStorm3D_Model_Object *object = (IStorm3D_Model_Object *)objlist.iterateNext();
							const char *objname = object->GetName();
							if (objname == NULL
								|| strcmp(&filename[objNamePart + 1], objname) != 0)
							{
								//delete object->GetMesh();
								sharedModel->Object_Delete(object);
							} else {
								if (objname != NULL)
									foundObject = true;
							}
						}
						if (!foundObject)
						{
							Logger::getInstance()->warning("VisualObjectModel::getNewObjectInstance - Model did not contain requested object.");
						}
					}

				}
			} else {
				Logger::getInstance()->debug("VisualObjectModel::getNewObjectInstance - Created empty visual object.");
			}
		}
		refCount++;

		assert(sharedModel != NULL);

		//IStorm3D_Model *model = visualStorm->CreateNewModel();
		IStorm3D_Model *model = NULL;

		// TODO: don't reload the model!! just copy the bones and stuff
		// from the shared model!!!

		// a quick hack method for getting helpers and stuff created...
		// just load the model again, and then clear the meshes...
		if (filename != NULL)
		{
			//Logger::getInstance()->error("Loading model.");
			// do some magic :)
			if (strlen(filename) > 4 
				&& strcmp(&filename[strlen(filename) - 4], ".b3d") == 0)
			{
				/*
				model = visualStorm->CreateNewModel();
				if (!model->LoadBones(filename))
				{
					Logger::getInstance()->error("VisualObjectModel::getNewObjectInstance - Failed to load bones.");
					Logger::getInstance()->debug(filename);
				}
				*/			
				model = sharedModel->GetClone(true, true, true);
			} else {
				//assert(0);
				// FIXME: ????????????????????????????????????????????
				/*
				model = visualStorm->CreateNewModel();
				model->LoadS3D(filename);
				*/
				model = sharedModel->GetClone(true, true, true);
			}
		} else {
			//Logger::getInstance()->debug("VisualObjectModel::getNewObjectInstance - Created empty visual object.");
			model = visualStorm->CreateNewModel();
		}

		assert(model != NULL);

		/*
		// delete loaded objects...
		LinkedList objlist;
		Iterator<IStorm3D_Model_Object *> *object_iterator;
		for(object_iterator = model->ITObject->Begin(); !object_iterator->IsEnd(); object_iterator->Next())
		{
			IStorm3D_Model_Object *object = object_iterator->GetCurrent();
			assert(object != NULL);
			objlist.append(object);
		}
		delete object_iterator;

		objlist.resetIterate();
		//while (objlist.iterateAvailable())
		while (!objlist.isEmpty())
		{
			//IStorm3D_Model_Object *object = (IStorm3D_Model_Object *)objlist.iterateNext();
			IStorm3D_Model_Object *object = (IStorm3D_Model_Object *)objlist.popLast();
			//delete object->GetMesh();
			model->Object_Delete(object);
		}

		// copy shared data to new model...
		Iterator<IStorm3D_Model_Object *> *del_object_iterator;
		for (del_object_iterator = sharedModel->ITObject->Begin(); !del_object_iterator->IsEnd(); del_object_iterator->Next())
		{
			IStorm3D_Model_Object *object = del_object_iterator->GetCurrent();
			IStorm3D_Mesh *mesh = object->GetMesh();
			if(mesh == NULL)
				continue;

			IStorm3D_Model_Object *objCopy = model->Object_New(object->GetName());
			objCopy->SetNoCollision(object->GetNoCollision());
			objCopy->SetNoRender(object->GetNoRender());
			objCopy->SetMesh(object->GetMesh());
			objCopy->SetPosition(object->GetPosition());
			objCopy->SetRotation(object->GetRotation());
			if(object->IsLightObject())
				objCopy->SetAsLightObject();
		} 		 
		delete del_object_iterator;
		*/

		VisualObject *ret = new VisualObject();
		ret->model = model;
		ret->animation = NULL;
		ret->storm3d = visualStorm;
		ret->scene = visualStormScene;
		ret->visualObjectModel = this;
		model->SetCustomData(ret);

		// DEBUG
		//Timer::update();
		//int timeelapsed = Timer::getTime() - starttime;
		//Logger::getInstance()->error("Time elapsed:");
		//Logger::getInstance()->error(int2str(timeelapsed));

		return ret;
	}
Example #9
0
int WINAPI WinMain(HINSTANCE hInstance, 
  HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  // initialize...

  int scr_width = 0;
  int scr_height = 0;

	char *cmdline = lpCmdLine;

	std::string fileName = cmdline;
	//MessageBox(0, cmdline, "Command line", MB_OK);

	std::string parsedLine;
	if(strlen(cmdline) > 2)
	{
		char buffer[1024] = { 0 };
		GetModuleFileName(GetModuleHandle(0), buffer, 1023);
		std::string dir = buffer;
		int end = dir.find_last_of('\\');
		dir = dir.substr(0, end);

//#ifdef NDEBUG
		if (strstr(dir.c_str(), "source") != NULL)
		{
			MessageBox(0, "NOTE: Seem to be running under source dir, so not changing dir.", "Running from source.", MB_OK);
		} else {
			//MessageBox(0, dir.c_str(), "Changing dir to", MB_OK);
			SetCurrentDirectory(dir.c_str());
		}
//#endif

		{
			int start = 0;
			if (fileName[0] == '\"')
				start++;
			int end = fileName.find_last_of('\"');
			fileName = fileName.substr(start, end - start);
		}
	}

	using namespace frozenbyte::filesystem;
	boost::shared_ptr<IFilePackage> standardPackage(new StandardPackage());
	//boost::shared_ptr<IFilePackage> zipPackage(new ZipPackage("data.zip"));

	FilePackageManager &manager = FilePackageManager::getInstance();
	manager.addPackage(standardPackage, 0);
	//manager.addPackage(zipPackage, 2);

	parse_commandline(fileName.c_str());

	if (binFilename == NULL)
	{
		return 1;
	}

	//MessageBox(0, binFilename, "Bin", MB_OK);
	//MessageBox(0, modelFilename, "Model", MB_OK);

  Timer::init();

	IStorm3D *s3d = IStorm3D::Create_Storm3D_Interface(true, NULL);
	s3d->SetUserWindowMessageProc(&customMessageProc);

	s3d->SetApplicationName("BinEditor", "BinEditor");

  scr_width = 1024;
  scr_height = 768;

	s3d->SetWindowedMode(scr_width, scr_height);
	ShowWindow(s3d->GetRenderWindow(), SW_MAXIMIZE);

  // keyb3 controller devices
	int ctrlinit = 0;
	ctrlinit |= KEYB3_CAPS_MOUSE;
  ctrlinit |= KEYB3_CAPS_KEYBOARD;
  Keyb3_Init(s3d->GetRenderWindow(), ctrlinit);
  Keyb3_SetActive(1);

	float mouse_sensitivity = 1.0f;
  
  Storm3D_SurfaceInfo screenInfo = s3d->GetScreenSize();
  Keyb3_SetMouseBorders((int)(screenInfo.width / mouse_sensitivity), 
    (int)(screenInfo.height / mouse_sensitivity));
  Keyb3_SetMousePos((int)(screenInfo.width / mouse_sensitivity) / 2, 
    (int)(screenInfo.height / mouse_sensitivity) / 2);

	Keyb3_UpdateDevices();

  // make a scene
  COL bgCol = COL(0.0f, 0.0f, 0.0f);

  disposable_scene = s3d->CreateNewScene();
  disposable_scene->SetBackgroundColor(bgCol);

  disposable_scene->GetCamera()->SetVisibilityRange(100.0f);

  // create and initialize ogui
  Ogui *ogui = new Ogui();
  OguiStormDriver *ogdrv = new OguiStormDriver(s3d, disposable_scene);
  ogui->SetDriver(ogdrv);
  ogui->SetScale(OGUI_SCALE_MULTIPLIER * scr_width / 1024, 
    OGUI_SCALE_MULTIPLIER * scr_height / 768); 
  ogui->SetMouseSensitivity(mouse_sensitivity, mouse_sensitivity);
  ogui->Init();

  // set default font
#ifdef LEGACY_FILES
  ogui->LoadDefaultFont("Data/Fonts/default.ogf");
#else
  ogui->LoadDefaultFont("data/gui/font/common/default.ogf");
#endif

  // set default ui (ogui and storm) for visual objects (pictures and models)
  ui::createUIDefaults(ogui);

	LoadingMessage::setManagers(s3d, disposable_scene, ogui);

  // create cursors
  ogui->SetCursorController(0, OGUI_CURSOR_CTRL_MOUSE);

  // cursors images for controller 0,1,2,3
  loadDHCursors(ogui, 0); 

  ogui->SetCursorImageState(0, DH_CURSOR_ARROW);

  // do the loop...

  Timer::update();
  DWORD startTime = Timer::getTime(); 
  DWORD curTime = startTime;
  DWORD movementTime = startTime;
  DWORD frameCountTime = startTime;
  DWORD lastOguiUpdateTime = startTime;
  bool quitRequested = false;

  int frames = 0;
  int polys = 0;
  int fps = 0;
  int polysps = 0;
	int precount = 0;

	VC3 campos = VC3(0,0,0);

	Keyb3_UpdateDevices();

	IStorm3D_Model *model = NULL;

	if (modelFilename != NULL)
	{
	  model = s3d->CreateNewModel();
		model->LoadS3D(modelFilename);
		disposable_scene->AddModel(model);

		/*
    QUAT rot = QUAT(
      UNIT_ANGLE_TO_RAD(modelAngleX), 
      UNIT_ANGLE_TO_RAD(modelAngle), 
      UNIT_ANGLE_TO_RAD(modelAngleZ));
		*/
		QUAT qx;
		qx.MakeFromAngles(modelAngleX*3.1415f/180.0f, 0, 0);
		QUAT qy;
		qy.MakeFromAngles(0, modelAngle*3.1415f/180.0f, 0);
		QUAT qz;
		qz.MakeFromAngles(0, modelAngleZ*3.1415f/180.0f, 0);
		QUAT rot = qz * qx * qy;

    model->SetRotation(rot);

		// ----------------------------
		// HIDE ROOF...

		Iterator<IStorm3D_Model_Object *> *objectIterator;
		for(objectIterator = model->ITObject->Begin(); !objectIterator->IsEnd(); objectIterator->Next())
		{
			IStorm3D_Model_Object *object = objectIterator->GetCurrent();
			const char *name = object->GetName();

			int namelen = strlen(name);

			if(namelen < 12)
				continue;

			// Test name tag
			for(int i = 0; i < namelen - 12 + 1; ++i)
			{
				if (strncmp(&name[i], "BuildingRoof", 12) == 0)
				{
					object->SetNoRender(true);
				}
			}

		}

		delete objectIterator;

		// END OF HIDE ROOF
		// ----------------------------

	}

	/*
	IStorm3D_Line *gridlines[GRID_AREA_SIZE *2+1][GRID_AREA_SIZE *2+1][4] = { 0 };
	*/
	IStorm3D_Model *gridmodels[GRID_AREA_SIZE *2+1][GRID_AREA_SIZE *2+1][3] = { 0 };
	for (int i = 0; i < GRID_AREA_SIZE *2+1; i++)
	{
		for (int j = 0; j < GRID_AREA_SIZE *2+1; j++)
		{
			for (int k = 0; k < 3; k++)
			{
				gridmodels[i][j][k] = s3d->CreateNewModel();
#ifdef LEGACY_FILES
				if (k < 1)
					gridmodels[i][j][k]->LoadS3D("Data/Models/Pointers/grid_green.s3d");
				else if (k == 2)
					gridmodels[i][j][k]->LoadS3D("Data/Models/Pointers/grid_red.s3d");
				else
					gridmodels[i][j][k]->LoadS3D("Data/Models/Pointers/grid_blue.s3d");
#else
				if (k < 1)
					gridmodels[i][j][k]->LoadS3D("data/model/pointer/grid_green.s3d");
				else if (k == 2)
					gridmodels[i][j][k]->LoadS3D("data/model/pointer/grid_red.s3d");
				else
					gridmodels[i][j][k]->LoadS3D("data/model/pointer/grid_blue.s3d");
#endif
				disposable_scene->AddModel(gridmodels[i][j][k]);
			}
		}
	}


	VC3 targ = campos;
	VC3 pos = targ - VC3(zoom/2,-zoom,0);
	disposable_scene->GetCamera()->SetPosition(pos);
	disposable_scene->GetCamera()->SetTarget(targ);

	unsigned short buffer[32*32] = { 0 };
	IStorm3D_Terrain *terrain = s3d->CreateNewTerrain(32);
	terrain->setHeightMap(buffer, VC2I(32,32), VC3(500,.01f,500), 4, 0, 1, 1);
	//terrain->getRenderer().setRenderMode(IStorm3D_TerrainRenderer::TexturesOnly);
	terrain->getRenderer().setFloatValue(IStorm3D_TerrainRenderer::ForceAmbient, 0.5f);
	disposable_scene->AddTerrain(terrain);
	disposable_scene->SetAmbientLight(COL(0.5f,0.5f,0.5f));

	frozenbyte::BuildingMap *bmap = NULL;

	if (binFilename != NULL
		&& modelFilename != NULL)
	{
		bmap = new frozenbyte::BuildingMap(modelFilename, model, modelAngleX, modelAngle, modelAngleZ);
	}

	if (bmap == NULL)
	{
		return 2;
	}

	float resolution = bmap->getMapResolution();
	const std::vector<std::vector<unsigned char> > &obstmap = bmap->getObstacleMap();
	const std::vector<std::vector<unsigned char> > &heightmap = bmap->getHeightMap();
	const std::vector<std::vector<char> > &floormap = bmap->getFloorHeightMap();

	int lastcammapx = -1;
	int lastcammapz = -1;

	bool wireframe = false;
	bool collision = false;

  while (!quitRequested)
  {
    // read input
    
    Keyb3_UpdateDevices();

		if (Keyb3_IsKeyPressed(KEYCODE_ESC))
		{
			quitRequested = true;
		}

    Timer::update();

    Timer::update();
    curTime = Timer::getTime();

    if (curTime - movementTime > 0)
    {
      // VEEERY jerky... 
      // attempt to fix that...
      float delta;
      delta = 100.0f;
      if (fps > 0) delta = 1000.0f/fps;
      if (delta < 1.0f) delta = 1.0f;
      if (delta > 100.0f) delta = 100.0f;
      float camera_time_factor = 1.0f;
      delta = (delta * camera_time_factor);

			float movespeed = 0.01f;
			if (Keyb3_IsKeyDown(KEYCODE_SHIFT_RIGHT)
				|| Keyb3_IsKeyDown(KEYCODE_SHIFT_LEFT))
				movespeed = 0.03f;

			IStorm3D_TerrainRenderer &renderer = terrain->getRenderer();
			if (Keyb3_IsKeyPressed(KEYCODE_1))
			{
				wireframe = !wireframe;
				if (wireframe)
				{
					renderer.enableFeature(IStorm3D_TerrainRenderer::Wireframe, true);
				} else {
					renderer.enableFeature(IStorm3D_TerrainRenderer::Wireframe, false);
				}
			}
			if (Keyb3_IsKeyPressed(KEYCODE_2))
			{
				collision = !collision;
				if (collision)
				{
					renderer.enableFeature(IStorm3D_TerrainRenderer::Collision, true);
				} else {
					renderer.enableFeature(IStorm3D_TerrainRenderer::Collision, false);
				}
			}

			if (Keyb3_IsKeyDown(KEYCODE_Q))
			{
				camrot -= 0.1f * delta;
			}
			if (Keyb3_IsKeyDown(KEYCODE_E))
			{
				camrot += 0.1f * delta;
			}
			if (camrot >= 360.0f) camrot -= 360.0f;
			if (camrot < 0.0f) camrot += 360.0f;

			if (Keyb3_IsKeyDown(KEYCODE_UP_ARROW)
				|| Keyb3_IsKeyDown(KEYCODE_W))
			{
				campos.x += (movespeed * delta)* cosf(camrot / 180.0f * 3.1415f);
				campos.z += (movespeed * delta)* -sinf(camrot / 180.0f * 3.1415f);
			}
			if (Keyb3_IsKeyDown(KEYCODE_DOWN_ARROW)
				|| Keyb3_IsKeyDown(KEYCODE_S))
			{
				campos.x -= (movespeed * delta)* cosf(camrot / 180.0f * 3.1415f);
				campos.z -= (movespeed * delta)* -sinf(camrot / 180.0f * 3.1415f);
			}
			if (Keyb3_IsKeyDown(KEYCODE_LEFT_ARROW)
				|| Keyb3_IsKeyDown(KEYCODE_A))
			{
				campos.z += (movespeed * delta)* cosf(camrot / 180.0f * 3.1415f);
				campos.x += (movespeed * delta)* sinf(camrot / 180.0f * 3.1415f);
			}
			if (Keyb3_IsKeyDown(KEYCODE_RIGHT_ARROW)
				|| Keyb3_IsKeyDown(KEYCODE_D))
			{
				campos.z -= (movespeed * delta)* cosf(camrot / 180.0f * 3.1415f);
				campos.x -= (movespeed * delta)* sinf(camrot / 180.0f * 3.1415f);
			}
			if (Keyb3_IsKeyDown(KEYCODE_KEYPAD_PLUS))
			{
				zoom -= movespeed * delta;
				if (zoom < 1.5f)
					zoom = 1.5f;
			}
			if (Keyb3_IsKeyDown(KEYCODE_KEYPAD_MINUS))
			{
				zoom += movespeed * delta;
				if (zoom > 80.0f)
					zoom = 80.0f;
			}
			if (Keyb3_IsKeyDown(KEYCODE_KEYPAD_DIVIDE))
			{
				camBeta -= movespeed*2 * delta;
				if (camBeta < -45.0f)
					camBeta = -45.0f;
			}
			if (Keyb3_IsKeyDown(KEYCODE_KEYPAD_MULTIPLY))
			{
				camBeta += movespeed*2 * delta;
				if (camBeta > 45.0f)
					camBeta = 45.0f;
			}

			VC3 targ = campos;
			float dirx = zoom*cosf((camBeta+45)/ 180.0f * 3.1415f) * cosf(camrot / 180.0f * 3.1415f);
			float dirz = zoom*cosf((camBeta+45)/ 180.0f * 3.1415f) * -sinf(camrot / 180.0f * 3.1415f);
			VC3 pos = targ - VC3(dirx,-zoom*cosf((camBeta-45)/ 180.0f * 3.1415f),dirz);

			disposable_scene->GetCamera()->SetPosition(pos);
			disposable_scene->GetCamera()->SetTarget(targ);

      movementTime = curTime;
    }

		// height/floor/obstacle visualization...
		
		int cammapx = int(campos.x / resolution);
		int cammapz = int(campos.z / resolution);

		if (cammapx != lastcammapx || cammapz != lastcammapz)
		{
			lastcammapx = cammapx;
			lastcammapz = cammapz;
			for (int mz = -GRID_AREA_SIZE; mz < GRID_AREA_SIZE+1; mz++)
			{
				for (int mx = -GRID_AREA_SIZE; mx < GRID_AREA_SIZE+1; mx++)
				{
					int tx = heightmap.size() / 2 + cammapx + mx;
					int tz = heightmap[0].size() / 2 + cammapz + mz;
					for (int i = 0; i < 3; i++)
					{
						gridmodels[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->SetPosition(VC3(0,0,0));
						//gridmodels[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->SetPosition(VC3(0,-2000,0));
						/*
						if (gridlines[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i] != NULL)
						{
							disposable_scene->RemoveLine(gridlines[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]);
							while (gridlines[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->GetPointCount() > 0)
							{
								gridlines[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->RemovePoint(0);
							}
							delete gridlines[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i];
							gridlines[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i] = NULL;
						}
						*/
					}
					if (tx >= 0 && tz >= 0
						&& tx < (int)heightmap.size() && tz < (int)heightmap[0].size())
					{
						for (int i = 0; i < 3; i++)
						{
							VC3 origin = VC3(cammapx*resolution,0,cammapz*resolution) + VC3(mx*resolution, 0, mz*resolution);

							if (floormap[tx][tz] != BUILDINGMAP_NO_FLOOR_BLOCK)
							{
								origin.y = (float)floormap[tx][tz] * bmap->getHeightScale() + 0.01f;
								if (!wireframe)
									origin.y += 0.05f;
							}

							if (i >= 2)
							{
								origin.y += (float)heightmap[tx][tz] * bmap->getHeightScale();
								origin.y += 0.02f;
								if (obstmap[tx][tz] == 0)
									origin = VC3(0,-2000,0);
							}
							//if (i == 1)
							//{
							//	gridmodels[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->SetScale(VC3(0.5f,0.5f,0.5f));
							//}
							if (i == 1 && obstmap[tx][tz] == 0)
							{
								origin = VC3(0,-2000,0);
							}
							if (i == 0 && obstmap[tx][tz] != 0)
							{
								origin = VC3(0,-2000,0);
							}

							gridmodels[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->SetPosition(origin);

							if (obstmap[tx][tz] == 2)
								gridmodels[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->SetScale(VC3(0.8f,1,0.8f));
							else
								gridmodels[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i]->SetScale(VC3(1,1,1));


							/*
							IStorm3D_Line *lineObject = s3d->CreateNewLine();
							unsigned int alpha = 0x30000000;
							unsigned int color = 0x0000ff00;
							float thickness = 0.03f;

							if (obstmap[tx][tz] != 0)
								color = 0x00ff0000;

							if (i < 2 || obstmap[tx][tz] != 0)
							{
								lineObject->SetThickness(thickness);
								lineObject->SetColor(color | alpha);

								VC3 origin = campos + VC3(mx*resolution, 0, mz*resolution);

								origin.y = floormap[tx][tz] * bmap->getHeightScale() + 0.001f;

								if (i >= 2)
									origin.y += (float)heightmap[tx][tz] * bmap->getHeightScale();

								lineObject->AddPoint(origin);
								VC3 line_endpoint;
								if ((i % 2) == 0)
									line_endpoint = origin + VC3(resolution,0,0);
								else
									line_endpoint = origin + VC3(0,0,resolution);
								lineObject->AddPoint(line_endpoint);
								disposable_scene->AddLine(lineObject, true);

								gridlines[GRID_AREA_SIZE+mx][GRID_AREA_SIZE+mz][i] = lineObject;
							}
							*/
						}
					}
				}
			}
		}

    // frame/poly counting
    frames++;
    {
      if (curTime - frameCountTime >= 200) 
      {
       float seconds = (curTime - frameCountTime) / 1000.0f;
       fps = (int)(frames / seconds);
       polysps = (int)(polys / seconds);
       frameCountTime = curTime;
       frames = 0;
       polys = 0;
      }
    }

    // run the gui
		int oguiTimeDelta = curTime - lastOguiUpdateTime;
		if (oguiTimeDelta > 200)
			oguiTimeDelta = 200;

    ogui->Run(oguiTimeDelta);

		lastOguiUpdateTime = curTime;

    // render stats

		bool show_polys = true;
		bool show_fps = true;
		// WARNING: unsafe cast!
		IStorm3D_Font *fpsFont = ((OguiStormFont *)ui::defaultIngameFont)->fnt;
    if (show_polys || show_fps)
    {
      float polyoffset = 0;
      float terroffset = 0;
      char polytextbuf[40];
      char polyframetextbuf[40];
      char fpstextbuf[40];
      if (show_fps)
      {
        polyoffset = 16;
				terroffset = 16;
        sprintf(fpstextbuf, "FPS:%d", fps);
        disposable_scene->Render2D_Text(fpsFont, VC2(0,0), VC2(16, 16), fpstextbuf);
      }
      if (show_polys)
      {
				terroffset += 32;
        sprintf(polytextbuf, "POLYS PER S:%d", polysps);
        int polyspf = 0;
        if (fps > 0) polyspf = polysps / fps;
        sprintf(polyframetextbuf, "POLYS PER F:%d", polyspf);
        disposable_scene->Render2D_Text(fpsFont, VC2(0,polyoffset), VC2(16, 16), polytextbuf);
        disposable_scene->Render2D_Text(fpsFont, VC2(0,polyoffset+16), VC2(16, 16), polyframetextbuf);
      }
    }

		int tx = heightmap.size() / 2 + cammapx;
		int tz = heightmap[0].size() / 2 + cammapz;
    char coordtextbuf[64];
    sprintf(coordtextbuf, "%d,%d", tx,tz);
    disposable_scene->Render2D_Text(fpsFont, VC2(0,768-16), VC2(16, 16), coordtextbuf);

    // Render scene
    polys += renderfunc(disposable_scene);

		//DebugDataView::getInstance(game)->run();

		// wait here if minimized...
		while (true)
		{
			// psd -- handle windows messages
			MSG msg = { 0 };
			while(PeekMessage(&msg, s3d->GetRenderWindow(), 0, 0, PM_NOREMOVE))
			{
				if(GetMessage(&msg, s3d->GetRenderWindow(), 0, 0) <= 0)
				{
					quitRequested = true;
				}
				else
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
			}
			if (lostFocusPause)
			{
				Sleep(500);
			} else {
				break;
			}
		}
  }

	if (bmap != NULL)
	{
		delete bmap;
		bmap = NULL;
	}

  // clean up

  unloadDHCursors(ogui, 0); 

  deleteUIDefaults();

  ogui->Uninit();
  delete ogui;
  delete ogdrv;

  Keyb3_Free();
  
  delete s3d;

	SystemRandom::cleanInstance();

	uninitLinkedListNodePool();

  Timer::uninit();

	Logger::cleanInstance();

  return 0;
}