static ISTATUS SphereComputeNormal( _In_ const void *context, _In_ POINT3 hit_point, _In_ uint32_t face_hit, _Out_ PVECTOR3 surface_normal ) { if (face_hit > SPHERE_BACK_FACE) { return ISTATUS_INVALID_ARGUMENT_01; } PCSPHERE sphere = (PCSPHERE)context; VECTOR3 normal; if (face_hit == SPHERE_FRONT_FACE) { normal = PointSubtract(hit_point, sphere->center); } else { normal = PointSubtract(sphere->center, hit_point); } *surface_normal = VectorNormalize(normal, NULL, NULL); return ISTATUS_SUCCESS; }
float BluePrintDetect::CalculateError( vector<CloudModel*> blueprints, vector<CloudModel*> clouds ){ if(blueprints.size() > clouds.size()) return 0;//you can never have a matching pattern with too few clouds Point comBlueprints; BluePrintDetect::ComputeCenterOfMass(blueprints,comBlueprints); Point comClouds; BluePrintDetect::ComputeCenterOfMass(clouds,comClouds); if (comClouds.y < 75) { return 0.0f; } Point diff; PointSubtract(comBlueprints,comClouds,diff); float score = 0; for(unsigned int i = 0; i < blueprints.size();i++){ CloudModel* cloud = blueprints[i]; assert(clouds.size()>0); CloudModel* closest = BluePrintDetect::GetClosestNeighbor(cloud,clouds,diff); for(unsigned int j = 0; j < clouds.size();j++){ if(clouds[j] == closest){ clouds.erase(clouds.begin() + j); break; } } score += BluePrintDetect::CloudsDeviation(cloud,closest,diff); } if(blueprints.size()>0) return score / blueprints.size(); else return 0; }
static ISTATUS SphereTrace( _In_ const void *context, _In_ PCRAY ray, _In_ PSHAPE_HIT_ALLOCATOR allocator, _Out_ PHIT *hit ) { PCSPHERE sphere = (PCSPHERE)context; VECTOR3 to_center = PointSubtract(sphere->center, ray->origin); float_t distance_to_chord_midpoint = VectorDotProduct(to_center, ray->direction); float_t distance_to_center_squared = VectorDotProduct(to_center, to_center); float_t distance_to_chord_midpoint_squared = distance_to_chord_midpoint * distance_to_chord_midpoint; float_t distance_from_chord_to_center_squared = distance_to_center_squared - distance_to_chord_midpoint_squared; // The ray completely misses the sphere. No intersections are possible. if (sphere->radius_squared < distance_from_chord_to_center_squared) { return ISTATUS_NO_INTERSECTION; } float_t half_chord_length = sqrt(sphere->radius_squared - distance_from_chord_to_center_squared); // Ray intersects sphere and originates inside the sphere if (distance_to_center_squared < sphere->radius_squared) { float_t forward_hit = distance_to_chord_midpoint + half_chord_length; ISTATUS status = ShapeHitAllocatorAllocate(allocator, NULL, forward_hit, SPHERE_BACK_FACE, SPHERE_FRONT_FACE, NULL, 0, 0, hit); if (status != ISTATUS_SUCCESS) { return status; } float_t backwards_hit = distance_to_chord_midpoint - half_chord_length; status = ShapeHitAllocatorAllocate(allocator, *hit, backwards_hit, SPHERE_BACK_FACE, SPHERE_FRONT_FACE, NULL, 0, 0, hit); return status; } // Ray intersects sphere and originates outside the sphere. float_t farther_hit = distance_to_chord_midpoint + half_chord_length; ISTATUS status = ShapeHitAllocatorAllocate(allocator, NULL, farther_hit, SPHERE_BACK_FACE, SPHERE_FRONT_FACE, NULL, 0, 0, hit); if (status != ISTATUS_SUCCESS) { return status; } float_t closer_hit = distance_to_chord_midpoint - half_chord_length; status = ShapeHitAllocatorAllocate(allocator, *hit, closer_hit, SPHERE_FRONT_FACE, SPHERE_BACK_FACE, NULL, 0, 0, hit); return status; }
STATIC ISTATUS PhysxVisibilityTesterComputePdfProcessHitCallback( _Inout_ PVOID Context, _In_ PCHIT Hit, _In_ PCMATRIX ModelToWorld, _In_ VECTOR3 ModelViewer, _In_ POINT3 ModelHitPoint, _In_ POINT3 WorldHitPoint ) { PCPHYSX_LIGHT BackLight; PCPHYSX_GEOMETRY Geometry; VECTOR3 ModelSurfaceNormal; VECTOR3 NormalizedWorldSurfaceNormal; PCPHYSX_LIGHT FrontLight; PCPHYSX_LIGHTED_GEOMETRY LightedGeometry; FLOAT Pdf; PPHYSX_VISIBILITY_TESTER_COMPUTE_PDF_PROCESS_HIT_CONTEXT ProcessHitContext; ISTATUS Status; FLOAT SurfaceArea; VECTOR3 WorldSurfaceNormal; VECTOR3 WorldToLight; ProcessHitContext = (PPHYSX_VISIBILITY_TESTER_COMPUTE_PDF_PROCESS_HIT_CONTEXT) Context; Geometry = (PCPHYSX_GEOMETRY) Hit->Data; PhysxGeometryGetLight(Geometry, Hit->FrontFace, &FrontLight); if (FrontLight != ProcessHitContext->Light) { if (ProcessHitContext->FirstHit != FALSE) { return ISTATUS_NO_MORE_DATA; } return ISTATUS_SUCCESS; } Status = PhysxGeometryComputeNormal(Geometry, Hit->FrontFace, ModelHitPoint, &ModelSurfaceNormal); if (Status != ISTATUS_SUCCESS) { return Status; } PhysxLightedGeometryAdapterGetLightedGeometry(Geometry, &LightedGeometry); PhysxLightedGeometryComputeSurfaceArea(LightedGeometry, Hit->FrontFace, &SurfaceArea); WorldSurfaceNormal = VectorMatrixInverseTransposedMultiply(ModelToWorld, ModelSurfaceNormal); NormalizedWorldSurfaceNormal = VectorNormalize(WorldSurfaceNormal, NULL, NULL); WorldToLight = PointSubtract(WorldHitPoint, ProcessHitContext->ToLight.Origin); Pdf = SurfaceArea * VectorDotProduct(WorldToLight, WorldToLight) / VectorDotProduct(ProcessHitContext->ToLight.Direction, NormalizedWorldSurfaceNormal); PhysxGeometryGetLight(Geometry, Hit->BackFace, &BackLight); if (BackLight == ProcessHitContext->Light) { Pdf *= (FLOAT) 2.0f; } ProcessHitContext->Pdf += Pdf * SurfaceArea * ProcessHitContext->InverseTotalSurfaceArea; if (ProcessHitContext->FirstHit != FALSE) { ProcessHitContext->ClosestWorldPointOnLight = WorldHitPoint; ProcessHitContext->FirstHit = FALSE; } return ISTATUS_SUCCESS; }