// this builds a VC problem from a list of targets. For each target, we request size, visibility, vertical // and horizontal orientation void buildVCProblem(List <GameObject> targetObjects, float desiredSize, bool addChildren) { // define list of properties List <CLVisualProperty> properties = new List <CLVisualProperty> (); List <CLVisualProperty> allProperties = new List <CLVisualProperty> (); List <CLTarget> targets = new List <CLTarget> (); List <float> weights = new List <float> (); int layerMask = (1 << 2); float preferredSize = desiredSize / (targetObjects.Count); // for each game object in the list foreach (GameObject targetobj in targetObjects) { List <GameObject> renderables = getChildrenWithRenderers(targetobj); List <GameObject> colliders = getChildrenWithColliders(targetobj); if ((renderables.Count > 0) && (colliders.Count > 0)) { CLTarget target = new CLTarget(targetobj, renderables, colliders, layerMask, CLTarget.VisibilityPointGenerationMethod.UNIFORM_IN_BB, 6); targets.Add(target); List <CLTarget> properties_targets = new List <CLTarget> (); properties_targets.Add(target); //area property with 2.5 weight List <float> sizeSatFuncCtrlX = new List <float> { 0.0f, 0.002f, preferredSize, 0.4f, 0.5f, 1.0f }; List <float> sizeSatFuncCtrlY = new List <float> { 0.0f, 0.1f, 0.8f, 1.0f, 0.1f, 0.0f }; CLSizeProperty sizeP = new CLSizeProperty(CLSizeProperty.SizeMode.AREA, targetobj.name + " size", properties_targets, sizeSatFuncCtrlX, sizeSatFuncCtrlY); weights.Add(2.5f); properties.Add(sizeP); // orientation property (see from front) with w = 1.0 List <float> hORFuncCtrlX = new List <float> { -180.0f, -90f, 0.0f, 90f, 180.0f }; List <float> hORFuncCtrlY = new List <float> { 0.0f, 0.1f, 1.0f, 0.1f, 0.0f }; CLOrientationProperty orP = new CLOrientationProperty(CLOrientationProperty.OrientationMode.HORIZONTAL, targetobj.name + " orientation", properties_targets, hORFuncCtrlX, hORFuncCtrlY); properties.Add(orP); weights.Add(1.0f); // v-orientation property (see from 90 to top), w=1.5 List <float> vORFuncCtrlX = new List <float> { 0.0f, 90.0f, 95f, 180.0f }; List <float> vORFuncCtrlY = new List <float> { 0.0f, 1.0f, 0.1f, 0.0f }; CLOrientationProperty orPV = new CLOrientationProperty(CLOrientationProperty.OrientationMode.VERTICAL_WORLD, targetobj.name + " vorientation", properties_targets, vORFuncCtrlX, vORFuncCtrlY); properties.Add(orPV); weights.Add(1.5f); // occlusion property with 4.0 weight List <float> occlFuncCtrlX = new List <float> { 0.0f, 0.5f, 0.6f, 1.0f }; List <float> occlFuncCtrlY = new List <float> { 1.0f, 0.7f, 0.1f, 0.0f }; CLOcclusionProperty occlP = new CLOcclusionProperty(targetobj.name + " occlusion", properties_targets, occlFuncCtrlX, occlFuncCtrlY, doubleSidedVisibilityChecking, randomRayCasts); weights.Add(4.0f); properties.Add(occlP); } } CLTradeOffSatisfaction satFunction = new CLTradeOffSatisfaction("all", targets, properties, weights); allProperties.AddRange(properties); allProperties.Insert(0, satFunction); camLibCam.SetSpecification(allProperties); }
// this method generates a random viewpoint with more probability where // target properties will be satisfied. It assumes we have at least a size // property for the target, plus optional angle and occlusion properties public Vector3 GenerateRandomSatisfyingPosition(CLCameraMan camera, bool considerVisibility = false) { Vector3 result = new Vector3(); bool found = false; int ntries = 0; float yFOV = (camera.cameraDomain.yFOVBounds [0] + camera.cameraDomain.yFOVBounds [1]) / 2; // we allow for 30 tries before giving up while (ntries < 30 && !found) { float distance = 0.0f; float phi = 0.0f; float theta = 0.0f; foreach (CLGroundProperty p in groundProperties) { if (p is CLSizeProperty) { CLSizeProperty sp = (CLSizeProperty)p; // this returns a random area, or width, or height, depending on the type of size // property, with more probability where the satisfaction is higher float randomSize = p.satFunction.GenerateRandomXPoint(); if (randomSize < 0.0001f) { randomSize = 0.0001f; // to avoid computing an infinite distance. } // compute distance from target size distance = ComputeDistanceFromSize(randomSize, sp.sizeType, camera, yFOV); } if (p is CLOrientationProperty) { CLOrientationProperty op = (CLOrientationProperty)p; if (op.orientation == CLOrientationProperty.OrientationMode.HORIZONTAL) { phi = Mathf.Deg2Rad * op.satFunction.GenerateRandomXPoint(); // horizontal random angle } else { theta = Mathf.Deg2Rad * op.satFunction.GenerateRandomXPoint(); // vertical random angle } } } // if we are not inside bs sphere if (distance > radius) { result = ComputeWorldPosFromSphericalCoordinates(distance, phi, theta); if (camera.InSearchSpace(new float[] { result.x, result.y, result.z })) { found = true; } } ntries++; } if (!found) { float[] randomCandidate = camera.cameraDomain.ComputeRandomViewpoint(3); result = new Vector3(randomCandidate [0], randomCandidate [1], randomCandidate [2]); //Debug.Log ("random candidate"); } else { //Debug.Log ("smart candidate in " + ntries + " tries"); } return(result); }