std::vector<Point2d> Intersect(const Arc &arc, const Circle &circle) { return Intersect(circle, arc); }
std::vector<vsr::cga2D::Vec> Intersect(const LineSegment &segment, const Circle &circle) { return Intersect(circle, segment); }
std::vector<vsr::cga2D::Vec> Intersect(const Arc &arc, const LineSegment &segment) { return Intersect(segment, arc); }
int Hull::AddContactsHullHull(btSeparation& sep, const Point3* pVertsA, const Point3* pVertsB, const Transform& trA, const Transform& trB,const Hull& hullA,const Hull& hullB, HullContactCollector* hullContactCollector) { const int maxContacts = hullContactCollector->GetMaxNumContacts(); Vector3 normalWorld = sep.m_axis; // edge->edge contact is always a single point if (sep.m_separator == btSeparation::kFeatureBoth) { const Hull::Edge& edgeA = hullA.getEdge(sep.m_featureA); const Hull::Edge& edgeB = hullB.getEdge(sep.m_featureB); float ta, tb; Line la(pVertsA[edgeA.m_verts[0]], pVertsA[edgeA.m_verts[1]]); Line lb(pVertsB[edgeB.m_verts[0]], pVertsB[edgeB.m_verts[1]]); Intersect(la, lb, ta, tb); #ifdef VALIDATE_CONTACT_POINTS AssertPointInsideHull(contact.m_points[0].m_pos, trA, hullA); AssertPointInsideHull(contact.m_points[0].m_pos, trB, hullB); #endif Point3 posWorld = Lerp(la.m_start, la.m_end, ta); float depth = -sep.m_dist; Vector3 tangent = Normalize(pVertsA[edgeA.m_verts[1]] - pVertsA[edgeA.m_verts[0]]); sep.m_contact = hullContactCollector->BatchAddContactGroup(sep,1,normalWorld,tangent,&posWorld,&depth); } // face->face contact is polygon else { short faceA = sep.m_featureA; short faceB = sep.m_featureB; Vector3 tangent; // find face of hull A that is most opposite contact axis // TODO: avoid having to transform planes here if (sep.m_separator == btSeparation::kFeatureB) { const Hull::Edge& edgeB = hullB.getEdge(hullB.GetFaceFirstEdge(faceB)); tangent = Normalize(pVertsB[edgeB.m_verts[1]] - pVertsB[edgeB.m_verts[0]]); Scalar dmin = Scalar::Consts::MaxValue; for (short face = 0; face < hullA.m_numFaces; face++) { Vector3 normal = hullA.getPlane(face).GetNormal() * trA; Scalar d = Dot(normal, sep.m_axis); if (d < dmin) { dmin = d; faceA = face; } } } else { const Hull::Edge& edgeA = hullA.getEdge(hullA.GetFaceFirstEdge(faceA)); tangent = Normalize(pVertsA[edgeA.m_verts[1]] - pVertsA[edgeA.m_verts[0]]); Scalar dmin = Scalar::Consts::MaxValue; for (short face = 0; face < hullB.m_numFaces; face++) { Vector3 normal = hullB.getPlane(face).GetNormal() * trB; Scalar d = Dot(normal, -sep.m_axis); if (d < dmin) { dmin = d; faceB = face; } } } Point3 workspace[2][Hull::kMaxVerts]; // setup initial clip face (minimizing face from hull B) int numContacts = 0; for (short edge = hullB.GetFaceFirstEdge(faceB); edge != -1; edge = hullB.GetFaceNextEdge(faceB, edge)) workspace[0][numContacts++] = pVertsB[ hullB.GetEdgeVertex0(faceB, edge) ]; // clip polygon to back of planes of all faces of hull A that are adjacent to witness face Point3* pVtxIn = workspace[0]; Point3* pVtxOut = workspace[1]; #if 0 for (short edge = hullA.GetFaceFirstEdge(faceA); edge != -1; edge = hullA.GetFaceNextEdge(faceA, edge)) { Plane planeA = hullA.getPlane( hullA.GetEdgeOtherFace(edge, faceA) ) * trA; numContacts = ClipFace(numContacts, &pVtxIn, &pVtxOut, planeA); } #else for (short f = 0; f < hullA.GetNumFaces(); f++) { Plane planeA = hullA.getPlane(f) * trA; numContacts = ClipFace(numContacts, &pVtxIn, &pVtxOut, planeA); } #endif // only keep points that are behind the witness face Plane planeA = hullA.getPlane(faceA) * trA; float depths[Hull::kMaxVerts]; int numPoints = 0; for (int i = 0; i < numContacts; i++) { Scalar d = Dot(planeA, pVtxIn[i]); if (IsNegative(d)) { depths[numPoints] = (float)-d; pVtxIn[numPoints] = pVtxIn[i]; #ifdef VALIDATE_CONTACT_POINTS AssertPointInsideHull(pVtxIn[numPoints], trA, hullA); AssertPointInsideHull(pVtxIn[numPoints], trB, hullB); #endif numPoints++; } } //we can also use a persistentManifold/reducer class // keep maxContacts points at most if (numPoints > 0) { if (numPoints > maxContacts) { int step = (numPoints << 8) / maxContacts; numPoints = maxContacts; for (int i = 0; i < numPoints; i++) { int nth = (step * i) >> 8; depths[i] = depths[nth]; pVtxIn[i] = pVtxIn[nth]; #ifdef VALIDATE_CONTACT_POINTS AssertPointInsideHull(contact.m_points[i].m_pos, trA, hullA); AssertPointInsideHull(contact.m_points[i].m_pos, trB, hullB); #endif } } sep.m_contact = hullContactCollector->BatchAddContactGroup(sep,numPoints,normalWorld,tangent,pVtxIn,depths); } return numPoints; }
/// Check if the paths of @a Walker and @a Vehicle intersect. /// /// It checks if within the update time the vehicle will cross the straight /// line of @a Walker sight radius on its forward direction. static bool Intersect(const APawn &Walker, const AWheeledVehicle &Vehicle) { return Intersect(PawnPath(Walker), PawnPath(Vehicle), Walker.GetWorld()); }
Intersect Model::intersect (Ray ray) const { // construct return value real_t min_dis = 9999999.9; // minimum distance to begin with Intersect result = Intersect(); // final intersect object result.intersect = false; // the default value is false // after transformaton, the center of the object should be (0,0,0) Vector3 E = invMat.transform_point(ray.e); // ray eye coordinate Vector3 D = invMat.transform_vector(ray.d); // ray direction vector // iterate through all the mesh triangles for (size_t kk=0; kk<mesh->num_triangles(); kk++) { // get the three vertices of the triangle MeshVertex first = mesh->vertices[ mesh->triangles[kk].vertices[0] ]; MeshVertex second = mesh->vertices[ mesh->triangles[kk].vertices[1] ]; MeshVertex third = mesh->vertices[ mesh->triangles[kk].vertices[2] ]; // calculate parameters for the intersection test real_t a = first.position.x - second.position.x; real_t b = first.position.y - second.position.y; real_t c = first.position.z - second.position.z; real_t d = first.position.x - third.position.x; real_t e = first.position.y - third.position.y; real_t f = first.position.z - third.position.z; real_t g = D.x; real_t h = D.y; real_t i = D.z; real_t j = first.position.x - E.x; real_t k = first.position.y - E.y; real_t l = first.position.z - E.z; // value cache real_t ei_hf = e*i - h*f; real_t gf_di = g*f - d*i; real_t dh_eg = d*h - e*g; real_t M = a*ei_hf + b*gf_di + c*dh_eg; // check t intersection real_t ak_jb = a*k - j*b; real_t jc_al = j*c - a*l; real_t bl_kc = b*l - k*c; real_t t = -( f*ak_jb + e*jc_al +d*bl_kc ) / M; if (t < MIN_T_THRESHOLD) { continue; } // check gamma intersection real_t gamma = ( i*ak_jb + h*jc_al + g*bl_kc ) / M; if (gamma < 0.0 || gamma > 1.0) { continue; } // check beta intersection real_t beta = ( j*ei_hf + k*gf_di + l*dh_eg ) / M; if (beta < 0.0 || beta > 1.0-gamma) { continue; } // calculate current position // get normal transformation matrix Matrix4 invMat_inv; make_transformation_matrix(&invMat_inv, position, orientation, scale); // calcualte world position Vector3 local_pos = E + t*D; Vector3 world_pos = invMat_inv.transform_point(local_pos); // need to check if this is smaller than the current min_dis if (distance(ray.e, world_pos) >= min_dis) { continue; } // reach here means intersection found, you are allowed to modify returned result // update distance first min_dis = distance(ray.e, world_pos); // set intersection found flag result.intersect = true; // set intersection position result.position = world_pos; // compute and set normal Vector3 local_norm = normalize(first.normal + second.normal + third.normal); result.normal = normalize(normMat * local_norm); // calculate texture color at this point if (material->texture_filename.empty()) { // if none of the material has texture, return white result.texture = Color3::White(); } else { // get texture coordinates first Vector2 temp_tex = first.tex_coord * (1.0-beta-gamma) + second.tex_coord * beta + third.tex_coord * gamma; // Bug fix: here need to solve the texture wrap problem temp_tex.x = temp_tex.x - floor(temp_tex.x); temp_tex.y = temp_tex.y - floor(temp_tex.y); // get the width and height int width, height; material->get_texture_size(&width, &height); // set the texture color result.texture = material->get_texture_pixel( (int)(temp_tex.x*(real_t)(width)), (int)(temp_tex.y*(real_t)(height)) ); } } // this can be done outside the for loop (save time) // calculate ambient color result.ambient = material->ambient; // calculate diffuse color result.diffuse = material->diffuse; // calculate specular color result.specular = material->specular; // calulate refractive index result.refractive_index = material->refractive_index; // return the value return result; }
vector<Collider2d*> Collider2d::Intersect(vec3 nPos) /// Wrapper to Intersect( Collider2d* , vec3 ) { return Intersect(this , nPos); }
void Region::Intersect (Rect rect) { Region tmp = Region (rect); Intersect (&tmp); }
void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* /*dispatcher*/) { btDbvtProxy* proxy=(btDbvtProxy*)absproxy; ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); #if DBVT_BP_PREVENTFALSEUPDATE if(NotEqual(aabb,proxy->leaf->volume)) #endif { bool docollide=false; if(proxy->stage==STAGECOUNT) {/* fixed -> dynamic set */ m_sets[1].remove(proxy->leaf); proxy->leaf=m_sets[0].insert(aabb,proxy); docollide=true; } else {/* dynamic set */ ++m_updates_call; if(Intersect(proxy->leaf->volume,aabb)) {/* Moving */ const btVector3 delta=aabbMin-proxy->m_aabbMin; btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction); if(delta[0]<0) velocity[0]=-velocity[0]; if(delta[1]<0) velocity[1]=-velocity[1]; if(delta[2]<0) velocity[2]=-velocity[2]; if ( #ifdef DBVT_BP_MARGIN m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN) #else m_sets[0].update(proxy->leaf,aabb,velocity) #endif ) { ++m_updates_done; docollide=true; } } else {/* Teleporting */ m_sets[0].update(proxy->leaf,aabb); ++m_updates_done; docollide=true; } } listremove(proxy,m_stageRoots[proxy->stage]); proxy->m_aabbMin = aabbMin; proxy->m_aabbMax = aabbMax; proxy->stage = m_stageCurrent; listappend(proxy,m_stageRoots[m_stageCurrent]); if(docollide) { m_needcleanup=true; if(!m_deferedcollide) { btDbvtTreeCollider collider(this); m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); } } } }
/** Create view with all rows not in the given view (no dups) * * Calculates set-difference of this view minus arg view. Result * is a subset, unlike c4_View::Different. Will only work if both * input views are sets, i.e. they have no duplicate rows in them. * * This view operation is based on a read-only custom viewer. */ c4_View c4_View::Minus(const c4_View &view_ ///< the second view )const { // inefficient: calculate difference, then keep only those in self return Intersect(Different(view_)); }
void BruteForceTexture(int x, int y, int samps = 1000) { std::vector<PosFilter> _filter_elems; // Sub pixel sampling const int nthread = std::thread::hardware_concurrency(); #pragma omp parallel for schedule(dynamic, 1) for(int t=0; t<nthread; ++t) { Random rng(t + nthread*clock()); for(int s=0; s<samps/nthread; s++){ // Create the RNG and get the sub-pixel sample float dx = rng(); float dy = rng(); // Generate the pixel direction Vector d = cx*((dx + x)/width - .5) + cy*((dy + y)/height - .5) + cam.d; d.Normalize(); // Evaluate the Covariance and Radiance at the pixel location const auto filter = indirect_filter(Ray(cam.o, d), rng, 0, 1); #pragma omp critical { _filter_elems.push_back(filter); } } } // Loop over the rows and columns of the image and evaluate radiance and // covariance per pixel using Monte-Carlo. float max_ref = 0.0f; #pragma omp parallel for schedule(dynamic, 1), shared(max_ref) for (int y=0; y<height; y++){ float max_temp = 0.0f; for (int x=0; x<width; x++) { int i=(width-x-1)*height+y; float _r = 0.0f; // Generate the pixel direction Vector d = cx*((0.5 + x)/width - .5) + cy*((0.5 + y)/height - .5) + cam.d; d.Normalize(); Ray ray(cam.o, d); double t; int id; if(!Intersect(spheres, ray, t, id)){ continue; } Vector hitp = ray.o + t*ray.d; for(auto& elem : _filter_elems) { const auto& p = elem.first; const auto x = Vector::Norm(hitp-p) / filterRadius; _r += (0.3989422804f/filterRadius) * exp(-0.5f * pow(x, 2)) * elem.second.x; } const auto scale = 20.f; const auto Nold = nPassesFilter * samps; const auto Nnew = (nPassesFilter+1) * samps; ref_img[i] = (ref_img[i]*Nold + scale*_r) / float(Nnew); max_temp = std::max(ref_img[i], max_temp); } #pragma omp critical { max_ref = std::max(max_ref, max_temp); } } // Update the scaling ref_scale = 1.0f/max_ref; // Progressive refinement of the radius and number of passes filterRadius *= sqrt((nPassesFilter + 0.8) / (nPassesFilter + 1.0)); ++nPassesFilter; }
TIntersection KDTree::IntersectP(Ray &a_Ray) { // Compute initial parametric range of ray inside kd-tree extent float tmin; TIntersection Intersect(-1,a_Ray.maxt); if (!bounds.IntersectP(a_Ray, &tmin, &a_Ray.maxt)) { return Intersect; } // Prepare to traverse kd-tree for ray Vector invDir(1.f/a_Ray.d.x, 1.f/a_Ray.d.y, 1.f/a_Ray.d.z); int TriangleID; TIntersection test; bool result = false; #define MAX_TODO 64 KdToDo todo[MAX_TODO]; int todoPos = 0; const KdNode *node = &nodes[0]; while (node != NULL) { if (node->IsLeaf()) { // Check for shadow ray intersections inside leaf node uint32_t nPrimitives = node->nPrimitives(); if (nPrimitives == 1) { const KDTreePrimitiveInfo &prim = primitives[node->onePrimitive]; //m_Candidates++; if (prim.bounds.IntersectP(a_Ray)){ TriangleID = prim.primitiveNumber; //candidates++; if (RayTriangleTest(a_Ray.o,a_Ray.d,test,TriangleID,m_pPrimitives) && test.t<Intersect.t) { Intersect.t = test.t; Intersect.u = test.u; Intersect.v = test.v; Intersect.IDTr = TriangleID; result = true; break; } } //break; } else { uint32_t *prims = node->primitives; bool tmp = false; for (uint32_t i = 0; i < nPrimitives; ++i) { const KDTreePrimitiveInfo &prim = primitives[prims[i]]; //m_Candidates++; if (prim.bounds.IntersectP(a_Ray)){ TriangleID = prim.primitiveNumber; //candidates++; if (RayTriangleTest(a_Ray.o,a_Ray.d,test,TriangleID,m_pPrimitives) && test.t<Intersect.t) { Intersect.t = test.t; Intersect.u = test.u; Intersect.v = test.v; Intersect.IDTr = TriangleID; result = true; tmp = true; } } } if(tmp) break; } // Grab next node to process from todo list if (todoPos > 0) { --todoPos; node = todo[todoPos].node; tmin = todo[todoPos].tmin; a_Ray.maxt = todo[todoPos].maxT; } else break; } else { // Process kd-tree interior node // Compute parametric distance along ray to split plane int axis = node->SplitAxis(); float tplane = (node->SplitPos() - a_Ray.o[axis]) * invDir[axis]; // Get node children pointers for ray const KdNode *firstChild, *secondChild; int belowFirst = (a_Ray.o[axis] < node->SplitPos()) || (a_Ray.o[axis] == node->SplitPos() && a_Ray.d[axis] >= 0); if (belowFirst) { firstChild = node + 1; secondChild = &nodes[node->AboveChild()]; } else { firstChild = &nodes[node->AboveChild()]; secondChild = node + 1; } // Advance to next child node, possibly enqueue other child if (tplane > a_Ray.maxt || tplane <= 0) node = firstChild; else if (tplane < tmin) node = secondChild; else { // Enqueue _secondChild_ in todo list todo[todoPos].node = secondChild; todo[todoPos].tmin = tplane; todo[todoPos].maxT = a_Ray.maxt; ++todoPos; node = firstChild; a_Ray.maxt = tplane; } } } return Intersect; }
bool OctreeAccel::IntersectP(const Ray &ray) const { Intersection *in = new Intersection(); return Intersect(ray, in); }
void btDbvt::benchmark() { static const btScalar cfgVolumeCenterScale = 100; static const btScalar cfgVolumeExentsBase = 1; static const btScalar cfgVolumeExentsScale = 4; static const int cfgLeaves = 8192; static const bool cfgEnable = true; //[1] btDbvtVolume intersections bool cfgBenchmark1_Enable = cfgEnable; static const int cfgBenchmark1_Iterations = 8; static const int cfgBenchmark1_Reference = 3499; //[2] btDbvtVolume merges bool cfgBenchmark2_Enable = cfgEnable; static const int cfgBenchmark2_Iterations = 4; static const int cfgBenchmark2_Reference = 1945; //[3] btDbvt::collideTT bool cfgBenchmark3_Enable = cfgEnable; static const int cfgBenchmark3_Iterations = 512; static const int cfgBenchmark3_Reference = 5485; //[4] btDbvt::collideTT self bool cfgBenchmark4_Enable = cfgEnable; static const int cfgBenchmark4_Iterations = 512; static const int cfgBenchmark4_Reference = 2814; //[5] btDbvt::collideTT xform bool cfgBenchmark5_Enable = cfgEnable; static const int cfgBenchmark5_Iterations = 512; static const btScalar cfgBenchmark5_OffsetScale = 2; static const int cfgBenchmark5_Reference = 7379; //[6] btDbvt::collideTT xform,self bool cfgBenchmark6_Enable = cfgEnable; static const int cfgBenchmark6_Iterations = 512; static const btScalar cfgBenchmark6_OffsetScale = 2; static const int cfgBenchmark6_Reference = 7270; //[7] btDbvt::rayTest bool cfgBenchmark7_Enable = cfgEnable; static const int cfgBenchmark7_Passes = 32; static const int cfgBenchmark7_Iterations = 65536; static const int cfgBenchmark7_Reference = 6307; //[8] insert/remove bool cfgBenchmark8_Enable = cfgEnable; static const int cfgBenchmark8_Passes = 32; static const int cfgBenchmark8_Iterations = 65536; static const int cfgBenchmark8_Reference = 2105; //[9] updates (teleport) bool cfgBenchmark9_Enable = cfgEnable; static const int cfgBenchmark9_Passes = 32; static const int cfgBenchmark9_Iterations = 65536; static const int cfgBenchmark9_Reference = 1879; //[10] updates (jitter) bool cfgBenchmark10_Enable = cfgEnable; static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale/10000; static const int cfgBenchmark10_Passes = 32; static const int cfgBenchmark10_Iterations = 65536; static const int cfgBenchmark10_Reference = 1244; //[11] optimize (incremental) bool cfgBenchmark11_Enable = cfgEnable; static const int cfgBenchmark11_Passes = 64; static const int cfgBenchmark11_Iterations = 65536; static const int cfgBenchmark11_Reference = 2510; //[12] btDbvtVolume notequal bool cfgBenchmark12_Enable = cfgEnable; static const int cfgBenchmark12_Iterations = 32; static const int cfgBenchmark12_Reference = 3677; //[13] culling(OCL+fullsort) bool cfgBenchmark13_Enable = cfgEnable; static const int cfgBenchmark13_Iterations = 1024; static const int cfgBenchmark13_Reference = 2231; //[14] culling(OCL+qsort) bool cfgBenchmark14_Enable = cfgEnable; static const int cfgBenchmark14_Iterations = 8192; static const int cfgBenchmark14_Reference = 3500; //[15] culling(KDOP+qsort) bool cfgBenchmark15_Enable = cfgEnable; static const int cfgBenchmark15_Iterations = 8192; static const int cfgBenchmark15_Reference = 1151; //[16] insert/remove batch bool cfgBenchmark16_Enable = cfgEnable; static const int cfgBenchmark16_BatchCount = 256; static const int cfgBenchmark16_Passes = 16384; static const int cfgBenchmark16_Reference = 5138; //[17] select bool cfgBenchmark17_Enable = cfgEnable; static const int cfgBenchmark17_Iterations = 4; static const int cfgBenchmark17_Reference = 3390; btClock wallclock; printf("Benchmarking dbvt...\r\n"); printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale); printf("\tExtents base: %f\r\n",cfgVolumeExentsBase); printf("\tExtents range: %f\r\n",cfgVolumeExentsScale); printf("\tLeaves: %u\r\n",cfgLeaves); printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume)); printf("\tsizeof(btDbvtNode): %u bytes\r\n",sizeof(btDbvtNode)); if(cfgBenchmark1_Enable) {// Benchmark 1 srand(380843); btAlignedObjectArray<btDbvtVolume> volumes; btAlignedObjectArray<bool> results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); for(int i=0;i<cfgLeaves;++i) { volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); } printf("[1] btDbvtVolume intersections: "); wallclock.reset(); for(int i=0;i<cfgBenchmark1_Iterations;++i) { for(int j=0;j<cfgLeaves;++j) { for(int k=0;k<cfgLeaves;++k) { results[k]=Intersect(volumes[j],volumes[k]); } } } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time); } if(cfgBenchmark2_Enable) {// Benchmark 2 srand(380843); btAlignedObjectArray<btDbvtVolume> volumes; btAlignedObjectArray<btDbvtVolume> results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); for(int i=0;i<cfgLeaves;++i) { volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); } printf("[2] btDbvtVolume merges: "); wallclock.reset(); for(int i=0;i<cfgBenchmark2_Iterations;++i) { for(int j=0;j<cfgLeaves;++j) { for(int k=0;k<cfgLeaves;++k) { Merge(volumes[j],volumes[k],results[k]); } } } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time); } if(cfgBenchmark3_Enable) {// Benchmark 3 srand(380843); btDbvt dbvt[2]; btDbvtBenchmark::NilPolicy policy; btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]); btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]); dbvt[0].optimizeTopDown(); dbvt[1].optimizeTopDown(); printf("[3] btDbvt::collideTT: "); wallclock.reset(); for(int i=0;i<cfgBenchmark3_Iterations;++i) { btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy); } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time); } if(cfgBenchmark4_Enable) {// Benchmark 4 srand(380843); btDbvt dbvt; btDbvtBenchmark::NilPolicy policy; btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); printf("[4] btDbvt::collideTT self: "); wallclock.reset(); for(int i=0;i<cfgBenchmark4_Iterations;++i) { btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy); } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time); } if(cfgBenchmark5_Enable) {// Benchmark 5 srand(380843); btDbvt dbvt[2]; btAlignedObjectArray<btTransform> transforms; btDbvtBenchmark::NilPolicy policy; transforms.resize(cfgBenchmark5_Iterations); for(int i=0;i<transforms.size();++i) { transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale); } btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]); btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]); dbvt[0].optimizeTopDown(); dbvt[1].optimizeTopDown(); printf("[5] btDbvt::collideTT xform: "); wallclock.reset(); for(int i=0;i<cfgBenchmark5_Iterations;++i) { btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy); } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time); } if(cfgBenchmark6_Enable) {// Benchmark 6 srand(380843); btDbvt dbvt; btAlignedObjectArray<btTransform> transforms; btDbvtBenchmark::NilPolicy policy; transforms.resize(cfgBenchmark6_Iterations); for(int i=0;i<transforms.size();++i) { transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale); } btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); printf("[6] btDbvt::collideTT xform,self: "); wallclock.reset(); for(int i=0;i<cfgBenchmark6_Iterations;++i) { btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy); } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time); } if(cfgBenchmark7_Enable) {// Benchmark 7 srand(380843); btDbvt dbvt; btAlignedObjectArray<btVector3> rayorg; btAlignedObjectArray<btVector3> raydir; btDbvtBenchmark::NilPolicy policy; rayorg.resize(cfgBenchmark7_Iterations); raydir.resize(cfgBenchmark7_Iterations); for(int i=0;i<rayorg.size();++i) { rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2); raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2); } btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); printf("[7] btDbvt::rayTest: "); wallclock.reset(); for(int i=0;i<cfgBenchmark7_Passes;++i) { for(int j=0;j<cfgBenchmark7_Iterations;++j) { btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy); } } const int time=(int)wallclock.getTimeMilliseconds(); unsigned rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations; printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time); } if(cfgBenchmark8_Enable) {// Benchmark 8 srand(380843); btDbvt dbvt; btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); printf("[8] insert/remove: "); wallclock.reset(); for(int i=0;i<cfgBenchmark8_Passes;++i) { for(int j=0;j<cfgBenchmark8_Iterations;++j) { dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0)); } } const int time=(int)wallclock.getTimeMilliseconds(); const int ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations; printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time); } if(cfgBenchmark9_Enable) {// Benchmark 9 srand(380843); btDbvt dbvt; btAlignedObjectArray<const btDbvtNode*> leaves; btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); dbvt.extractLeaves(dbvt.m_root,leaves); printf("[9] updates (teleport): "); wallclock.reset(); for(int i=0;i<cfgBenchmark9_Passes;++i) { for(int j=0;j<cfgBenchmark9_Iterations;++j) { dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]), btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale)); } } const int time=(int)wallclock.getTimeMilliseconds(); const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations; printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time); } if(cfgBenchmark10_Enable) {// Benchmark 10 srand(380843); btDbvt dbvt; btAlignedObjectArray<const btDbvtNode*> leaves; btAlignedObjectArray<btVector3> vectors; vectors.resize(cfgBenchmark10_Iterations); for(int i=0;i<vectors.size();++i) { vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale; } btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); dbvt.extractLeaves(dbvt.m_root,leaves); printf("[10] updates (jitter): "); wallclock.reset(); for(int i=0;i<cfgBenchmark10_Passes;++i) { for(int j=0;j<cfgBenchmark10_Iterations;++j) { const btVector3& d=vectors[j]; btDbvtNode* l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]); btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d); dbvt.update(l,v); } } const int time=(int)wallclock.getTimeMilliseconds(); const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations; printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time); } if(cfgBenchmark11_Enable) {// Benchmark 11 srand(380843); btDbvt dbvt; btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); printf("[11] optimize (incremental): "); wallclock.reset(); for(int i=0;i<cfgBenchmark11_Passes;++i) { dbvt.optimizeIncremental(cfgBenchmark11_Iterations); } const int time=(int)wallclock.getTimeMilliseconds(); const int op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations; printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000); } if(cfgBenchmark12_Enable) {// Benchmark 12 srand(380843); btAlignedObjectArray<btDbvtVolume> volumes; btAlignedObjectArray<bool> results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); for(int i=0;i<cfgLeaves;++i) { volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); } printf("[12] btDbvtVolume notequal: "); wallclock.reset(); for(int i=0;i<cfgBenchmark12_Iterations;++i) { for(int j=0;j<cfgLeaves;++j) { for(int k=0;k<cfgLeaves;++k) { results[k]=NotEqual(volumes[j],volumes[k]); } } } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time); } if(cfgBenchmark13_Enable) {// Benchmark 13 srand(380843); btDbvt dbvt; btAlignedObjectArray<btVector3> vectors; btDbvtBenchmark::NilPolicy policy; vectors.resize(cfgBenchmark13_Iterations); for(int i=0;i<vectors.size();++i) { vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); } btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); printf("[13] culling(OCL+fullsort): "); wallclock.reset(); for(int i=0;i<cfgBenchmark13_Iterations;++i) { static const btScalar offset=0; policy.m_depth=-SIMD_INFINITY; dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy); } const int time=(int)wallclock.getTimeMilliseconds(); const int t=cfgBenchmark13_Iterations; printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time); } if(cfgBenchmark14_Enable) {// Benchmark 14 srand(380843); btDbvt dbvt; btAlignedObjectArray<btVector3> vectors; btDbvtBenchmark::P14 policy; vectors.resize(cfgBenchmark14_Iterations); for(int i=0;i<vectors.size();++i) { vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); } btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); policy.m_nodes.reserve(cfgLeaves); printf("[14] culling(OCL+qsort): "); wallclock.reset(); for(int i=0;i<cfgBenchmark14_Iterations;++i) { static const btScalar offset=0; policy.m_nodes.resize(0); dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false); policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc); } const int time=(int)wallclock.getTimeMilliseconds(); const int t=cfgBenchmark14_Iterations; printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time); } if(cfgBenchmark15_Enable) {// Benchmark 15 srand(380843); btDbvt dbvt; btAlignedObjectArray<btVector3> vectors; btDbvtBenchmark::P15 policy; vectors.resize(cfgBenchmark15_Iterations); for(int i=0;i<vectors.size();++i) { vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); } btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); policy.m_nodes.reserve(cfgLeaves); printf("[15] culling(KDOP+qsort): "); wallclock.reset(); for(int i=0;i<cfgBenchmark15_Iterations;++i) { static const btScalar offset=0; policy.m_nodes.resize(0); policy.m_axis=vectors[i]; dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy); policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc); } const int time=(int)wallclock.getTimeMilliseconds(); const int t=cfgBenchmark15_Iterations; printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time); } if(cfgBenchmark16_Enable) {// Benchmark 16 srand(380843); btDbvt dbvt; btAlignedObjectArray<btDbvtNode*> batch; btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); dbvt.optimizeTopDown(); batch.reserve(cfgBenchmark16_BatchCount); printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount); wallclock.reset(); for(int i=0;i<cfgBenchmark16_Passes;++i) { for(int j=0;j<cfgBenchmark16_BatchCount;++j) { batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0)); } for(int j=0;j<cfgBenchmark16_BatchCount;++j) { dbvt.remove(batch[j]); } batch.resize(0); } const int time=(int)wallclock.getTimeMilliseconds(); const int ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount; printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time)); } if(cfgBenchmark17_Enable) {// Benchmark 17 srand(380843); btAlignedObjectArray<btDbvtVolume> volumes; btAlignedObjectArray<int> results; btAlignedObjectArray<int> indices; volumes.resize(cfgLeaves); results.resize(cfgLeaves); indices.resize(cfgLeaves); for(int i=0;i<cfgLeaves;++i) { indices[i]=i; volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); } for(int i=0;i<cfgLeaves;++i) { btSwap(indices[i],indices[rand()%cfgLeaves]); } printf("[17] btDbvtVolume select: "); wallclock.reset(); for(int i=0;i<cfgBenchmark17_Iterations;++i) { for(int j=0;j<cfgLeaves;++j) { for(int k=0;k<cfgLeaves;++k) { const int idx=indices[k]; results[idx]=Select(volumes[idx],volumes[j],volumes[k]); } } } const int time=(int)wallclock.getTimeMilliseconds(); printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time); } printf("\r\n\r\n"); }
bool Rect2f::Intersect( Math::Vector2f vec2f )const { return Intersect(vec2f.x,vec2f.y); }
void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher) { if (m_paircache->hasDeferredRemoval()) { btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray(); //perform a sort, to find duplicates and to sort 'invalid' pairs to the end overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); int invalidPair = 0; int i; btBroadphasePair previousPair; previousPair.m_pProxy0 = 0; previousPair.m_pProxy1 = 0; previousPair.m_algorithm = 0; for (i=0;i<overlappingPairArray.size();i++) { btBroadphasePair& pair = overlappingPairArray[i]; bool isDuplicate = (pair == previousPair); previousPair = pair; bool needsRemoval = false; if (!isDuplicate) { //important to perform AABB check that is consistent with the broadphase btDbvtProxy* pa=(btDbvtProxy*)pair.m_pProxy0; btDbvtProxy* pb=(btDbvtProxy*)pair.m_pProxy1; bool hasOverlap = Intersect(pa->leaf->volume,pb->leaf->volume); if (hasOverlap) { needsRemoval = false; } else { needsRemoval = true; } } else { //remove duplicate needsRemoval = true; //should have no algorithm btAssert(!pair.m_algorithm); } if (needsRemoval) { m_paircache->cleanOverlappingPair(pair,dispatcher); pair.m_pProxy0 = 0; pair.m_pProxy1 = 0; invalidPair++; } } //perform a sort, to sort 'invalid' pairs to the end overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); overlappingPairArray.resize(overlappingPairArray.size() - invalidPair); } }
bool Sphere::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { Thread->Stats()[Ray_Sphere_Tests]++; if(Do_Ellipsoid) { register int Intersection_Found; DBL Depth1, Depth2, len; Vector3d IPoint; BasicRay New_Ray; // Transform the ray into the ellipsoid's space MInvTransRay(New_Ray, ray, Trans); len = New_Ray.Direction.length(); New_Ray.Direction /= len; Intersection_Found = false; if(Intersect(New_Ray, Center, Sqr(Radius), &Depth1, &Depth2)) { Thread->Stats()[Ray_Sphere_Tests_Succeeded]++; if((Depth1 > DEPTH_TOLERANCE) && (Depth1 < MAX_DISTANCE)) { IPoint = New_Ray.Evaluate(Depth1); MTransPoint(IPoint, IPoint, Trans); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth1 / len, IPoint, this)); Intersection_Found = true; } } if((Depth2 > DEPTH_TOLERANCE) && (Depth2 < MAX_DISTANCE)) { IPoint = New_Ray.Evaluate(Depth2); MTransPoint(IPoint, IPoint, Trans); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth2 / len, IPoint, this)); Intersection_Found = true; } } } return(Intersection_Found); } else { register int Intersection_Found; DBL Depth1, Depth2; Vector3d IPoint; Intersection_Found = false; if(Intersect(ray, Center, Sqr(Radius), &Depth1, &Depth2)) { Thread->Stats()[Ray_Sphere_Tests_Succeeded]++; if((Depth1 > DEPTH_TOLERANCE) && (Depth1 < MAX_DISTANCE)) { IPoint = ray.Evaluate(Depth1); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth1, IPoint, this)); Intersection_Found = true; } } if((Depth2 > DEPTH_TOLERANCE) && (Depth2 < MAX_DISTANCE)) { IPoint = ray.Evaluate(Depth2); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth2, IPoint, this)); Intersection_Found = true; } } } return(Intersection_Found); } }
void btDbvtBroadphase::collide(btDispatcher* dispatcher) { /*printf("---------------------------------------------------------\n"); printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves); printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves); printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs()); { int i; for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++) { printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(), getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid()); } printf("\n"); } */ SPC(m_profiling.m_total); /* optimize */ m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); if(m_fixedleft) { const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); m_fixedleft=btMax<int>(0,m_fixedleft-count); } /* dynamic -> fixed set */ m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; btDbvtProxy* current=m_stageRoots[m_stageCurrent]; if(current) { btDbvtTreeCollider collider(this); do { btDbvtProxy* next=current->links[1]; listremove(current,m_stageRoots[current->stage]); listappend(current,m_stageRoots[STAGECOUNT]); #if DBVT_BP_ACCURATESLEEPING m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); collider.proxy=current; btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); #endif m_sets[0].remove(current->leaf); ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); current->leaf = m_sets[1].insert(curAabb,current); current->stage = STAGECOUNT; current = next; } while(current); m_fixedleft=m_sets[1].m_leaves; m_needcleanup=true; } /* collide dynamics */ { btDbvtTreeCollider collider(this); if(m_deferedcollide) { SPC(m_profiling.m_fdcollide); m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider); } if(m_deferedcollide) { SPC(m_profiling.m_ddcollide); m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider); } } /* clean up */ if(m_needcleanup) { SPC(m_profiling.m_cleanup); btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); if(pairs.size()>0) { int ni=btMin(pairs.size(),btMax<int>(m_newpairs,(pairs.size()*m_cupdates)/100)); for(int i=0;i<ni;++i) { btBroadphasePair& p=pairs[(m_cid+i)%pairs.size()]; btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; if(!Intersect(pa->leaf->volume,pb->leaf->volume)) { #if DBVT_BP_SORTPAIRS if(pa->m_uniqueId>pb->m_uniqueId) btSwap(pa,pb); #endif m_paircache->removeOverlappingPair(pa,pb,dispatcher); --ni;--i; } } if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; } } ++m_pid; m_newpairs=1; m_needcleanup=false; if(m_updates_call>0) { m_updates_ratio=m_updates_done/(btScalar)m_updates_call; } else { m_updates_ratio=0; } m_updates_done/=2; m_updates_call/=2; }
vector<Collider2d*> Collider2d::Intersect( Collider2d* target ) /// Wrapper to Intersect( Collider2d* , vec3 ) { return Intersect( target, target->owner->transform.gPosition() ); }
bool Shade(Path* path, Geometry *geometry, BVHAccel *bvh, const RayHit& rayHit) { uint tracedShadowRayCount; if (rayHit.index == 0xffffffffu) { return false; } // Something was hit unsigned int currentTriangleIndex = rayHit.index; RGB triInterpCol = geometry->triangles[currentTriangleIndex].InterpolateColor( geometry->vertColors, rayHit.b1, rayHit.b2); Normal shadeN = geometry->triangles[currentTriangleIndex].InterpolateNormal( geometry->vertNormals, rayHit.b1, rayHit.b2); // Calculate next step path->depth++; // Check if I have to stop if (path->depth >= MAX_PATH_DEPTH) { // Too depth, terminate the path return false; } else if (path->depth > 2) { // Russian Rulette, maximize cos const float p = min(1.f, triInterpCol.filter() * AbsDot(shadeN, path->pathRay.d)); if (p > getFloatRNG(&path->seed)) path->throughput /= p; else { // Terminate the path return false; } } //-------------------------------------------------------------------------- // Build the shadow ray //-------------------------------------------------------------------------- // Check if it is a light source float RdotShadeN = Dot(path->pathRay.d, shadeN); if (geometry->IsLight(currentTriangleIndex)) { // Check if we are on the right side of the light source if ((path->depth == 1) && (RdotShadeN < 0.f)) path->radiance += triInterpCol * path->throughput; // Terminate the path return false; } if (RdotShadeN > 0.f) { // Flip shade normal shadeN = -shadeN; } else RdotShadeN = -RdotShadeN; path->throughput *= RdotShadeN * triInterpCol; // Trace shadow rays const Point hitPoint = path->pathRay(rayHit.t); tracedShadowRayCount = 0; const float lightStrategyPdf = static_cast<float> (SHADOWRAY) / static_cast<float> (geometry->nLights); float lightPdf[SHADOWRAY]; RGB lightColor[SHADOWRAY]; Ray shadowRay[SHADOWRAY]; for (unsigned int i = 0; i < SHADOWRAY; ++i) { // Select the light to sample const unsigned int currentLightIndex = geometry->SampleLights(getFloatRNG(&path->seed)); // const TriangleLight &light = scene->lights[currentLightIndex]; // Select a point on the surface lightColor[tracedShadowRayCount] = Sample_L(currentLightIndex, geometry, hitPoint, shadeN, getFloatRNG(&path->seed), getFloatRNG(&path->seed), &lightPdf[tracedShadowRayCount], &shadowRay[tracedShadowRayCount]); // Scale light pdf for ONE_UNIFORM strategy lightPdf[tracedShadowRayCount] *= lightStrategyPdf; // Using 0.1 instead of 0.0 to cut down fireflies if (lightPdf[tracedShadowRayCount] > 0.1f) tracedShadowRayCount++; } RayHit* rh = new RayHit[tracedShadowRayCount]; for (unsigned int i = 0; i < tracedShadowRayCount; ++i) Intersect(shadowRay[i], rh[i], bvh->bvhTree, geometry->triangles, geometry->vertices); if ((tracedShadowRayCount > 0)) { for (unsigned int i = 0; i < tracedShadowRayCount; ++i) { const RayHit *shadowRayHit = &rh[i]; if (shadowRayHit->index == 0xffffffffu) { // Nothing was hit, light is visible path->radiance += path->throughput * lightColor[i] / lightPdf[i]; } } } //-------------------------------------------------------------------------- // Build the next vertex path ray //-------------------------------------------------------------------------- // Calculate exit direction float r1 = 2.f * M_PI * getFloatRNG(&path->seed); float r2 = getFloatRNG(&path->seed); float r2s = sqrt(r2); const Vector w(shadeN); Vector u; if (fabsf(shadeN.x) > .1f) { const Vector a(0.f, 1.f, 0.f); u = Cross(a, w); } else { const Vector a(1.f, 0.f, 0.f); u = Cross(a, w); } u = Normalize(u); Vector v = Cross(w, u); Vector newDir = u * (cosf(r1) * r2s) + v * (sinf(r1) * r2s) + w * sqrtf(1.f - r2); newDir = Normalize(newDir); path->pathRay.o = hitPoint; path->pathRay.d = newDir; return true; }
vector<Collider2d*> Collider2d::Intersect() /// Wrapper to Intersect( Collider2d* ) { return Intersect(this); }
bool SHAPE_LINE_CHAIN::Intersects( const SHAPE_LINE_CHAIN& aChain ) const { INTERSECTIONS dummy; return Intersect( aChain, dummy ) != 0; }
// There could probably be a subroutine here, but I'll only fix it if it breaks. bool CEntityPhysics::HitboxCollide( const CEntityPhysics& that, const CEntityTransform& thistransform, const CEntityTransform& thattransform) const { if (m_pVertices == NULL || that.m_pVertices == NULL) return false; if (m_pVertices->size() == 0 || that.m_pVertices->size() == 0) return false; vector<CVector3> thisboxes; this->GetVertices(thistransform.GetMatrix(), thisboxes); vector<CVector3> thatboxes; that.GetVertices(thattransform.GetMatrix(), thatboxes); bool intersection = false; CVector3* this_0 = &thisboxes[0]; CVector3* this_1 = NULL; CVector3* this_2 = NULL; for (auto it = thisboxes.begin(); it != thisboxes.end(); it++) { if (!this_2) { this_2 = &*it; } else { this_1 = this_2; this_2 = &*it; CVector3* that_0 = &thatboxes[0]; CVector3* that_1 = NULL; CVector3* that_2 = NULL; for (auto it2 = thatboxes.begin(); it2 != thatboxes.end(); it2++) { if (!that_2) { that_2 = &*it2; } else { that_1 = that_2; that_2 = &*it2; intersection = intersection || Intersect(*this_1,*this_2,*that_1,*that_2); if (intersection) return intersection; } } intersection = intersection || Intersect(*this_2,*this_0,*that_2,*that_0); } } CVector3* that_0 = &thatboxes[0]; CVector3* that_1 = NULL; CVector3* that_2 = NULL; for (auto it2 = thatboxes.begin(); it2 != thatboxes.end(); it2++) { if (!that_2) { that_2 = &*it2; } else { that_1 = that_2; that_2 = &*it2; intersection = intersection || Intersect(*this_1,*this_2,*that_1,*that_2); } } intersection = intersection || Intersect(*this_2,*this_0,*that_2,*that_0); that_0 = &thatboxes[0]; that_1 = NULL; that_2 = NULL; for (auto it3 = thatboxes.begin(); it3 != thatboxes.end(); it3++) { if (!that_2) { that_2 = &*it3; } else { that_1 = that_2; that_2 = &*it3; intersection = intersection || Intersect(thistransform.GetPosition(),this->m_PreviousPosition,*that_1,*that_2); } } intersection = intersection || Intersect(thistransform.GetPosition(),this->m_PreviousPosition,*that_2,*that_0); this_0 = &thatboxes[0]; this_1 = NULL; this_2 = NULL; for (auto it4 = thisboxes.begin(); it4 != thisboxes.end(); it4++) { if (!this_2) { this_2 = &*it4; } else { this_1 = that_2; this_2 = &*it4; intersection = intersection || Intersect(thattransform.GetPosition(),that.m_PreviousPosition,*this_1,*this_2); } } intersection = intersection || Intersect(thattransform.GetPosition(),that.m_PreviousPosition,*this_2,*this_0); return intersection; }
bool Rect< TReal >::Intersect( const Rect& r ) { return Intersect( r.Left, r.Top, r.Right, r.Bottom ); }