判断一个物体是否在相机视野内思路很简单,对场景中每一个模型上的定点进行遍历,如果该点在相机视野内,那么该模型就在相机视野内,遍历结束。所以只要场景中模型数量不高,顶点数量不高,该方法执行效率还是很有保障的。
那么怎样判断一个顶点在相机视野内呢?
通过以下这段代码即可获得当前相机视野的横向开角Hangle及纵向开角Vangle。
#Get the point of camera. camDirection = cmds.camera( activeCamera , q = True , worldCenterOfInterest = True ) camPosition = cmds.camera( activeCamera , q = True , position = True ) #Get the vector of camera. camUpDirection = cmds.camera( activeCamera , q = True , worldUp = True ) camDirec = [camDirection[i] - camPosition[i] for i in range(3)] #Get the parameters of lens. F = cmds.camera(activeCamera , q = True , focalLength = True) H = cmds.camera(activeCamera , q = True , horizontalFilmAperture = True) V = cmds.camera(activeCamera , q = True , verticalFilmAperture = True) Hangle = math.degrees( math.atan2(H*25.4/2, F) ) Vangle = math.degrees( math.atan2(V*25.4/2, F) )
设相机中心到某顶点的向量为pointDir,相机方向的向量为camDirec,相机正上方的向量为camUpDirection,相机正侧方向量为camSideDirection;设camDirec与camUpDirection形成平面Vplane,camDirec与camUpDirection形成平面Hplane。只要pointDir与Vplane形成的夹角大于Vangle或者pointDir与Hplane形成的夹角大于Hangle,或者camDirec与pointDir相乘所得值小于0,那么就可以判断当前顶点不在相机视野范围内。反之该顶点处于相机视野范围内,顶点所在模型也处于相机视野范围内。
代码如下:
def calculateAngle(somepoint): pointDir = [somepoint[i] - camPosition[i] for i in range(3)] camSideDirection = [camDirec[1]*camUpDirection[2]-camDirec[2]*camUpDirection[1],camDirec[2]*camUpDirection[0]-camDirec[0]*camUpDirection[2],camDirec[0]*camUpDirection[1] - camDirec[1]*camUpDirection[0]] #the angle between two vector. VerticAngle = math.degrees(math.asin((camUpDirection[0]*pointDir[0] + camUpDirection[1]*pointDir[1] + camUpDirection[2]*pointDir[2])/(math.sqrt(camUpDirection[0]*camUpDirection[0] + camUpDirection[1]*camUpDirection[1] + camUpDirection[2]*camUpDirection[2])*math.sqrt(pointDir[0]*pointDir[0] + pointDir[1]*pointDir[1] + pointDir[2]*pointDir[2] )))) #the angle between two vector. horizoAngle = math.degrees(math.asin((camSideDirection[0]*pointDir[0] + camSideDirection[1]*pointDir[1] + camSideDirection[2]*pointDir[2])/(math.sqrt(camSideDirection[0]*camSideDirection[0] + camSideDirection[1]*camSideDirection[1] + camSideDirection[2]*camSideDirection[2])*math.sqrt(pointDir[0]*pointDir[0] + pointDir[1]*pointDir[1] + pointDir[2]*pointDir[2] )))) #the angle between two vector. FrontAngle =camDirec[0]*pointDir[0] + camDirec[1]*pointDir[1] + camDirec[2]*pointDir[2] if abs(horizoAngle) >Hangle: return False elif abs(VerticAngle) >Vangle: return False elif FrontAngle< 0: return False else: return True
该函数用于检测somepoint这个顶点是否在相机视野范围内,如果该函数返回False即表明somepoint不在相机视野范围内,返回True则反之。通过该函数对场景中所有模型的顶点进行遍历即可得知哪些模型在当前相机视野里哪些不在。