void Client::ZCom_cbNodeRequest_Dynamic( ZCom_ConnID _id, ZCom_ClassID _requested_class, ZCom_BitStream *_announcedata, eZCom_NodeRole _role, ZCom_NodeID _net_id ) { if (_requested_class == bomb_id) { printf("Client: Bomb requested\n"); float x = _announcedata->getFloat(POSITION_MANTISSA); float y = _announcedata->getFloat(POSITION_MANTISSA); float z = _announcedata->getFloat(POSITION_MANTISSA); Bomb* bomb = new Bomb; bomb->Register_net_node(this, bomb_id); bomb->Set_position(Vector3(x, y, z)); play->Add_bomb(bomb); } if (_requested_class == player_id) { printf("Client: Player requested\n"); float x = _announcedata->getFloat(POSITION_MANTISSA); float y = _announcedata->getFloat(POSITION_MANTISSA); float z = _announcedata->getFloat(POSITION_MANTISSA); Player* player = new Player; player->Register_net_node(this, player_id); player->Set_position(Vector3(x, y, z)); play->Add_player(player, _role==eZCom_RoleOwner); } if (_requested_class == heightmap_id) { printf("Client: Heightmap requested\n"); Heightmap* heightmap = new Heightmap; heightmap->Register_net_node(this, heightmap_id); play->Add_heightmap(heightmap); } }
void CommandCopyPasteHeightmap::Execute() { LandscapeEditorHeightmap* editor = GetEditor(); if (!editor) { SetState(STATE_INVALID); return; } // Apply new heightmap if (heightmap) { if (editor->IsActive()) { Heightmap* heightmap = editor->GetHeightmap(); heightmap->Load(heightmapRedoFilename); editor->UpdateHeightmap(heightmap, updatedRect); } else { UpdateLandscapeHeightmap(heightmapRedoFilename); } } // Apply new tilemap if (tilemap) { UpdateLandscapeTilemap(tilemapRedoImage); } }
LandscapeEditorDrawSystem::eErrorType LandscapeEditorDrawSystem::Init() { if (!heightmapProxy) { Heightmap* heightmap = baseLandscape->GetHeightmap(); if (heightmap == NULL || heightmap->Size() == 0) { return LANDSCAPE_EDITOR_SYSTEM_HEIGHTMAP_ABSENT; } heightmapProxy = new HeightmapProxy(baseLandscape->GetHeightmap()->Clone(NULL)); } if (!customColorsProxy) { customColorsProxy = new CustomColorsProxy((int32)GetTextureSize(Landscape::TEXTURE_TILE_FULL)); } if (!visibilityToolProxy) { visibilityToolProxy = new VisibilityToolProxy((int32)GetTextureSize(Landscape::TEXTURE_TILE_FULL)); } if (!rulerToolProxy) { rulerToolProxy = new RulerToolProxy((int32)GetTextureSize(Landscape::TEXTURE_TILE_FULL)); } return LANDSCAPE_EDITOR_SYSTEM_NO_ERRORS; }
void CommandCopyPasteHeightmap::Cancel() { // Restore old heightmap if (heightmap) { LandscapeEditorHeightmap* editor = GetEditor(); if (!editor) return; if (editor->IsActive()) { Heightmap* heightmap = editor->GetHeightmap(); heightmap->Load(heightmapUndoFilename); editor->UpdateHeightmap(heightmap, updatedRect); } else { UpdateLandscapeHeightmap(heightmapUndoFilename); } } // Restore old tilemap if (tilemap) { UpdateLandscapeTilemap(tilemapUndoImage); } }
// Updates a player based on user input: void Player::update(const Heightmap& hmap, const Graphics::Camera& cam, double timestep) { double height = hmap.getHeight(loc)+size; vel -= vec3::Y()*0.008*timestep; // If we can walk: if(loc.y-walkTolerance < height) { // Apply motion along cardinal directions if any of the keys are pressed, or else have them stand still: if(KEY(17)||KEY(30)||KEY(31)||KEY(32)) { vec3 snorm = hmap.getNormal(loc); vel += cam.right().cross(snorm).norm() * (0.6*KEY(31) - KEY(17)) * 0.06*timestep; vel += cam.ahead().cross(snorm).norm() * (KEY(32) - KEY(30)) * 0.05*timestep; } else if(vel.abs2()<3) vel = vec3::zero(); } else if(loc.y-stillTolerance < height && vel.abs2()<3) { vel = vec3::zero(); } // Jetpack and gravity: vel += cam.up()*KEY(57)*0.07*timestep - vec3::Y()*timestep*0.03; // Resistance to motion: vel *= pow(0.7, 0.001*timestep); // Superclass update: Agent::update(hmap, timestep); }
void LandscapePropertyControl::SaveHeightmapToPng(DAVA::BaseObject *object, void *userData, void *callerData) { LandscapeNode *landscape = GetLandscape(); if (!landscape) return; Heightmap * heightmap = landscape->GetHeightmap(); String heightmapPath = landscape->GetHeightmapPathname(); heightmapPath = FileSystem::ReplaceExtension(heightmapPath, ".png"); heightmap->SaveToImage(heightmapPath); }
bool SceneValidator::ValidateHeightmapPathname(const FilePath &pathForValidation, Set<String> &errorsLog) { DVASSERT_MSG(!pathForChecking.IsEmpty(), "Need to set pathname for DataSource folder"); bool pathIsCorrect = IsPathCorrectForProject(pathForValidation); if(pathIsCorrect) { String::size_type posPng = pathForValidation.GetAbsolutePathname().find(".png"); String::size_type posHeightmap = pathForValidation.GetAbsolutePathname().find(Heightmap::FileExtension()); pathIsCorrect = ((String::npos != posPng) || (String::npos != posHeightmap)); if(!pathIsCorrect) { errorsLog.insert(Format("Heightmap path %s is wrong", pathForValidation.GetAbsolutePathname().c_str())); return false; } Heightmap *heightmap = new Heightmap(); if(String::npos != posPng) { Image *image = CreateTopLevelImage(pathForValidation); pathIsCorrect = heightmap->BuildFromImage(image); SafeRelease(image); } else { pathIsCorrect = heightmap->Load(pathForValidation); } if(!pathIsCorrect) { SafeRelease(heightmap); errorsLog.insert(Format("Can't load Heightmap from path %s", pathForValidation.GetAbsolutePathname().c_str())); return false; } pathIsCorrect = IsPowerOf2(heightmap->Size() - 1); if(!pathIsCorrect) { errorsLog.insert(Format("Heightmap %s has wrong size", pathForValidation.GetAbsolutePathname().c_str())); } SafeRelease(heightmap); return pathIsCorrect; } else { errorsLog.insert(Format("Path %s is incorrect for project %s", pathForValidation.GetAbsolutePathname().c_str(), pathForChecking.GetAbsolutePathname().c_str())); } return pathIsCorrect; }
void CommandDrawHeightmap::Cancel() { LandscapeEditorHeightmap* editor = GetEditor(); if (editor) { Heightmap* heightmap; editor->GetHeightmap(&heightmap); heightmap->Load(undoFilename); editor->UpdateHeightmap(heightmap); } }
void RenderDataManager::InitializeNode (TQuad *q) { assert (!q->renderData); QuadRenderData *rd = q->renderData = Allocate (); // Allocate vertex data space int vertexSize = q->GetVertexSize (); if (vertexSize != rd->vertexSize) { int size = NUM_VERTICES * vertexSize; if (rd->vertexBuffer.GetSize () != size) rd->vertexBuffer.Init (size); rd->vertexSize = vertexSize; } // build the vertex buffer Vector3 *v = (Vector3*)rd->vertexBuffer.LockData (); uint vda = q->textureSetup->vertexDataReq; // vertex data requirements Heightmap *hm = roothm->GetLevel (q->depth); // get the right heightmap level for(int y=q->hmPos.y;y<=q->hmPos.y+QUAD_W;y++) for(int x=q->hmPos.x;x<=q->hmPos.x+QUAD_W;x++) { *(v++) = Vector3(x * hm->squareSize, hm->HeightAt (x,y), y * hm->squareSize); Vector3 tangent, binormal; CalculateTangents (hm, x,y, tangent, binormal); Vector3 normal = binormal.cross(tangent); normal.ANormalize (); if (vda & VRT_Normal) *(v++) = normal; if (vda & VRT_TangentSpaceMatrix) { tangent.ANormalize (); binormal.ANormalize (); // orthonormal matrix, so inverse=transpose // Take the inverse of the tangent space -> world space transformation Vector3* tgs2ws = v; tgs2ws[0] = Vector3(tangent.x, binormal.x, normal.x); tgs2ws[1] = Vector3(tangent.y, binormal.y, normal.y); tgs2ws[2] = Vector3(tangent.z, binormal.z, normal.z); v+=3; } } rd->vertexBuffer.UnlockData (); rd->SetQuad(q); }
float32 LandscapeEditorHeightmap::GetDropperHeight() { Vector3 landSize; AABBox3 transformedBox; workingLandscape->GetBoundingBox().GetTransformedBox(*workingLandscape->GetWorldTransformPtr(), transformedBox); landSize = transformedBox.max - transformedBox.min; Heightmap *heightmap = landscapesController->GetCurrentHeightmap(); int32 index = (int32)(landscapePoint.x + landscapePoint.y * heightmap->Size()); float32 height = heightmap->Data()[index]; float32 maxHeight = landSize.z; return (height / Heightmap::MAX_VALUE * maxHeight); }
void HeightmapModificationCommand::UpdateLandscapeHeightmap(String filename) { SceneData *activeScene = SceneDataManager::Instance()->SceneGetActive(); LandscapesController* landscapesController = activeScene->GetLandscapesController(); Landscape* landscapeNode = landscapesController->GetCurrentLandscape(); Heightmap* heightmap = new Heightmap(); heightmap->Load(filename); landscapeNode->SetHeightmap(heightmap); heightmap->Save(landscapeNode->GetHeightmapPathname()); SafeRelease(heightmap); }
void LandscapeEditorHeightmap::SaveTextureAction(const String &pathToFile) { Heightmap *heightmap = landscapesController->GetCurrentHeightmap(); if(heightmap) { String heightmapPath = pathToFile; String extension = FileSystem::Instance()->GetExtension(pathToFile); if(Heightmap::FileExtension() != extension) { heightmapPath = FileSystem::Instance()->ReplaceExtension(heightmapPath, Heightmap::FileExtension()); } savedPath = heightmapPath; heightmap->Save(heightmapPath); } }
void LandscapeEditorHeightmap::TextureDidChanged(const String &forKey) { if("property.landscape.texture.heightmap" == forKey) { savedPath = workingLandscape->GetHeightmapPathname(); Heightmap *heightmap = landscapesController->GetCurrentHeightmap(); landscapeSize = heightmap->Size(); CreateHeightmapUndo(); } else if("property.landscape.texture.tilemask" == forKey) { CreateTilemaskImage(); } }
Heightmap Heightmap::operator-=( Heightmap &other ) { for(int j=0;j<Size;j++) for(int i=0;i<Size;i++) put(i,j,at(i,j)-other.at(i,j)); return *this; }
void Map::CalcBetaSkeletonHeightmap(float gamma, Heightmap &map) { int size = towns.size(); bool hasATownInBetaSkeleton = false; const float step_y = 0.1f; int cmp = 0; for (int a = 0; a < size; ++a) { for (int b = cmp; b < size; ++b) { if (a == b) continue; bool hasATownInBetaSkeleton = false; for (int p = 0; p < size; ++p) { if (p != a && p != b && IsInBetaSkeletonHeightmap(towns[p], towns[a], towns[b], gamma, map)) { hasATownInBetaSkeleton = true; } } if (!hasATownInBetaSkeleton) { waysPoints.push_back(towns[a]); waysPoints.push_back(towns[b]); waysCost.push_back(map.getDistance(towns[a], towns[b])); waysEdges.push_back(Vector2d(waysPoints.size() - 2, waysPoints.size() - 1)); } } ++cmp; } }
void CommandDrawHeightmap::Cancel() { LandscapeEditorHeightmap* editor = GetEditor(); if (!editor) return; if (editor->IsActive()) { Heightmap* heightmap = editor->GetHeightmap(); heightmap->Load(undoFilename); editor->UpdateHeightmap(heightmap, updatedRect); } else { UpdateLandscapeHeightmap(undoFilename); } }
Heightmap Heightmap::operator-( Heightmap &other ) { Heightmap temp(Size); for(int j=0;j<Size;j++) for(int i=0;i<Size;i++) temp.put(i,j,at(i,j)-other.at(i,j)); return temp; }
float32 LandscapeEditorDrawSystem::GetHeightAtPoint(const Vector2& point) { Heightmap *heightmap = GetHeightmapProxy(); int32 x = (int32)point.x; int32 y = (int32)point.y; DVASSERT_MSG((x >= 0 && x < heightmap->Size()) && (y >= 0 && y < heightmap->Size()), "Point must be in heightmap coordinates"); int32 index = x + y * heightmap->Size(); float32 height = heightmap->Data()[index]; float32 maxHeight = GetLandscapeMaxHeight(); height *= maxHeight; height /= Heightmap::MAX_VALUE; return height; }
void LandscapeEditorHeightmap::UpdateHeightmap(const Rect &updatedRect) { Heightmap *heightmap = landscapesController->GetCurrentHeightmap(); Rect clippedRect; clippedRect.x = (float32)Clamp((int32)updatedRect.x, 0, heightmap->Size()-1); clippedRect.y = (float32)Clamp((int32)updatedRect.y, 0, heightmap->Size()-1); clippedRect.dx = Clamp((updatedRect.x + updatedRect.dx), 0.f, (float32)heightmap->Size() - 1.f) - clippedRect.x; clippedRect.dy = Clamp((updatedRect.y + updatedRect.dy), 0.f, (float32)heightmap->Size() - 1.f) - clippedRect.y; if(heightmapNode) { heightmapNode->UpdateHeightmapRect(clippedRect); } landscapesController->HeghtWasChanged(clippedRect); }
void LandscapeEditorHeightmap::ShowAction() { prevToolSize = 0.f; SceneData *activeScene = SceneDataManager::Instance()->SceneGetActive(); landscapesController = activeScene->GetLandscapesController(); landscapesController->CreateEditorLandscape(); SafeRetain(landscapesController); savedPath = workingLandscape->GetHeightmapPathname(); Heightmap *heightmap = landscapesController->GetCurrentHeightmap(); landscapeSize = heightmap->Size(); landscapesController->CursorEnable(); CreateTilemaskImage(); }
void CommandDrawHeightmap::Execute() { LandscapeEditorHeightmap* editor = GetEditor(); if (editor == NULL) { SetState(STATE_INVALID); return; } if (editor->IsActive()) { Heightmap* heightmap = editor->GetHeightmap(); heightmap->Load(redoFilename); editor->UpdateHeightmap(heightmap, updatedRect); } else { UpdateLandscapeHeightmap(redoFilename); } }
void CommandDrawHeightmap::Execute() { LandscapeEditorHeightmap* editor = GetEditor(); if (editor == NULL) { SetState(STATE_INVALID); return; } Heightmap* heightmap; editor->GetHeightmap(&heightmap); if (redoFilename == "") { redoFilename = SaveHeightmap(heightmap, "_" + GetRandomString(10)); } else { heightmap->Load(redoFilename); editor->UpdateHeightmap(heightmap); } }
int main(int argc, char** argv) { if (argc == 3 && strncmp(argv[1], "--convert", 9) == 0) { Configuration* config = new IniConfig(argv[2]); Heightmap* map = new Heightmap(config->getFloatValue("terrain","spacing")); if (map->loadFromImage(config->getValue("terrain","heightmap").c_str())) { std::cout << "Generating Terrain.." << std::endl; TerrainGenerator(map, config->getIntValue("terrain","chunksize"), config->getValue("out","filename").c_str()); std::cout << "..done" << std::endl; std::cout.flush(); } else std::cout << "Generation failed." << std::endl; return 0; } if (argc == 4 && strncmp(argv[1], "--load", 6) == 0) { int id = atoi(argv[3]); TerrainFileReader* reader = new TerrainFileReader(); reader->openFile(argv[2]); TerrainChunk* tc = reader->readId(id); if (tc == NULL || tc->getInfo()->getQuadId() != id) { std::cout << "Got ID" << tc->getInfo()->getQuadId() << " instead of " << id << std::endl; return 1; } else { std::cout << "Successfully got Terrainchunk " << id << std::endl; std::cout << "Spacing of Heightmap is " << tc->getHeightmap()->getSpacing() << " where origin is " << tc->getOrigin().x << "," << tc->getOrigin().y << " and center at " << tc->getCenter().x << "," << tc->getCenter().y << std::endl; } reader->closeFile(); delete tc; delete reader; } if (argc != 2 || strncmp(argv[1], "--run", 5) != 0) { std::cout << "Usage of '" << argv[0] << "'" <<std::endl; std::cout << "\nAvailable Parameter:" << "\n\t--convert terrain.desc" << "\n\t--load terrain.terr chunkid(=0)" << "\n\t--run" << std::endl; return 1; } int width, height; Configuration * win_config = new IniConfig("config.ini"); WindowHints* hints = new WindowHints(); hints->Fullscreen = win_config->getBooleanValue("Window","fullscreen"); hints->Width = win_config->getIntValue("Window","width"); hints->Height = win_config->getIntValue("Window","height"); GraphicsSystem* GSystem = new GraphicsSystem(GraphicsSystem::PROFILE_GL3, hints); if (GSystem->isError()) return -1; GraphicsContext* grctx = GSystem->getGraphicsContext(); Window* win = GSystem->getWindow(); TextureManager* tmgr = new TextureManager(grctx); ModelLoader* mmgr = new ModelLoader(grctx, tmgr); TerrainManager* terrmgr = new TerrainManager(grctx); Model* mdl, *mdl2; Camera* cam = new Camera(); win->getSize(&width, &height); cam->setScreen(width,height); cam->setupLens(65.0f, 1.0f, 1000.0f); if ((mdl = mmgr->loadAsset("Resources/Models/ant01.ms3d")) == NULL) std::cerr << "Could not load Model" << std::endl; if ((mdl2 = mmgr->loadAsset("Resources/Models/dwarf1.ms3d")) == NULL) std::cerr << "Could not load Model" << std::endl; ModelAnimationController mdlanictrl(mdl), mdlanictrl2(mdl2); mdlanictrl.addAnimation("idle", 52, 67, 0.25f, true); mdlanictrl.addAnimation("die", 30, 49, 0.25f, false); mdlanictrl2.addAnimation("begin_walk", 1, 2, 0.25f, false, "walk"); mdlanictrl2.addAnimation("walk", 2, 14, 0.25f, true); mdlanictrl2.addAnimation("jump", 28, 40, 0.5f, false, "begin_walk"); mdlanictrl2.addAnimation("idle", 292, 325, 0.25f, false, "idle2"); mdlanictrl2.addAnimation("idle2", 327, 360, 0.25f, true); mdlanictrl2.addAnimation("die", 230, 251, 0.25f, false); std::cout << "Using DesktopMode: " << width << "x" << height << std::endl; win->setTitle("Xng?! -> Yeah!"); Shader* sh = grctx->createShader(); if (!sh->loadFromFile("Shader/Animation.vs", "Shader/Animation.fs")) return 1; Shader* tsh = grctx->createShader(); if (!tsh->loadFromFile("Shader/Terrain.vs", "Shader/Terrain.fs")) return 1; Timer* t = new Timer(); double frames = 0; grctx->setClearColor(glm::vec4(1.0f, 0.5f, 0.25f, 1.0f)); t->start(); Terrain* terr = terrmgr->loadAsset("Resources/terrain/terrain.terr"); terr->setDetail(0.05f,cam); glm::mat4 mdlm = glm::scale( glm::translate(glm::mat4(1.0f), glm::vec3(5.0f, -5.0f, -20.0f)), glm::vec3(0.5f)); glm::mat4 mdlm2 = glm::scale( glm::translate(glm::mat4(1.0f), glm::vec3(-5.0f, -5.0f, -20.0f)), glm::vec3(0.18f)); mdlm = glm::rotate(mdlm, 180.0f, glm::vec3(0.0f, 1.0f, 0.0f)); mdlm2 = glm::rotate(mdlm2, 180.0f, glm::vec3(0.0f, 1.0f, 0.0f)); glm::vec3 cam_pos = glm::vec3(0.0f,0.0f,0.0f); glm::quat cam_orient = glm::quat(); float speed = 0.0f; float deltaTime = 0; float second = t->getMilli(); float lastTime = second; while (win->isOpen()) { second = t->getMilli(); deltaTime = second - lastTime; lastTime = second; if (glfwGetKey(GLFW_KEY_ESC)) break; if (glfwGetKey(GLFW_KEY_SPACE)) mdlanictrl2.setActiveAnimation("jump"); if (glfwGetKey('W')) mdlanictrl2.setActiveAnimation("begin_walk"); if (glfwGetKey('S')) mdlanictrl2.setActiveAnimation("idle"); if (glfwGetKey('F')) mdlanictrl.setActiveAnimation("die"); if (glfwGetKey('G')) mdlanictrl2.setActiveAnimation("die"); if (glfwGetKey('A')) mdlm2 = glm::rotate(mdlm2, -0.3f, glm::vec3(0.0f, 1.0f, 0.0f)); if (glfwGetKey('D')) mdlm2 = glm::rotate(mdlm2, 0.3f, glm::vec3(0.0f, 1.0f, 0.0f)); if( glfwGetKey(GLFW_KEY_LSHIFT) || glfwGetKey(GLFW_KEY_RSHIFT)) speed = 1.0f; else speed = 0.1f; if (glfwGetKey('I')) cam_pos += glm::cross(cam->getUpVector(),cam->getRightVector()) * speed * deltaTime; if (glfwGetKey('K')) cam_pos -= glm::cross(cam->getUpVector(),cam->getRightVector()) * speed * deltaTime; if (glfwGetKey('J')) cam_pos -= cam->getRightVector() * speed * deltaTime; if (glfwGetKey('L')) cam_pos += cam->getRightVector() * speed * deltaTime; if (glfwGetKey('O')) cam_pos += cam->getUpVector() * speed * deltaTime; if (glfwGetKey('P')) cam_pos -= cam->getUpVector() * speed * deltaTime; if(glfwGetKey(GLFW_KEY_LEFT)) cam_orient = glm::rotate(cam_orient,speed * deltaTime,glm::vec3(0.0f,1.0f,0.0f)); if(glfwGetKey(GLFW_KEY_RIGHT)) cam_orient =glm::rotate(cam_orient,-speed * deltaTime,glm::vec3(0.0f,1.0f,0.0f)); if(glfwGetKey(GLFW_KEY_UP)) cam_orient = glm::rotate(cam_orient,speed * deltaTime,glm::vec3(1.0f,0.0f,0.0f)); if(glfwGetKey(GLFW_KEY_DOWN)) cam_orient = glm::rotate(cam_orient,-speed * deltaTime,glm::vec3(1.0f,0.0f,0.0f)); cam_pos.y = terr->getHeightAt(cam_pos.x,cam_pos.z) + 5; cam->setPosition(cam_pos); cam->setOrientation(cam_orient); mdlanictrl.update(deltaTime); mdlanictrl2.update(deltaTime); grctx->clearDisplay(); grctx->setShader(sh); grctx->setProjectionMatrix(cam->getLens()); grctx->setViewMatrix(cam->getView()); grctx->setModelMatrix(&mdlm); for (int i = 0; i < mdl->getNumMeshes(); i++) { grctx->setMesh(mdl->getMesh(i)); grctx->setMaterial(mdl->getMaterial(mdl->getMesh(i)->getMaterialId())); grctx->setBoneTransformation(mdlanictrl.getBoneTransformation(), mdlanictrl.getNumBones()); grctx->draw(); } grctx->setModelMatrix(&mdlm2); for (int i = 0; i < mdl2->getNumMeshes(); i++) { grctx->setMesh(mdl2->getMesh(i)); grctx->setMaterial(mdl2->getMaterial(mdl2->getMesh(i)->getMaterialId())); grctx->setBoneTransformation(mdlanictrl2.getBoneTransformation(), mdlanictrl2.getNumBones()); grctx->draw(); } grctx->setShader(tsh); grctx->setProjectionMatrix(cam->getLens()); grctx->setViewMatrix(cam->getView()); terr->selectNodes(cam); grctx->swapBuffers(); frames++; } t->end(); delete sh; mmgr->removeAsset("Resources/Models/dwarf1.ms3d"); mmgr->removeAsset("Resources/Models/ant01.ms3d"); std::cout << "TpF: " << t->getLastMilli() / frames << " mspf was " << frames << " Frames in " << t->getLastMilli() << "ms or " << frames / t->getLastSecond() << "fps" << std::endl; delete mmgr; delete tmgr; delete t; delete GSystem; return 0; }
void Blendmap::Generate (Heightmap *rootHm, int lodLevel, float hmScale, float hmOffset) { Heightmap *heightmap = rootHm->GetLevel(-lodLevel); // Allocate the blendmap image AlphaImage *bm = new AlphaImage; bm->Alloc (heightmap->w-1, heightmap->h-1); // texture dimensions have to be power-of-two Blendmap::GeneratorInfo *gi = generatorInfo; // Calculate blend factors using the function parameters and heightmap input: for (int y=0;y<bm->h;y++) { for (int x=0;x<bm->w;x++) { float h = (heightmap->at (x,y) - hmOffset) / hmScale; float factor=1.0f; if(h < gi->minHeight - gi->minHeightFuzzy) { bm->at (x,y) = 0.0f; continue; } else if (gi->minHeightFuzzy > 0.0f && h < gi->minHeight + gi->minHeightFuzzy) factor = (h - (gi->minHeight - gi->minHeightFuzzy)) / (2.0f * gi->minHeightFuzzy); if(h > gi->maxHeight + gi->maxHeightFuzzy) { bm->at (x,y) = 0.0f; continue; } else if (gi->maxHeightFuzzy > 0.0f && h > gi->maxHeight - gi->maxHeightFuzzy) factor *= ((gi->maxHeight + gi->maxHeightFuzzy) - h) / (2.0f * gi->maxHeightFuzzy); float norm_y = 0.0f; if (heightmap->normalData) { uchar *cnorm = heightmap->GetNormal (x,y); norm_y = cnorm[1] / 255.0f * 2.0f - 1.0f; if (norm_y > 1.0f) norm_y = 1.0f; } else { Vector3 tangent, binormal; CalculateTangents(heightmap, x,y,tangent,binormal); Vector3 normal = tangent.cross(binormal); normal.ANormalize(); norm_y = normal.y; } // flatness=dotproduct of surface normal with up vector float slope = 1.0f - fabs(norm_y); if (slope < gi->minSlope - gi->minSlopeFuzzy) { bm->at (x,y) = 0.0f; continue; } else if (gi->minSlopeFuzzy > 0.0f && slope < gi->minSlope + gi->minSlopeFuzzy) factor *= (h - (gi->minSlope - gi->minSlopeFuzzy)) / ( 2.0f * gi->minSlopeFuzzy); if (slope > gi->maxSlope + gi->maxSlopeFuzzy) { bm->at (x,y) = 0.0f; continue; } else if (gi->maxSlopeFuzzy > 0.0f && slope > gi->maxSlope - gi->maxSlopeFuzzy) factor *= ((gi->maxSlope + gi->maxSlopeFuzzy) - h) / (2.0f * gi->maxSlopeFuzzy); factor *= gi->coverage; factor *= (rand () < gi->noise * RAND_MAX) ? 0.0f : 1.0f; bm->at (x,y) = factor; } } BlendmapFilter(bm); image = bm; }
Lightmap::Lightmap(Heightmap *orghm, int level, int shadowLevelDif, LightingInfo *li) { const spring_time startTicks = spring_gettime(); tilesize.x = orghm->w-1; tilesize.y = orghm->h-1; name = "lightmap"; Heightmap *hm; int w; for(;;) { hm = orghm->GetLevel(-level); w=hm->w-1; GLint maxw; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxw); if (w > maxw) level ++; else break; } shadowLevelDif=0; Heightmap *shadowhm = orghm->GetLevel(-(level+shadowLevelDif)); int shadowScale=1<<shadowLevelDif; int shadowW=shadowhm->w-1; assert (w/shadowW == shadowScale); //float org2c = w/float(orghm->w-1); //float c2org = (float)(orghm->w-1)/w; float *centerhm = new float[w*w]; Vector3 *shading = new Vector3[w*w]; for (int y=0;y<w;y++) for (int x=0;x<w;x++) { centerhm[y*w+x] =/* hm->scale * */ 0.25f * ( (int)hm->at(x,y)+ (int)hm->at(x+1,y)+ (int)hm->at(x,y+1) + (int)hm->at(x+1,y+1) ); //+ hm->offset; shading[y*w+x] = li->ambient; } uchar *lightMap = new uchar[shadowW*shadowW]; for (std::vector<StaticLight>::const_iterator l=li->staticLights.begin();l!=li->staticLights.end();++l) { float lightx; float lighty; if (l->directional) { lightx = l->position.x; lighty = l->position.y; } else { lightx = (int)(l->position.x / shadowhm->squareSize); lighty = (int)(l->position.z / shadowhm->squareSize); } CalculateShadows(lightMap, shadowW, lightx, lighty, l->position.y, centerhm, w, shadowScale, l->directional); for (int y=0;y<w;y++) { for (int x=0;x<w;x++) { if (!lightMap[(y*shadowW+x)/shadowScale]) continue; Vector3 wp; if (l->directional) wp = l->position; else wp = l->position - Vector3((x+0.5f)*hm->squareSize,centerhm[y*w+x],(y+0.5f)*hm->squareSize); uchar* normal = hm->GetNormal (x,y); Vector3 normv((2 * (int)normal[0] - 256)/255.0f, (2 * (int)normal[1] - 256)/255.0f, (2 * (int)normal[2] - 256)/255.0f); wp.ANormalize(); float dot = wp.dot(normv); if(dot < 0.0f) dot = 0.0f; if(dot > 1.0f) dot = 1.0f; dot *= lightMap[(y*shadowW+x)/shadowScale]*(1.0f/255.0f); shading[y*w+x] += l->color * dot; } } } delete[] lightMap; glGenTextures(1,&shadingTex); glBindTexture (GL_TEXTURE_2D, shadingTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); uchar *shadingTexData=new uchar[w*w*4]; for(int y=0;y<w;y++) { for (int x=0;x<w;x++) { shadingTexData[(y*w+x)*4+0] = (uchar)(min(1.0f, shading[y*w+x].x) * 255); shadingTexData[(y*w+x)*4+1] = (uchar)(min(1.0f, shading[y*w+x].y) * 255); shadingTexData[(y*w+x)*4+2] = (uchar)(min(1.0f, shading[y*w+x].z) * 255); shadingTexData[(y*w+x)*4+3] = CReadMap::EncodeHeight(centerhm[w*y+x]); } } SaveImage ("lightmap.png", 4, IL_UNSIGNED_BYTE, w,w, shadingTexData); glBuildMipmaps(GL_TEXTURE_2D, 4, w,w, GL_RGBA, GL_UNSIGNED_BYTE, shadingTexData); delete[] shadingTexData; id = shadingTex; delete[] shading; delete[] centerhm; const spring_duration numTicks = spring_gettime() - startTicks; d_trace ("Lightmap generation: %2.3f seconds\n", spring_tomsecs(numTicks) * 0.001f); }
Lightmap::Lightmap(Heightmap *orghm, int level, LightingInfo *li) { int startTicks = SDL_GetTicks(); tilesize.x = orghm->w-1; tilesize.y = orghm->h-1; name = "lightmap"; Heightmap *hm = orghm->GetLevel(-level); int w=hm->w-1; float org2c = w/float(orghm->w-1); float c2org = (float)(orghm->w-1)/w; float *centerhm = new float[w*w]; Vector3 *shading = new Vector3[w*w]; for (int y=0;y<w;y++) for (int x=0;x<w;x++) { centerhm[y*w+x] = hm->scale * 0.25f * ( (int)hm->at(x,y)+ (int)hm->at(x+1,y)+ (int)hm->at(x,y+1) + (int)hm->at(x+1,y+1) ) + hm->offset; shading[y*w+x] = li->ambient; } uchar *lightMap = new uchar[w*w]; int lightIndex = 0; for (std::vector<StaticLight>::const_iterator l=li->staticLights.begin();l!=li->staticLights.end();++l) { memset(lightMap, 255, w*w); // 255 is lit, 0 is unlit int lightx = (int)(l->position.x / hm->squareSize); int lighty = (int)(l->position.z / hm->squareSize); for (int y=0;y<w;y++) { for (int x=0;x<w;x++) { if (!lightMap[y*w+x]) // shadowed pixels can't shadow other pixels continue; if (x==lightx && y==lighty) continue; float dx = lightx-x; float dy = lighty-y; float h = centerhm[y*w+x]; float dh = l->position.y-h; float len = sqrtf(dx*dx+dy*dy); const float step = 5.0f; float invLength2d = step/len; dx *= invLength2d; dy *= invLength2d; dh *= invLength2d; float px = x + dx, py = y + dy; h += dh; while (px >= 0.0f && px < w && py >= 0.0f && py < w && len >= 0.0f) { int index = (int)py * w + (int)px; if (centerhm[index] > h + 2.0f) { lightMap[y*w+x]=0; break; } px += dx; py += dy; h += dh; len -= step; } } } BlurGrayscaleImage(w,w,lightMap); char sm_fn[64]; SNPRINTF(sm_fn, sizeof(sm_fn), "shadowmap%d.bmp", lightIndex++); SaveImage(sm_fn, 1, IL_UNSIGNED_BYTE, w,w, lightMap); for (int y=0;y<w;y++) { for (int x=0;x<w;x++) { if (!lightMap[y*w+x]) continue; Vector3 wp((x+0.5f)*hm->squareSize,centerhm[y*w+x],(y+0.5f)*hm->squareSize); wp = l->position - wp; uchar* normal = hm->GetNormal (x,y); Vector3 normv((2 * (int)normal[0] - 256)/255.0f, (2 * (int)normal[1] - 256)/255.0f, (2 * (int)normal[2] - 256)/255.0f); wp.Normalize(); float dot = wp.dot(normv); if(dot < 0.0f) dot = 0.0f; if(dot > 1.0f) dot = 1.0f; dot *= lightMap[y*w+x]*(1.0f/255.0f); shading[y*w+x] += l->color * dot; } } } delete[] lightMap; shadingTex.Bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); uchar *shadingTexData=new uchar[w*w*3], *td = shadingTexData; for(int y=0;y<w;y++) { for (int x=0;x<w;x++) { shadingTexData[(y*w+x)*3+0] = (uchar)(min(1.0f, shading[y*w+x].x) * 255); shadingTexData[(y*w+x)*3+1] = (uchar)(min(1.0f, shading[y*w+x].y) * 255); shadingTexData[(y*w+x)*3+2] = (uchar)(min(1.0f, shading[y*w+x].z) * 255); } } SaveImage ("lightmap.png", 3, IL_UNSIGNED_BYTE, w,w, shadingTexData); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w,w, GL_RGB, GL_UNSIGNED_BYTE, shadingTexData); delete[] shadingTexData; id = shadingTex; delete[] shading; delete[] centerhm; int numTicks = SDL_GetTicks() - startTicks; d_trace ("Lightmap generation: %2.3f seconds\n", numTicks * 0.001f); }
void RenderDataManager::InitializeNodeNormalMap(TQuad* q, int cfgNormalMapLevel) { QuadRenderData* rd = q->renderData; if (q->isLeaf()) { if (rd->normalMap) { glDeleteTextures(1, &rd->normalMap); rd->normalMap = 0; rd->normalMapW = 0; } return; } // find the right level heightmap to generate the normal map from Heightmap* hm = roothm; int level = 0; for (; hm->highDetail; hm = hm->highDetail, level++) if (level == q->depth + cfgNormalMapLevel) break; // calculate dimensions const int scale = 1 << (level - q->depth); size_t w = QUAD_W * scale + 1; const size_t h = w; const int startx = q->hmPos.x * scale; // use power-of-two texture sizes if required size_t texw = 1; //if (GLEW_ARB_texture_non_power_of_two) texw = w; //else while (texw < w) texw *= 2; // if not yet created, create a texture for it GLuint texture; if (rd->normalMap && (rd->normalMapW == w) && (rd->normalMapTexWidth == texw)) { texture = rd->normalMap; glBindTexture(GL_TEXTURE_2D, texture); } else { if (rd->normalMap) glDeleteTextures(1,&rd->normalMap); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); rd->normalMap = texture; rd->normalMapW = w; rd->normalMapTexWidth = texw; } // allocate temporary storage for normals uchar* normals = new uchar[texw*texw*3]; // calculate normals for (size_t y=0; y<h; y++) { const uchar* src = hm->GetNormal(startx, y + q->hmPos.y * scale); memcpy(&normals [3 * y * texw], src, 3 * w); } // fill texture glTexImage2D(GL_TEXTURE_2D, 0, 3, texw,texw,0, GL_RGB, GL_UNSIGNED_BYTE, normals); delete[] normals; }
bool Map::IsInMoonBetaSkeletonHeightmap(const Vector2d & p, const Vector2d & a, const Vector2d & b, float gamma, Heightmap &map) { float distAP = map.getDistance(a, p); float distBP = map.getDistance(b, p); float distAB = map.getDistance(a, b); return std::abs(std::pow(distAP, gamma) + std::pow(distBP, gamma) - std::pow(distAB, gamma)) < 1.f; }