status_t MSequence::Head(ArpMidiEvent** event) { ArpMidiNode* node; if ((node = dynamic_cast<ArpMidiNode*>(HeadNode())) == NULL) return B_ERROR; if (node->Event() == NULL) return B_ERROR; *event = node->Event(); return B_OK; }
bool cBSPTree::RayCastToBoundary3(cRay &ret, const cCoord3& start, const cCoord3& direction ) { if(!CheckBoxHit(start, direction)){ return false; } p4::Log::TMI("%s Raycast", mName); float min_bound = 0.0f; float max_bound = MaxFloat(); if(mBoundingBox.CheckWithin(start)){ mBoundingBox.RayIntersection(max_bound, start, direction); } else{ mBoundingBox.RayIntersection(min_bound, start, direction); mBoundingBox.RayIntersection(max_bound, start+(min_bound+0.01f)*direction, direction); max_bound+=min_bound+0.01f; } p4::Log::TMI("ray bounds = (%f, %f)", min_bound, max_bound ); cRay last_result(direction, 0.0f); float current_distance = min_bound+cBSPNode::kEqualThreshold*0.5f; cCoord3 best_plane = direction; cCoord3 p = start+current_distance*direction; while(mBoundingBox.CheckWithin(p) && IsOutsidePoly(last_result, p, direction, HeadNode())){ current_distance+=GreaterOf(last_result.mLength, cBSPNode::kEqualThreshold*0.5f); best_plane = last_result.mDirection; p4::Log::TMI("current result = %f, last result = %f", current_distance, last_result.mLength); p = start+(current_distance+cBSPNode::kEqualThreshold*0.5f)*direction; } p4::Log::TMI("Ready to return %f", current_distance); /* for (int i = 0; i < 100; i++) { const float d = (max_bound-min_bound)*(i/100.0f)+min_bound; p=start+d*direction; bool is_out = IsOutsidePoly(last_result, p, direction, HeadNode()); if(is_out){ p4::Log::Debug("%d\t OUT current result = %f, last result = %f",i, d, last_result); } else{ p4::Log::Debug("%d\t IN current result = %f, last result = %f",i, d, last_result); } } */ p = start+(current_distance)*direction; p4::Log::TMI("Done result = %f, last result = %f", current_distance, last_result.mLength); if( mBoundingBox.CheckWithin(p)){ cBSPNode* best = ClosestContainingPlane(p+direction*cBSPNode::kEqualThreshold*0.5f, direction, HeadNode()); if(best == NULL){ return false; } ret.mLength = current_distance; ret.mDirection = best->GetDividingPlane().NormalVec(); return true; } p4::Log::TMI("Not within Bounds? result = %f, last result = %f", current_distance, last_result.mLength); return false; }
void ArpIndexedList::DeleteOnlyNodes() { if (chain == 0) return; ArpIndexedNode *node; if ((node = HeadNode()) != 0) delete node; pFreeChain(); }
status_t MSequence::RemoveAt(ArpMidiT time, ArpMidiEvent** removedEvent) { ArpMidiNode* node = (ArpMidiNode*)HeadNode(); while (node != 0) { if (node->Index() == time) { *removedEvent = node->Event(); return DeleteNode(node); } node = (ArpMidiNode*)node->next; } return B_ERROR; }
void ArpIndexedList::DeleteNodeContents() { if (chain == 0) return; ArpIndexedNode *node; if ((node = HeadNode()) != 0) { node->DeleteListContents(); delete node; } pFreeChain(); }
int32 ArpIndexedList::Count() { ArpIndexedNode *node; int32 k = 0; if ((node = HeadNode()) == 0) return k; while (node != 0) { k++; node = node->next; } return k; }
uint32_t VisibleSpriteList::FindSubsectorDepth(RenderThread *thread, const DVector2 &worldPos) { auto Level = thread->Viewport->Level(); if (Level->nodes.Size() == 0) { subsector_t *sub = &Level->subsectors[0]; return thread->OpaquePass->GetSubsectorDepth(sub->Index()); } else { return FindSubsectorDepth(thread, worldPos, Level->HeadNode()); } }
//初始化,构建整个图 //从文件读取 SubwayGuider &SubwayGuider::init(string fileName) { //键为几号线 //值为该线上的站点 map<int, vector<tmp>> tmpMap; struct tmp t; ifstream inFile(fileName); while (!inFile.eof()) { int line, stopNum; inFile >> line >> stopNum; while (stopNum--) { inFile >> t.name >> t.price >> t.time; t.line = line; //尚无当前站点 if (subwayMap.find(t.name) == subwayMap.end()) { //添加新站点 subwayMap[t.name] = HeadNode(t.name, line); } else { //已经有了当前站点 //为站点添加新线路信息(没什么用 subwayMap[t.name].linePassThisStop.push_back(line); } tmpMap[line].push_back(t); } } inFile.close(); //创建线路 for (const auto &item : tmpMap) { for (auto cur = item.second.begin(); cur != item.second.end() - 1; cur++) { addRoute(*cur, (cur + 1)->name); } } createMap(); return *this; }
bool cBSPTree::RayCastToBoundary2(float &ret, const cCoord3& start, const cCoord3& direction ) { p4::Log::GetInstance()->SetLogLevel(p4::Log::LOG_LEVEL_TMI); if(!CheckBoxHit(start, direction)){ return false; } float min_bound = 0.0f; float max_bound = MaxFloat(); if(mBoundingBox.CheckWithin(start)){ mBoundingBox.RayIntersection(max_bound, start, direction); } else{ mBoundingBox.RayIntersection(min_bound, start, direction); mBoundingBox.RayIntersection(max_bound, start+(min_bound+0.01f)*direction, direction); max_bound+=min_bound+0.01f; } float min_d = min_bound; float max_d = max_bound; float best_result = max_bound+1.0f; p4::Log::TMI("ray bounds = (%f, %f)", min_bound, max_bound ); mNodeStack.clear(); int search_depth = 0; cBSPNode* current_node = HeadNode(); float current_distance = 0.0f; bool terminal_candidate = false; cBSPNode::eClassification in_out = cBSPNode::BSP_SPLIT; while((current_node != NULL )){ in_out = current_node->ClassifyPoint(start+direction*current_distance, 0.0f); //nudge it a bit if we're coplanar if(in_out == cBSPNode::BSP_COPLANAR){ current_distance += 0.5f*cBSPNode::kEqualThreshold; in_out = current_node->ClassifyPoint(start+direction*current_distance, 0.0f); } P4_ASSERT(in_out != cBSPNode::BSP_COPLANAR); const float next_plane_dist = current_node->DistanceToPlane(start+direction*current_distance, direction); p4::Log::TMI("%s, %d, %d dist: %f, next plane = %f", mName, search_depth, in_out, current_distance, current_distance+next_plane_dist); const float new_distance = current_distance + next_plane_dist; const bool too_far = (new_distance > max_bound) || (new_distance > max_d); const bool too_near = (new_distance < min_bound) || (new_distance < min_d); current_distance = Clamp(min_d, current_distance, max_d); if(too_far){ p4::Log::TMI("%s, %d,-|Too far (%f, %f)", mName, search_depth, min_d, max_d); } if(too_near){ p4::Log::TMI("%s, %d,|- Too near (%f, %f)", mName, search_depth, min_d, max_d); } //terminal_candidate = (in_out == cBSPNode::BSP_FRONT && next_plane_dist > 0.0f) || (in_out == cBSPNode::BSP_BACK && next_plane_dist < 0.0f); //terminal_candidate &= (!too_near && !too_far); terminal_candidate = in_out == cBSPNode::BSP_BACK; int next_index = -1; int next_stack_index = -1; if(in_out == cBSPNode::BSP_FRONT){ if( !IsOutsidePoly(start+(new_distance+1.5f*cBSPNode::kEqualThreshold)*direction, current_node) ){ p4::Log::TMI("point is inside"); if(new_distance <= max_bound && new_distance >= min_bound && new_distance < best_result){ best_result = new_distance; p4::Log::TMI("saved new best: %f", new_distance); } } else { p4::Log::TMI("point is outside"); } //we're front, and moving forward will give us rear //queue up the forward move, and check the rear if(next_plane_dist > 0.0f){ if(!too_near){ p4::Log::TMI("%s, %d,0<- Back to the front node", mName, search_depth); next_index = current_node->GetFrontNodeIndex(); } // don't bother queueing up the forward move, just go back for now if(!too_far){ next_stack_index = current_node->GetRearNodeIndex(); p4::Log::TMI("%s, %d,->1 forward to the rear node %d", mName, search_depth, next_stack_index); } } //we're front, and moving forward will give us more front // descend back for now, queue up the rest if(next_plane_dist < 0.0f){ if(!too_near){ p4::Log::TMI("%s, %d,1<- descend to the rear node", mName, search_depth); next_index = current_node->GetRearNodeIndex(); } if(!too_far){ p4::Log::TMI("%s, %d,->0 descend to the front node", mName, search_depth); next_stack_index = current_node->GetFrontNodeIndex(); } } } else if(in_out == cBSPNode::BSP_BACK){ if( !IsOutsidePoly(start+(new_distance+0.5f*cBSPNode::kEqualThreshold)*direction, current_node) ){ p4::Log::TMI("point is inside"); if(new_distance <= max_bound && new_distance >= min_bound && new_distance < best_result){ best_result = new_distance; p4::Log::TMI("saved new best: %f", new_distance); } } else { p4::Log::TMI("point is outside"); } //we're back, and moving forward will give us front if(next_plane_dist > 0.0f){ if(!too_near){ p4::Log::TMI("%s, %d,1<- descend to the rear node", mName, search_depth); next_index = current_node->GetRearNodeIndex(); } if(!too_far){ p4::Log::TMI("%s, %d,->0 descend to the front node", mName, search_depth); next_stack_index = current_node->GetFrontNodeIndex(); } } //we're rear, and moving backward will give us front if(next_plane_dist < 0.0f){ if(!too_near){ p4::Log::TMI("%s, %d,0<- descend to the front node", mName, search_depth); next_index = current_node->GetFrontNodeIndex(); } if (!too_far){ p4::Log::TMI("%s, %d,->1 descend to the rear node", mName, search_depth); next_stack_index = current_node->GetRearNodeIndex(); } } } else { p4::Log::Debug("Coplanar"); } current_node = NULL; if(next_index != -1 || next_stack_index != -1){ terminal_candidate = false; current_distance = Clamp(min_d,new_distance,max_d); search_depth ++; if(next_index != -1 ){ current_node = &mNodeVec[next_index]; if(next_plane_dist > 0.0f && current_distance < max_d){ max_d = current_distance; } } float stack_max = max_d; float stack_min = min_d; if(next_plane_dist < 0.0f && current_distance > min_d){ stack_min = current_distance; } if(next_index == -1 && next_stack_index != -1){ current_node = &mNodeVec[next_stack_index]; min_d = stack_min; max_d = stack_max; //clear so it doesn't get queued next_stack_index = -1; } if(next_stack_index != -1){ p4::Log::TMI("%s, %d,-%d-\\ placing on stack", mName, search_depth, mNodeStack.size()); mNodeStack.push_back(cNodeRecord()); mNodeStack.back().mNode=&mNodeVec[next_stack_index]; mNodeStack.back().mMax = stack_max; mNodeStack.back().mMin = stack_min; mNodeStack.back().mLocation = current_distance; } else if(!too_near && !too_far) { p4::Log::TMI("%s, %d, nothing to put on stack", mName, search_depth); } } else if( !mBoundingBox.CheckWithin(start+best_result*direction) && !mNodeStack.empty()){ current_node = mNodeStack.back().mNode; current_distance = mNodeStack.back().mLocation; min_d = mNodeStack.back().mMin; max_d = mNodeStack.back().mMax; mNodeStack.pop_back(); p4::Log::TMI("%d unstacking d = %f (stack size = %d)", search_depth, current_distance, mNodeStack.size()); } if(current_node == NULL){ p4::Log::TMI("%s, %d,--- Scratch that, not descending: this is a terminal node", mName, search_depth); } } P4_ASSERT(in_out != cBSPNode::BSP_SPLIT); P4_ASSERT(current_distance < 10000.0); bool in_bounds = (mBoundingBox.CheckWithin(start+best_result*direction)); if(in_bounds){ p4::Log::TMI(">>HIT, depth = %d, ret = %f, best = %f", search_depth, current_distance, best_result); ret = best_result; return true; } p4::Log::TMI(">>MISS, depth = %d, ret = %f, best result:%f", search_depth, current_distance, best_result); p4::Log::GetInstance()->SetLogLevel(p4::Log::LOG_LEVEL_DEBUG); return false; }
status_t ArpIndexedList::RemoveHeadNode(ArpIndexedNode **removedNode) { if ((*removedNode = HeadNode()) == 0) return B_ERROR; return RemoveNode(*removedNode); }