bool SetupDefaultStructures(const vtString &fname) { if (fname != "") { if (g_DefaultStructures.ReadXML(fname)) return true; } // else supply some internal defaults and let the user know the load failed vtBuilding *pBld = g_DefaultStructures.NewBuilding(); vtLevel *pLevel; DPolygon2 DefaultFootprint; // Single edge DefaultFootprint.resize(1); DefaultFootprint[0].Append(DPoint2(0.0, 0.0)); DefaultFootprint[0].Append(DPoint2(0.0, 1.0)); // The default building is NOT a complete building // Alter the code here to set different hard coded // defaults for use in other operations // First set any structure tags needed // // NONE // // Now create the required number of levels // and set the values // // Level 0 pLevel = pBld->CreateLevel(DefaultFootprint); pLevel->m_iStories = 1; pLevel->m_fStoryHeight = 3.20f; pLevel->SetEdgeMaterial(BMAT_NAME_PLAIN); pLevel->SetEdgeColor(RGBi(255,0,0)); // Red pLevel->GetEdge(0)->m_iSlope = 90; // Level 1 pLevel = pBld->CreateLevel(DefaultFootprint); pLevel->m_iStories = 1; pLevel->m_fStoryHeight = 3.20f; pLevel->SetEdgeMaterial(BMAT_NAME_PLAIN); pLevel->SetEdgeColor(RGBi(255,240,225)); // Tan pLevel->GetEdge(0)->m_iSlope = 0; // Flat g_DefaultStructures.Append(pBld); return false; }
bool vtTin::FindAltitudeAtPoint(const FPoint3 &p3, float &fAltitude, bool bTrue, int iCultureFlags, FPoint3 *vNormal) const { // Convert to 2D earth point, and test vs. TIN triangles DPoint3 earth; m_LocalCS.LocalToEarth(p3, earth); // If we need to provide a normal, do a separate test that gets the triangle if (vNormal != NULL) { int iTriangle; const bool hit = FindTriangleOnEarth(DPoint2(earth.x, earth.y), fAltitude, iTriangle, bTrue); if (hit) *vNormal = GetTriangleNormal(iTriangle); return hit; } else return FindAltitudeOnEarth(DPoint2(earth.x, earth.y), fAltitude, bTrue); }
void UtilityVisitor::endElement(const char *name) { const char *data = m_data.c_str(); if (m_state == 4) // Coordinate of the pylon { if (!strcmp(name, "gml:coordinates")) { double x, y; sscanf(data, "%lf,%lf", &x, &y); m_pRoute->AddPoint(DPoint2(x,y), GetReference()); // now set also the rotation !!!! HOW?? TODO m_state = 3; } } }
vtBuilding *vtStructureArray::AddBuildingFromLineString(OGRLineString *pLineString) { int num_points = pLineString->getNumPoints(); int j; // Ignore last point if it is the same as the first DPoint2 p1(pLineString->getX(0), pLineString->getY(0)); DPoint2 p2(pLineString->getX(num_points - 1), pLineString->getY(num_points - 1)); if (p1 == p2) num_points--; // Copy from OGR DLine2 footprint(num_points); for (j = 0; j < num_points; j++) footprint.SetAt(j, DPoint2(pLineString->getX(j), pLineString->getY(j))); PolyChecker PolyChecker; // Remove redundant points double dEpsilon = 1; for (j = 0; j < num_points && num_points > 2; j++) { DPoint2 p0 = footprint.GetSafePoint(j-1); DPoint2 p1 = footprint.GetSafePoint(j); DPoint2 p2 = footprint.GetSafePoint(j+1); if (PolyChecker.AreaSign(p0, p1, p2, dEpsilon) == 0) { footprint.RemoveAt(j); num_points--; j--; } } if (num_points < 3) return NULL; // Force footprint anticlockwise if (PolyChecker.IsClockwisePolygon(footprint)) footprint.ReverseOrder(); vtBuilding *bld = AddNewBuilding(); bld->SetFootprint(0, footprint); return bld; }
void DLine2FromString(const char *data, DLine2 &line) { // Speed/memory optimization: quick check of how many vertices // there are, then preallocate that many uint verts = 0; for (size_t i = 0; i < strlen(data); i++) if (data[i] == ',') verts++; line.Empty(); line.SetMaxSize(verts); double x, y; while (sscanf(data, "%lf,%lf", &x, &y) == 2) { line.Append(DPoint2(x,y)); data = strchr(data, ' '); if (!data) break; data++; } }
// // Test code // void EnviroFrame::DoTestCode() { SetMode(MM_SLOPE); #if 0 // Shadow tests const int ReceivesShadowTraversalMask = 0x1; const int CastsShadowTraversalMask = 0x2; osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene = new osgShadow::ShadowedScene; shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask); shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask); #if 0 osg::ref_ptr<osgShadow::ShadowMap> sm = new osgShadow::ShadowMap; shadowedScene->setShadowTechnique(sm.get()); int mapres = 1024; sm->setTextureSize(osg::Vec2s(mapres,mapres)); #else osg::ref_ptr<osgShadow::ShadowTexture> sm = new osgShadow::ShadowTexture; shadowedScene->setShadowTechnique(sm.get()); #endif osg::Group* cessna1 = (osg::Group*) osgDB::readNodeFile("cessna.osg"); if (!cessna1) return; cessna1->setNodeMask(CastsShadowTraversalMask); cessna1->getChild(0)->setNodeMask(CastsShadowTraversalMask); osg::Group* cessna2 = (osg::Group*) osgDB::readNodeFile("cessna.osg"); if (!cessna2) return; int flags_off = ~(CastsShadowTraversalMask | ReceivesShadowTraversalMask); cessna2->setNodeMask(flags_off); cessna2->getChild(0)->setNodeMask(flags_off); osg::MatrixTransform* positioned = new osg::MatrixTransform; positioned->setDataVariance(osg::Object::STATIC); positioned->setMatrix(osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,1.0f,0.0f) *osg::Matrix::translate(40,40,0)); positioned->addChild(cessna1); //osg::ref_ptr<osg::Group> shadowedScene = new osg::Group; shadowedScene->addChild(positioned); shadowedScene->addChild(cessna2); // osg::ref_ptr<osg::Group> container = new osg::Group; // container->addChild(positioned); // container->addChild(cessna2); vtGroup *vtg = GetCurrentTerrain()->GetTerrainGroup(); vtg->GetOsgGroup()->addChild(shadowedScene.get()); // vtg->GetOsgGroup()->addChild(container.get()); vtLogGraph(shadowedScene.get()); #endif #if 0 if (pTerr && g_App.m_bSelectedStruct) { vtStructureArray3d *sa = pTerr->GetStructureLayer(); int i = 0; while (!sa->GetAt(i)->IsSelected()) i++; vtBuilding3d *bld = sa->GetBuilding(i); // (Do something to the building as a test) sa->ConstructStructure(bld); } #endif #if 0 { // Read points from a text file, create OBJ file with geometry at that locations FILE *fp = fopen("test.txt", "r"); if (!fp) return; char buf[80]; float depth, x, y; // Add the geometry and materials to the shape vtGeode *pGeode = new vtGeode; vtMaterialArray *pMats = new vtMaterialArray; pMats->AddRGBMaterial(RGBf(1.0f, 1.0f, 1.0f), false, false, false); pGeode->SetMaterials(pMats); vtMesh *mesh = new vtMesh(osg::PrimitiveSet::TRIANGLES, VT_Normals | VT_Colors, 4000); int line = 0; fgets(buf, 80, fp); // skip first while (fgets(buf, 80, fp) != NULL) { sscanf(buf, "%f\t%f\t%f", &depth, &x, &y); int idx = mesh->NumVertices(); for (int i = 0; i < 20; i++) { double angle = (double)i / 20.0 * PI2d; FPoint3 vec; vec.x = x/2 * cos(angle); vec.y = 0.0f; vec.z = y/2 * sin(angle); // normal FPoint3 norm = vec; norm.Normalize(); // color RGBAf col(1.0f, 1.0f, 1.0f, 1.0f); if (x > y) { float frac = (x-y)/1.5f; // typical: 0 - 1.2 col.g -= frac; col.b -= frac; } else if (y > x) { float frac = (y-x)/1.5f; // typical: 0 - 1.2 col.r -= frac; col.g -= frac; } int add = mesh->AddVertexN(vec.x, /*650*/-depth, vec.z, norm.x, norm.y, norm.z); mesh->SetVtxColor(add, col); } if (line != 0) { for (int i = 0; i < 20; i++) { int next = (i+1)%20; mesh->AddTri(idx-20 + i, idx + i, idx-20 + next); mesh->AddTri(idx + i, idx + next, idx-20 + next); } } line++; } pGeode->AddMesh(mesh, 0); WriteGeomToOBJ(pGeode, "bore.obj"); vtTransform *model = new vtTransform; model->addChild(pGeode); DPoint3 pos; g_App.m_pTerrainPicker->GetCurrentEarthPos(pos); GetCurrentTerrain()->AddNode(model); GetCurrentTerrain()->PlantModelAtPoint(model, DPoint2(pos.x, pos.y)); } #endif }
void EnviroFrame::EarthPosUpdated(const DPoint3 &pos) { m_pInstanceDlg->SetLocation(DPoint2(pos.x, pos.y)); }
inline DPoint2 GridPos(const DPoint2 &base, const DPoint2 &spacing, int i, int j) { return DPoint2(base.x + spacing.x * i, base.y + spacing.y * j); }
void vtHeightField3d::SetEarthExtents(const DRECT &ext) { vtHeightField::SetEarthExtents(ext); m_LocalCS.Setup(m_LocalCS.GetUnits(), DPoint2(m_EarthExtents.left, m_EarthExtents.bottom)); UpdateWorldExtents(); }
/** * Create a set of points on the heightfield for a 2D polyline by draping the point onto * the surface. * * \param line The 2D line to drape, in Earth coordinates. * \param fSpacing The approximate spacing of the surface tessellation, used to * decide how finely to tessellate the line. * \param fOffset An offset to elevate each point in the resulting geometry, * useful for keeping it visibly above the ground. * \param bInterp True to interpolate between the vertices of the input * line. This is generally desirable when the ground is much more finely * spaced than the input line. * \param bCurve True to interpret the vertices of the input line as * control points of a curve. The created geometry will consist of * a draped line which passes through the control points. * \param bTrue True to use the true elevation of the terrain, ignoring * whatever scale factor is being used to exaggerate elevation for * display. * \param output Received the points. * \return The approximate length of the resulting 3D polyline. */ float vtHeightField3d::LineOnSurface(const DLine2 &line, float fSpacing, float fOffset, bool bInterp, bool bCurve, bool bTrue, FLine3 &output) { uint i, j; FPoint3 v1, v2, v; float fTotalLength = 0.0f; int iVerts = 0; uint points = line.GetSize(); if (bCurve) { DPoint2 p2, last(1E9,1E9); DPoint3 p3; int spline_points = 0; CubicSpline spline; for (i = 0; i < points; i++) { p2 = line[i]; if (i > 1 && p2 == last) continue; p3.Set(p2.x, p2.y, 0); spline.AddPoint(p3); spline_points++; last = p2; } spline.Generate(); // Estimate how many steps to subdivide this line into const double dLinearLength = line.Length(); float fLinearLength, dummy; m_LocalCS.VectorEarthToLocal(DPoint2(dLinearLength, 0.0), fLinearLength, dummy); double full = (double) (spline_points-1); int iSteps = (uint) (fLinearLength / fSpacing); if (iSteps < 3) iSteps = 3; double dStep = full / iSteps; FPoint3 last_v; for (double f = 0; f <= full; f += dStep) { spline.Interpolate(f, &p3); m_LocalCS.EarthToLocal(p3.x, p3.y, v.x, v.z); FindAltitudeAtPoint(v, v.y, bTrue); v.y += fOffset; output.Append(v); iVerts++; // keep a running total of approximate ground length if (f > 0) fTotalLength += (v - last_v).Length(); last_v = v; } } else { // not curved: straight line in earth coordinates FPoint3 last_v; for (i = 0; i < points; i++) { if (bInterp) { v1 = v2; m_LocalCS.EarthToLocal(line[i].x, line[i].y, v2.x, v2.z); if (i == 0) continue; // estimate how many steps to subdivide this segment into FPoint3 diff = v2 - v1; float fLen = diff.Length(); uint iSteps = (uint) (fLen / fSpacing); if (iSteps < 1) iSteps = 1; for (j = (i == 1 ? 0:1); j <= iSteps; j++) { // simple linear interpolation of the ground coordinate v.Set(v1.x + diff.x / iSteps * j, 0.0f, v1.z + diff.z / iSteps * j); FindAltitudeAtPoint(v, v.y, bTrue); v.y += fOffset; output.Append(v); iVerts++; // keep a running total of approximate ground length if (j > 0) fTotalLength += (v - last_v).Length(); last_v = v; } } else { m_LocalCS.EarthToLocal(line[i], v.x, v.z); FindAltitudeAtPoint(v, v.y, bTrue); v.y += fOffset; output.Append(v); } } } return fTotalLength; }
bool vtContourConverter::SetupTerrain(vtTerrain *pTerr) { // Make a note of this terrain and its attributes m_pTerrain = pTerr; m_pHF = pTerr->GetHeightFieldGrid3d(); int tileLod0Size = 0; if (!m_pHF) { vtTiledGeom *tiledGeom = pTerr->GetTiledGeom(); if (!tiledGeom) return false; m_ext = tiledGeom->GetEarthExtents(); //get highest LOD int minLod = 0; for(int i = 0; i < tiledGeom->rows * tiledGeom->rows; i++) if (tiledGeom->m_elev_info.lodmap.m_min[i] > minLod) minLod = tiledGeom->m_elev_info.lodmap.m_min[i]; tileLod0Size = 1 << minLod; m_spacing = DPoint2(m_ext.Width() / (tiledGeom->cols * tileLod0Size), m_ext.Height() / (tiledGeom->rows *tileLod0Size)); } else { m_ext = m_pHF->GetEarthExtents(); m_spacing = m_pHF->GetSpacing(); } // copy data from our grid to a QuikGrid object int nx, ny; if (m_pHF) m_pHF->GetDimensions(nx, ny); else { vtTiledGeom *tiledGeom = pTerr->GetTiledGeom(); nx = tiledGeom->cols * tileLod0Size + 1; ny = tiledGeom->rows * tileLod0Size + 1; } // we can't allocate too much memory, so reduce the resolution if too large DPoint2 scale(1.0, 1.0); while ((nx/scale.x) > 8192) scale.x *= 2.0; while ((ny/scale.y) > 8192) scale.y *= 2.0; m_spacing.x *= scale.x; m_spacing.y *= scale.y; nx /= scale.x; ny /= scale.y; m_pGrid = new SurfaceGrid(nx,ny); int i, j; if (m_pHF) { for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { // use the true elevation, for true contours m_pGrid->zset(i, j, m_pHF->GetElevation(i, j, true)); } } } else { vtTiledGeom *tiledGeom = pTerr->GetTiledGeom(); float topBottom = tiledGeom->m_WorldExtents.top - tiledGeom->m_WorldExtents.bottom; float rightLeft = tiledGeom->m_WorldExtents.right - tiledGeom->m_WorldExtents.left; float xwidth = rightLeft / nx; float ywidth = topBottom / ny; float altitude; for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { // use the true elevation, for true contours tiledGeom->FindAltitudeAtPoint(FPoint3(i*xwidth, 0, j*ywidth),altitude, true); m_pGrid->zset(i, j, altitude); } } } return true; }
/** Get the grid spacing, the width of each column and row. */ DPoint2 vtHeightFieldGrid3d::GetSpacing() const { return DPoint2(m_dXStep, m_dYStep); }
void vtHeightField3d::SetEarthExtents(const DRECT &ext) { vtHeightField::SetEarthExtents(ext); m_Conversion.SetOrigin(DPoint2(m_EarthExtents.left, m_EarthExtents.bottom)); UpdateWorldExtents(); }
void StructVisitorGML::endElement(const char *name) { bool bGrabAttribute = false; const char *data = m_data.c_str(); if (m_state == 7 && !strcmp(name, "Edge")) { m_iEdge++; m_state = 3; } else if (m_state == 6) // inside Footprint innerBoundaryIs { if (!strcmp(name, "gml:coordinates")) { DLine2 line; DLine2FromString(data, line); m_Footprint.push_back(line); } else if (!strcmp(name, "gml:innerBoundaryIs")) m_state = 4; } else if (m_state == 5) // inside Footprint outerBoundaryIs { if (!strcmp(name, "gml:coordinates")) { DLine2 line; DLine2FromString(data, line); m_Footprint.push_back(line); } else if (!strcmp(name, "gml:outerBoundaryIs")) m_state = 4; } else if (m_state == 4) // inside Footprint { if (!strcmp(name, "Footprint")) { m_pLevel->SetFootprint(m_Footprint); m_state = 3; } } else if (m_state == 3 && !strcmp(name, "Level")) { m_state = 2; m_iLevel ++; } else if (m_state == 2) { if (!strcmp(name, "Building")) { m_state = 1; // do this once after we done adding levels m_pBuilding->DetermineLocalFootprints(); m_pSA->Append(m_pStructure); m_pStructure = NULL; } else bGrabAttribute = true; } else if (m_state == 1 && (!strcmp(name, "SRS"))) { m_pSA->m_proj.SetTextDescription("wkt", data); // This seems wrong - why would each .vtst file reset the global projection? // g_Conv.Setup(m_pSA->m_proj.GetUnits(), DPoint2(0,0)); } else if (m_state == 10) { if (!strcmp(name, "Linear")) { m_state = 1; m_pSA->Append(m_pStructure); m_pStructure = NULL; } } else if (m_state == 11) { if (!strcmp(name, "gml:coordinates")) { DLine2 &fencepts = m_pFence->GetFencePoints(); double x, y; while (sscanf(data, "%lf,%lf", &x, &y) == 2) { fencepts.Append(DPoint2(x,y)); data = strchr(data, ' '); if (data) data++; else break; } } else if (!strcmp(name, "Path")) m_state = 10; } else if (m_state == 20) { if (!strcmp(name, "Imported")) { m_state = 1; m_pSA->Append(m_pStructure); m_pStructure = NULL; } else if (!strcmp(name, "Rotation")) { float fRot; sscanf(data, "%f", &fRot); m_pInstance->SetRotation(fRot); } else if (!strcmp(name, "Scale")) { float fScale; sscanf(data, "%f", &fScale); m_pInstance->SetScale(fScale); } else bGrabAttribute = true; } else if (m_state == 21) { if (!strcmp(name, "gml:coordinates")) { double x, y; sscanf(data, "%lf,%lf", &x, &y); m_pInstance->SetPoint(DPoint2(x,y)); } else if (!strcmp(name, "Location")) m_state = 20; } // first check for Attribute nodes if (bGrabAttribute) { // save these elements as literal strings vtTag tag; tag.name = name; tag.value = data; m_pStructure->AddTag(tag); // where does the tag go? } }