void vtLevel::GetEdgePlane(uint i, FPlane &plane) { vtEdge *edge = m_Edges[i]; int islope = edge->m_iSlope; float slope = (islope / 180.0f * PIf); int index = i; int ring = m_LocalFootprint.WhichRing(index); FLine3 &loop = m_LocalFootprint[ring]; uint ring_edges = loop.GetSize(); int next = (index+1 == ring_edges) ? 0 : index+1; // get edge vector FPoint3 vec = loop[next] - loop[index]; vec.Normalize(); // get perpendicular (upward pointing) vector FPoint3 perp; perp.Set(0, 1, 0); // create rotation matrix to rotate it upward FMatrix4 mat; mat.Identity(); mat.AxisAngle(vec, slope); // create normal FPoint3 norm; mat.TransformVector(perp, norm); plane.Set(loop[index], norm); }
void GlobePicker::Eval() { FPoint3 pos, dir; vtGetScene()->CameraRay(m_pos, pos, dir); // test whether we hit the globe FSphere sphere(FPoint3(0.0f, 0.0f, 0.0f), (float)m_fRadius); FPoint3 akPoint[2]; int riQuantity; m_bOnTerrain = RaySphereIntersection(pos, dir, sphere, riQuantity, akPoint); if (m_bOnTerrain) { // save result m_GroundPoint = akPoint[0]; // apply global position to target (which is not a child of the globe) vtTransform *pTarget = (vtTransform *) GetTarget(); if (pTarget) { pTarget->Identity(); pTarget->SetTrans(m_GroundPoint); pTarget->PointTowards(m_GroundPoint * 2.0f); pTarget->Scale(m_fTargetScale); } if (m_pGlobe) { // rotate to find position relative to globe's rotation vtTransform *xform = m_pGlobe->GetTop(); FMatrix4 rot; xform->GetTransform1(rot); FMatrix4 inverse; inverse.Invert(rot); FPoint3 newpoint; // work around SML bug: matrices flagged as identity but // will still transform by their components if (! inverse.IsIdentity()) { inverse.Transform(m_GroundPoint, newpoint); m_GroundPoint = newpoint; } } // Find corresponding geographic coordinates xyz_to_geo(m_fRadius, m_GroundPoint, m_EarthPos); } }
FMatrix4 FTransform::LocalToWorldMatrix() const { FMatrix4 LocalToWorld; LocalToWorld.Scale(mScale); LocalToWorld *= mRotation.ToMatrix4(); LocalToWorld.SetOrigin(mTranslation); if (!mParent) { return LocalToWorld; } return mParent->LocalToWorldMatrix() * LocalToWorld; }
void vtFence3d::AddFencepost(const FPoint3 &p1, int iMatIdx) { // create fencepost block vtMesh *pPostMesh = new vtMesh(osg::PrimitiveSet::TRIANGLE_FAN, VT_Normals | VT_TexCoords, 20); FPoint3 PostSize(m_Params.m_fPostWidth, m_Params.m_fPostHeight, m_Params.m_fPostDepth); pPostMesh->CreateOptimizedBlock(PostSize); // scoot over and upwards to put it above ground FMatrix4 t; t.Identity(); t.Translate(p1); pPostMesh->TransformVertices(t); m_pFenceGeom->AddMesh(pPostMesh, iMatIdx); }
void vtRoute::_StringWires(long ll, vtHeightField3d *pHeightField) { // pick pole numbers i and i-1 and string a wire between them long numiterations = NUM_WIRE_SEGMENTS; FPoint3 fp0, fp1; vtUtilNode *n0 = m_Nodes[ll-1]; vtUtilNode *n1 = m_Nodes[ll]; vtUtilStruct *st0 = n0->m_struct; vtUtilStruct *st1 = n1->m_struct; // safety check if (!st0 || !st1) return; DPoint2 p0 = n0->m_Point; DPoint2 p1 = n1->m_Point; pHeightField->ConvertEarthToSurfacePoint(p0, fp0); pHeightField->ConvertEarthToSurfacePoint(p1, fp1); FMatrix4 rot; rot.Identity(); FPoint3 axisY(0, 1, 0); FPoint3 offset, wire0, wire1; vtMesh *pWireMesh; for (int j = 0; j < st1->m_iNumWires; j++) { pWireMesh = new vtMesh(osg::PrimitiveSet::LINE_STRIP, 0, numiterations+1); offset = st0->m_fpWireAtt1[j]; rot.AxisAngle(axisY, n0->dRadAzimuth); rot.Transform(offset, wire0); FPoint3 wire_start = fp0 + wire0; pWireMesh->AddVertex(wire_start); offset = st1->m_fpWireAtt2[j]; rot.AxisAngle(axisY, n1->dRadAzimuth); rot.Transform(offset, wire1); FPoint3 wire_end = fp1 + wire1; _DrawCat(wire_start, wire_end, vtGetTS()->m_fCatenaryFactor, numiterations, pWireMesh); pWireMesh->AddVertex(wire_end); pWireMesh->AddStrip2(numiterations+1, 0); m_pWireGeom->AddMesh(pWireMesh, m_mi_wire); } }