/// erzeugt Rand-Vertex void TerrainRenderer::UpdateBorderVertex(const MapPoint pt, const GameWorldViewer& gwv) { /// @todo GetTerrainX und Co durch GetTerrainXA ausdrücken Vertex& vertex = GetVertex(pt); vertex.borderPos[0] = ( GetTerrainAround(pt, 5) + GetTerrain(pt) + GetTerrainAround(pt, 4) ) / 3.0f; vertex.borderColor[0] = ( GetColor(gwv.GetNeighbour(pt, 5)) + GetColor(pt) + GetColor(gwv.GetNeighbour(pt, 4)) ) / 3.0f; vertex.borderPos[1] = ( GetTerrainAround(pt, 3) + GetTerrain(pt) + GetTerrainAround(pt, 4) ) / 3.0f; vertex.borderColor[1] = ( GetColor(gwv.GetNeighbour(pt, 3)) + GetColor(pt) + GetColor(gwv.GetNeighbour(pt, 4)) ) / 3.0f; }
static void DS_Place(MECH * ds, MECH * mech, int frombay) { int i; int nx, ny; MAP *mech_map; for(i = 0; i < NUM_BAYS; i++) if(AeroBay(ds, i) == frombay) break; if(i == NUM_BAYS || !(mech_map = getMap(mech->mapindex))) { /* i _should_ be set, otherwise things are deeply disturbing */ mech_notify(mech, MECHALL, "Reality collapse imminent."); return; } i = Find_DS_Bay_Dir(ds, i); nx = dirs[(DSBearMod(ds) + i) % 6][0] + MechX(ds); ny = dirs[(DSBearMod(ds) + i) % 6][1] + MechY(ds) + KLUDGE(MechX(ds), nx); nx = BOUNDED(0, nx, mech_map->map_width - 1); ny = BOUNDED(0, ny, mech_map->map_height - 1); /* snippage from mech_Rsetxy */ MechX(mech) = nx; MechLastX(mech) = nx; MechY(mech) = ny; MechLastY(mech) = ny; MechZ(mech) = MechZ(ds); MechElev(mech) = MechElev(ds); MapCoordToRealCoord(MechX(mech), MechY(mech), &MechFX(mech), &MechFY(mech)); MechTerrain(mech) = GetTerrain(mech_map, MechX(mech), MechY(mech)); }
bool CCourse::LoadTerrainMap () { CImage terrImage; if (!terrImage.LoadPng (CourseDir.c_str(), "terrain.png", true)) { Message ("unable to open terrain.png"); return false; } if (nx != terrImage.nx || ny != terrImage.ny) { Message ("wrong terrain size", ""); } try { terrain = new char[nx * ny]; } catch(...) { Message ("Allocation failed in LoadTerrainMap", ""); } int pad = 0; for (int y=0; y<ny; y++) { for (int x=0; x<nx; x++) { int imgidx = (x+nx*y) * terrImage.depth + pad; int arridx = (nx-1-x) + nx * (ny-1-y); int terr = GetTerrain (&terrImage.data[imgidx]); terrain[arridx] = terr; if (TerrList[terr].texture == NULL) { TerrList[terr].texture = new TTexture(); TerrList[terr].texture->LoadMipmap(param.terr_dir, TerrList[terr].textureFile, 1); } } pad += (nx * terrImage.depth) % 4; } return true; }
void FuelCellManager::OnLocationEntry() { if (GetGameMode() == AMJU_MODE_EDIT) { // Add node to Scene Graph m_sceneNode = new Ve1Node(this); SceneNode* root = GetVe1SceneGraph()->GetRootNode(SceneGraph::AMJU_OPAQUE); Assert(root); root->AddChild(m_sceneNode); m_sceneNode->SetAABB(m_aabb); } // else... ???? // Create fuel cells static int id = 20000; for (int i = 0; i < 10; i++) { FuelCell* f = new FuelCell; f->SetId(id++); float s = ROConfig()->GetFloat("fuel-cell-spread", 200.0f); Vec3f r(Rnd(-s, s), Rnd(0, s), Rnd(-s, s)); Vec3f p = GetPos() + r; if (TerrainReady()) { GetTerrain()->GetCollisionMesh()->GetY(Vec2f(p.x, p.z), &p.y); // TODO TEMP TEST Set all food to y = 0 } f->SetPos(p); f->Load(0); TheGame::Instance()->AddGameObject(f); f->OnLocationEntry(); } }
CTexture* CProject::GetWaterTexture(int index) { const int currentFrame = (int)m_waterLists[index].frame; if (!m_waterLists[index].textures[currentFrame]) m_waterLists[index].textures[currentFrame] = GetTerrain(m_waterLists[index].textureIDs[currentFrame]); return m_waterLists[index].textures[currentFrame]; }
VEditableTerrainSector* VUndoableSectorAction::GetSector() { VEditableTerrain *pTerrain = GetTerrain(); VASSERT(pTerrain); VEditableTerrainSector *pSector = pTerrain->GetSector(m_iSectorX,m_iSectorY); pSector->EnsureLoaded(); return pSector; }
TerrainRenderer::PointF TerrainRenderer::GetTerrainAround(MapPoint pt, const unsigned dir) { PointI ptNb = GetPointAround(PointI(pt), dir); PointI offset; MapPoint t = ConvertCoords(ptNb, &offset); return GetTerrain(t) + PointF(offset); }
void TerrainRenderer::UpdateTrianglePos(const MapPoint pt, const GameWorldViewer& gwv, const bool update) { unsigned int pos = GetTriangleIdx(pt); gl_vertices[pos][0] = GetTerrainAround(pt, 4); gl_vertices[pos][1] = GetTerrain(pt); gl_vertices[pos][2] = GetTerrainAround(pt, 5); ++pos; gl_vertices[pos][0] = GetTerrain(pt); gl_vertices[pos][1] = GetTerrainAround(pt, 4); gl_vertices[pos][2] = GetTerrainAround(pt, 3); if(update && vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, (pos - 1) * sizeof(Triangle), 2 * sizeof(Triangle), &gl_vertices[pos - 1]); } }
void Ve1ObjectChar::Update() { // Not safe to do anything if the Terrain has not been created yet if (!TerrainReady()) { return; } // TODO Not if underwater ? // TODO Put in base class, so we can drop things ? static const float GRAVITY = ROConfig()->GetFloat("gravity", -50.0f); m_acc.y = GRAVITY; Ve1Object::Update(); if (IsHidden()) { return; } // Handle wall collisions with terrain and any building if (HandleWalls(GetTerrain()->GetCollisionMesh(), m_oldPos, m_pos)) { m_recalcHeading = true; } HasCollisionMesh* h = dynamic_cast<HasCollisionMesh*>(m_collidingObject); if (h) { if (HandleWalls(h->GetCollisionMesh(), m_oldPos, m_pos)) { m_recalcHeading = true; } } HandleFloor(GetTerrain()->GetCollisionMesh()); if (h) { HandleFloor(h->GetCollisionMesh()); } // Recalc heading if we are not colliding if (m_collidingObject) { m_recalcHeading = true; } if (true) //m_recalcHeading) { m_recalcHeading = false; if (m_isMoving) { MoveTo(m_newPos); } } m_collidingObject = 0; /* // Stop moving if we are close enough to the destination // TODO This ends up happening every frame, only do it if we are moving if (m_isMoving) { Vec3f dir = GetPos() - m_newPos; dir.y = 0; // ignore y coord for now if (dir.SqLen() < 1.0f) // TODO CONFIG { SetVel(Vec3f(0, 0, 0)); m_newPos = GetPos(); SetArrowVis(false); m_isMoving = false; } } else { Assert(GetVel().SqLen() == 0); } */ if (m_sceneNode) { Matrix m; m.Translate(m_pos); m_sceneNode->SetLocalTransform(m); //m_sceneNode->Update(); // done for whole scene graph elsewhere if (m_shadow) { // Set shadow AABB to same as Scene Node so we don't cull it by mistake m_shadow->SetAABB(*m_sceneNode->GetAABB()); } if (m_effect) { m_effect->SetAABB(*m_sceneNode->GetAABB()); } static const float XSIZE = ROConfig()->GetFloat("player-aabb-x", 30.0f); static const float YSIZE = ROConfig()->GetFloat("player-aabb-y", 100.0f); GetAABB()->Set( m_pos.x - XSIZE, m_pos.x + XSIZE, m_pos.y, m_pos.y + YSIZE, m_pos.z - XSIZE, m_pos.z + XSIZE); /* NOT FOR 2D TurnToFaceDir(); */ Ve1Character* vc = dynamic_cast<Ve1Character*>(m_sceneNode.GetPtr()); if (vc) //// && vc->GetMd2()) { Vec3f v = m_vel; v.y = 0; float speed = v.SqLen(); // TODO Simplify -- either moving or idle. // NB Speeds should be an avatar variable and level up static const float MAX_SPEED = 100.0f; // TODO CONFIG static const float RUN_SPEED = MAX_SPEED * 0.5f; static const float WALK_SPEED = RUN_SPEED * 0.5f; if (speed > RUN_SPEED) { vc->SetAnim(Ve1Character::ANIM_RUN); } else if (speed > WALK_SPEED) { vc->SetAnim(Ve1Character::ANIM_WALK); } else { vc->SetAnim(Ve1Character::ANIM_IDLE); } } } }
void TerrainRenderer::PrepareWaysPoint(PreparedRoads& sorted_roads, const GameWorldView& gwv, MapPoint t, const PointI& offset) { PointI startPos = PointI(GetTerrain(t)) - gwv.GetOffset() + offset; GameWorldViewer& gwViewer = gwv.GetGameWorldViewer(); Visibility visibility = gwViewer.GetVisibility(t); int totalWidth = gwViewer.GetWidth() * TR_W; int totalHeight = gwViewer.GetHeight() * TR_H; // Wegtypen für die drei Richtungen for(unsigned dir = 0; dir < 3; ++dir) { unsigned char type = gwViewer.GetVisibleRoad(t, dir, visibility); if (!type) continue; MapPoint ta = gwViewer.GetNeighbour(t, 3 + dir); PointI endPos = PointI(GetTerrain(ta)) - gwv.GetOffset() + offset; PointI diff = startPos - endPos; // Gehen wir über einen Kartenrand (horizontale Richung?) if(std::abs(diff.x) >= totalWidth / 2) { if(std::abs(endPos.x - totalWidth - startPos.x) < std::abs(diff.x)) endPos.x -= totalWidth; else endPos.x += totalWidth; } // Und dasselbe für vertikale Richtung if(std::abs(diff.y) >= totalHeight / 2) { if(std::abs(endPos.y - totalHeight - startPos.y) < std::abs(diff.y)) endPos.y -= totalHeight; else endPos.y += totalHeight; } --type; // Wegtypen "konvertieren" switch(type) { case RoadSegment::RT_DONKEY: case RoadSegment::RT_NORMAL: { TerrainType t1 = gwViewer.GetTerrainAround(t, dir + 2); TerrainType t2 = gwViewer.GetTerrainAround(t, dir + 3); // Prüfen, ob Bergwege gezeichnet werden müssen, indem man guckt, ob der Weg einen // Berg "streift" oder auch eine Bergwiese if(TerrainData::IsMountain(t1) || TerrainData::IsMountain(t2)) type = 3; break; } case RoadSegment::RT_BOAT: type = 2; break; } sorted_roads[type].push_back( PreparedRoad(type, startPos, endPos, GetColor(t), GetColor(ta), dir) ); } }
/// Erzeugt die Dreiecke für die Ränder void TerrainRenderer::UpdateBorderTrianglePos(const MapPoint pt, const GameWorldViewer& gwv, const bool update) { unsigned int pos = GetVertexIdx(pt); // Für VBO-Aktualisierung: // Erzeugte Ränder zählen unsigned count_borders = 0; // Erstes Offset merken unsigned first_offset = 0; // Rand links - rechts for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].left_right[i]) continue; unsigned int offset = borders[pos].left_right_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset][i ? 0 : 2] = GetTerrain(pt); gl_vertices[offset][1 ] = GetTerrainAround(pt, 4); gl_vertices[offset][i ? 2 : 0] = GetB(pt, i); ++count_borders; } // Rand rechts - links for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].right_left[i]) continue; unsigned int offset = borders[pos].right_left_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset][i ? 2 : 0] = GetTerrainAround(pt, 4); gl_vertices[offset][1 ] = GetTerrainAround(pt, 3); if(i == 0) gl_vertices[offset][2] = GetB(pt, 1); else gl_vertices[offset][0] = GetBAround(pt, 0, 3); ++count_borders; } // Rand oben - unten for(unsigned char i = 0; i < 2; ++i) { if(!borders[pos].top_down[i]) continue; unsigned int offset = borders[pos].top_down_offset[i]; if(!first_offset) first_offset = offset; gl_vertices[offset][i ? 2 : 0] = GetTerrainAround(pt, 5); gl_vertices[offset][1 ] = GetTerrainAround(pt, 4); if(i == 0) gl_vertices[offset][2] = GetB(pt, i); else gl_vertices[offset][0] = GetBAround(pt, i, 5); //x - i + i * rt, y + i, i ++count_borders; } /// Bei Vertexbuffern das die Daten aktualisieren if(update && vboBuffersUsed) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_vertices); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, first_offset * sizeof(Triangle), count_borders * sizeof(Triangle), &gl_vertices[first_offset]); } }
void MapTerrainT::Render3D(Renderer3DT& Renderer) const { TerrainT::ViewInfoT VI; const wxSize WinSize=Renderer.GetViewWin3D().GetClientSize(); const CameraT& Camera =Renderer.GetViewWin3D().GetCamera(); const Plane3fT* Planes =Renderer.GetViewFrustumPlanes(); const float tau =4.0; // Error tolerance in pixel. const float fov_y =Camera.VerticalFOV; const float fov_x =2.0*atan(float(WinSize.GetWidth())/float(WinSize.GetHeight())*tan((fov_y*3.14159265358979323846/180.0)/2.0)); const float kappa =tau/WinSize.GetWidth()*fov_x; VI.cull =true; VI.nu =kappa>0.0 ? 1.0/kappa : 999999.0; // Inverse of error tolerance in radians. VI.nu_min =VI.nu*2.0/3.0; // Lower morph parameter. VI.nu_max =VI.nu; // Upper morph parameter. VI.viewpoint=Camera.Pos; for (unsigned long i=0; i<5; i++) // We don't need the sixth (the "far") plane. VI.viewplanes[i]=Planes[i]; // Setup texturing for the terrain, using automatic texture coordinates generation. const BoundingBox3fT& BB=m_TerrainBounds; const float CoordPlane1[4]={ 1.0f/(BB.Max.x-BB.Min.x), 0.0f, 0.0f, -BB.Min.x/(BB.Max.x-BB.Min.x) }; const float CoordPlane2[4]={ 0.0f, -1.0f/(BB.Max.y-BB.Min.y), 0.0f, BB.Max.y/(BB.Max.y-BB.Min.y) }; // Texture y-axis points top-down! MatSys::Renderer->SetGenPurposeRenderingParam( 4, CoordPlane1[0]); MatSys::Renderer->SetGenPurposeRenderingParam( 5, CoordPlane1[1]); MatSys::Renderer->SetGenPurposeRenderingParam( 6, CoordPlane1[2]); MatSys::Renderer->SetGenPurposeRenderingParam( 7, CoordPlane1[3]); MatSys::Renderer->SetGenPurposeRenderingParam( 8, CoordPlane2[0]); MatSys::Renderer->SetGenPurposeRenderingParam( 9, CoordPlane2[1]); MatSys::Renderer->SetGenPurposeRenderingParam(10, CoordPlane2[2]); MatSys::Renderer->SetGenPurposeRenderingParam(11, CoordPlane2[3]); // Finally, draw the terrain. m_TerrainMesh.Vertices.Overwrite(); #if 1 const ArrayT<Vector3fT>& VectorStrip=GetTerrain().ComputeVectorStrip(VI); m_TerrainMesh.Vertices.PushBackEmpty(VectorStrip.Size()); for (unsigned long VNr=0; VNr<VectorStrip.Size(); VNr++) m_TerrainMesh.Vertices[VNr].SetOrigin(VectorStrip[VNr]); #else if (/*VI_morph*/ true) { const ArrayT<Vector3fT>& VectorStrip=GetTerrain().ComputeVectorStripByMorphing(VI); m_TerrainMesh.Vertices.PushBackEmpty(VectorStrip.Size()-1); // Note that the first VectorT at VectorStrip[0] must be skipped! for (unsigned long VNr=1; VNr<VectorStrip.Size(); VNr++) m_TerrainMesh.Vertices[VNr-1].SetOrigin(VectorStrip[VNr]); } else { const ArrayT<unsigned long>& IdxStrip=GetTerrain().ComputeIndexStripByRefinement(VI); const TerrainT::VertexT* Vertices=GetTerrain().GetVertices(); m_TerrainMesh.Vertices.PushBackEmpty(IdxStrip.Size()-1); // Note that the first index at IdxStrip[0] must be skipped! for (unsigned long IdxNr=1; IdxNr<IdxStrip.Size(); IdxNr++) m_TerrainMesh.Vertices[IdxNr-1].SetOrigin(Vertices[IdxStrip[IdxNr]]); } #endif MatSys::Renderer->SetCurrentMaterial(m_Material->GetRenderMaterial(true /*Terrains are always in "Full Material" mode.*/)); // MatSys::Renderer->SetCurrentLightMap(LightMapTexture); // MatSys::Renderer->SetCurrentLightDirMap(NULL); // The MatSys provides a default for LightDirMaps when NULL is set. MatSys::Renderer->RenderMesh(m_TerrainMesh); if (IsSelected()) { // Todo: Set all vertex colors to yellow. MatSys::Renderer->SetCurrentMaterial(Renderer.GetRMatWireframe_OffsetZ()); MatSys::Renderer->RenderMesh(m_TerrainMesh); } // Render tool if its bounding box has volume. if (m_ToolBounds.Min!=m_ToolBounds.Max) { const BoundingBox3fT& BB=m_ToolBounds; const float CoordPlane1[4]={ 1.0f/(BB.Max.x-BB.Min.x), 0.0f, 0.0f, -BB.Min.x/(BB.Max.x-BB.Min.x) }; const float CoordPlane2[4]={ 0.0f, -1.0f/(BB.Max.y-BB.Min.y), 0.0f, BB.Max.y/(BB.Max.y-BB.Min.y) }; // Texture y-axis points top-down! MatSys::Renderer->SetGenPurposeRenderingParam( 4, CoordPlane1[0]); MatSys::Renderer->SetGenPurposeRenderingParam( 5, CoordPlane1[1]); MatSys::Renderer->SetGenPurposeRenderingParam( 6, CoordPlane1[2]); MatSys::Renderer->SetGenPurposeRenderingParam( 7, CoordPlane1[3]); MatSys::Renderer->SetGenPurposeRenderingParam( 8, CoordPlane2[0]); MatSys::Renderer->SetGenPurposeRenderingParam( 9, CoordPlane2[1]); MatSys::Renderer->SetGenPurposeRenderingParam(10, CoordPlane2[2]); MatSys::Renderer->SetGenPurposeRenderingParam(11, CoordPlane2[3]); if (m_RenderEyeDropper) MatSys::Renderer->SetCurrentMaterial(Renderer.GetRMatTerrainEyeDropper()); else MatSys::Renderer->SetCurrentMaterial(Renderer.GetRMatTerrainEditorTool()); MatSys::Renderer->RenderMesh(m_TerrainMesh); } }