void SimplePathGraph::read_old ( Iff & iff ) { clear(); // ---------- iff.enterChunk(TAG_PNOD); { FloorLocator loc; while(iff.getChunkLengthLeft()) { loc.read_0000(iff); m_nodes->push_back( PathNode(loc.getPosition_p()) ); } } iff.exitChunk(TAG_PNOD); iff.enterChunk(TAG_PEDG); { while(iff.getChunkLengthLeft()) { int a = iff.read_int32(); int b = iff.read_int32(); m_edges->push_back( PathEdge(a,b) ); m_edges->push_back( PathEdge(b,a) ); } } iff.exitChunk(TAG_PEDG); // ---------- buildIndexTables(); #ifdef _DEBUG if(ConfigSharedCollision::getBuildDebugData()) { buildDebugData(); } #endif }
//----------------------------- GetPath ------------------------------------ // // called by an agent after it has been notified that a search has terminated // successfully. The method extracts the path from m_pCurrentSearch, adds // additional edges appropriate to the search type and returns it as a list of // PathEdges. //----------------------------------------------------------------------------- CActor_PathPlanner::Path CActor_PathPlanner::GetPath() { assert( m_pCurrentSearch && "<CActor_PathPlanner::GetPathAsNodes>: no current search" ); Path path = m_pCurrentSearch->GetPathAsPathEdges(); int closest = GetClosestNodeToPosition( m_pOwner->Pos() ); path.push_front( PathEdge( m_pOwner->Pos(), GetNodePosition( closest ), NavGraphEdge::normal ) ); //if the bot requested a path to a location then an edge leading to the //destination must be added if ( m_pCurrentSearch->GetType() == Graph_SearchTimeSliced < EdgeType >::AStar ) { int idx = m_pOwner->World()->GetCellSpace()->PositionToIndex( m_vDestinationPos ); if ( invalid_node_index != m_pOwner->World()->GetNavGraph().GetNode( idx ).Index() ) { path.push_back( PathEdge( path.back().Destination(), m_vDestinationPos, NavGraphEdge::normal ) ); } } //smooth paths if required if ( script->GetBool( "SmoothPathsQuick" ) ) { SmoothPathEdgesQuick( path ); } if ( script->GetBool( "SmoothPathsPrecise" ) ) { SmoothPathEdgesPrecise( path ); } return path; }
//----------------------------- GetPath ------------------------------------ // // called by an agent after it has been notified that a search has terminated // successfully. The method extracts the path from m_pCurrentSearch, adds // additional edges appropriate to the search type and returns it as a list of // PathEdges. //----------------------------------------------------------------------------- Raven_PathPlanner::Path Raven_PathPlanner::GetPath() { assert (m_pCurrentSearch && "<Raven_PathPlanner::GetPathAsNodes>: no current search"); Path path = m_pCurrentSearch->GetPathAsPathEdges(); int closest = GetClosestNodeToPosition(m_pOwner->Pos()); path.push_front(PathEdge(m_pOwner->Pos(), GetNodePosition(closest), NavGraphEdge::normal)); //if the bot requested a path to a location then an edge leading to the //destination must be added if (m_pCurrentSearch->GetType() == Graph_SearchTimeSliced<EdgeType>::AStar) { path.push_back(PathEdge(path.back().Destination(), m_vDestinationPos, NavGraphEdge::normal)); } //smooth paths if required if (UserOptions->m_bSmoothPathsQuick) { SmoothPathEdgesQuick(path); } if (UserOptions->m_bSmoothPathsPrecise) { SmoothPathEdgesPrecise(path); } return path; }
bool PathVertex::sampleNextVertex(const TraceableScene &scene, TraceBase &tracer, TraceState &state, bool adjoint, PathVertex *prev, PathEdge *prevEdge, PathVertex &next, PathEdge &nextEdge) { Vec3f weight; float pdf; switch (_type) { case EmitterVertex: { EmitterRecord &record = _record.emitter; if (_sampler.emitter->isInfinite()) { weight = record.point.weight; pdf = record.point.pdf; } else { if (!_sampler.emitter->sampleDirection(state.sampler, record.point, record.direction)) return false; weight = record.direction.weight; pdf = record.direction.pdf; } state.ray = Ray(record.point.p, record.direction.d); break; } case CameraVertex: { CameraRecord &record = _record.camera; if (!_sampler.camera->sampleDirection(state.sampler, record.point, record.pixel, record.direction)) return false; weight = record.direction.weight; pdf = record.direction.pdf; state.ray = Ray(record.point.p, record.direction.d); state.ray.setPrimaryRay(true); break; } case SurfaceVertex: { SurfaceRecord &record = _record.surface; if (record.info.primitive->isInfinite()) return false; Vec3f scatterWeight(1.0f); Vec3f emission(0.0f); bool scattered = tracer.handleSurface(record.event, record.data, record.info, state.medium, state.bounce, adjoint, false, state.ray, scatterWeight, emission, state.wasSpecular, state.mediumState); if (!scattered) return false; if (record.event.sampledLobe.isForward()) prev->_pdfBackward = record.event.pdf; else prev->_pdfBackward = _sampler.bsdf->pdf(record.event.makeFlippedQuery()); _dirac = record.event.sampledLobe.isPureSpecular(); _forward = record.event.sampledLobe.isForward(); // Technically, we could connect to these kinds of vertices (e.g. BSDF with transparency), // but this creates so much headache for back-propagating the PDFs that we're just not // going to bother if (_forward) _connectable = false; weight = record.event.weight; pdf = record.event.pdf; break; } case MediumVertex: { MediumRecord &record = _record.medium; if (!record.mediumSample.phase->sample(state.sampler, state.ray.dir(), record.phaseSample)) return false; prev->_pdfBackward = record.mediumSample.phase->pdf(-record.phaseSample.w, -state.ray.dir()); state.ray = state.ray.scatter(record.mediumSample.p, record.phaseSample.w, 0.0f); state.ray.setPrimaryRay(false); weight = record.phaseSample.weight; pdf = record.phaseSample.pdf; break; } default: return false; } SurfaceRecord surfaceRecord; bool didHit = scene.intersect(state.ray, surfaceRecord.data, surfaceRecord.info); bool hitSurface; float edgePdfForward; float edgePdfBackward; MediumRecord mediumRecord; if (state.medium) { if (!state.medium->sampleDistance(state.sampler, state.ray, state.mediumState, mediumRecord.mediumSample)) return false; if (mediumRecord.mediumSample.t < 1e-6f) return false; hitSurface = mediumRecord.mediumSample.exited; edgePdfForward = mediumRecord.mediumSample.pdf; Ray reverseRay(mediumRecord.mediumSample.p, -state.ray.dir(), 0.0f, mediumRecord.mediumSample.t); edgePdfBackward = state.medium->pdf(state.sampler, reverseRay, onSurface()); weight *= mediumRecord.mediumSample.weight; if (hitSurface && !didHit) return false; } else { hitSurface = true; edgePdfForward = 1.0f; edgePdfBackward = 1.0f; } if (!hitSurface) { mediumRecord.wi = state.ray.dir(); next = PathVertex(mediumRecord.mediumSample.phase, mediumRecord, _throughput*weight); next._medium = state.medium; state.bounce++; nextEdge = PathEdge(*this, next, edgePdfForward, edgePdfBackward); next._pdfForward = pdf; return true; } else if (didHit) { surfaceRecord.event = tracer.makeLocalScatterEvent(surfaceRecord.data, surfaceRecord.info, state.ray, &state.sampler); next = PathVertex(surfaceRecord.info.bsdf, surfaceRecord, _throughput*weight); next._medium = state.medium; next.pointerFixup(); state.bounce++; nextEdge = PathEdge(*this, next, edgePdfForward, edgePdfBackward); next._pdfForward = pdf; return true; } else if (!adjoint && scene.intersectInfinites(state.ray, surfaceRecord.data, surfaceRecord.info)) { next = PathVertex(surfaceRecord.info.bsdf, surfaceRecord, _throughput*weight); next._medium = state.medium; state.bounce++; nextEdge = PathEdge(state.ray.dir(), 1.0f, 1.0f, edgePdfForward, edgePdfBackward); next._pdfForward = pdf; return true; } else { return false; } }