Render.ru

Как программно уместить объект в поле зрения камеры?

Vatis

Пользователь сайта
Рейтинг
2
#1
Есть целенаправленная камера. Программно в сцену помещается объект.
Как программно проверить попадает ли объект в поле зрения камеры?
И если не попадает, то как программно подогнать?
Решается это с помощью настроек FOV камеры, но главное - как узнать насколько виден объект в объективе камеры?

у меня ступор.. Помогите, плиз!
 

Vatis

Пользователь сайта
Рейтинг
2
#4
С опозданием, но все же. Simulating Zoom Extents All не подходит((
Направление примерно то, но логику расчет FOV не могу понять.
Нужно чтобы максимальная сторона баундинг бокса, с точки зрения камеры, умещалась в итоговое frame window. В примере выше это почти так, но камера так же захватывает кучу пустого пространства, которое не нужно.
В идеале, смотря из камеры, мы должны видеть набор объектов, четко умещенных в frame window.
Например, есть башня. В frame window она должна упираться в верхнюю и в нижнюю границы. Выше и ниже не должно быть пустого пространства. Справа и слева пустое пространство, логично, может быть (беря во внимание стандартные размеры frame window).
Буду очень признателен. если кто еще что подскажет.
 

Vatis

Пользователь сайта
Рейтинг
2
#5
нашел вот такой скрипт:
(работает просто прекрасно! но без камеры, рисует рамку вокруг объектов во вьюпорте)

global easyViewSelectionBBox
unRegisterRedrawViewsCallback easyViewSelectionBBox

fn easyViewSelectionBBox =
(
nodes = for node in selection where iskindof node GeometryClass collect node
if nodes.count > 0 do
(
view = viewport.activeViewport
local bmin = [1e9,1e9,0], bmax = [-1e9,-1e9,0]

gw.setTransform (matrix3 1)
transPoint = gw.hTransPoint
for node in nodes do
(
mesh = snapshotasmesh node
for v=1 to mesh.numverts do
(
vp = transPoint (GetVert mesh v)
if vp.x < bmin.x do bmin.x = vp.x
if vp.x > bmax.x do bmax.x = vp.x
if vp.y < bmin.y do bmin.y = vp.y
if vp.y > bmax.y do bmax.y = vp.y
)
free mesh
)
w = (bmax.x - bmin.x) as integer
h = (bmax.y - bmin.y) as integer
rect = box2 bmin.x bmin.y w h
gw.hPolyline #(bmin, point3 bmax.x bmin.y 0, bmax, point3 bmin.x bmax.y 0) on rgb:#(orange,orange,orange,orange)
gw.hText (bmin + [5,h-20,0]) ("Size: [" + (w as string) + ", " + (h as string) + "]") color:eek:range
gw.enlargeUpdateRect rect
gw.updateScreen()
)
)
registerRedrawViewsCallback easyViewSelectionBBox
completeRedraw()
 

igorznag

Мастер
Рейтинг
103
#6
Написал простой скрипт. Проверьте как он работает.
1. В новой сцене создаем один чайник (Teapot).
2. Создаем одну обычную камеру Free и устанавливаем камеру в качестве вида.
3. Выделяем чайник. Активируем вид Camera или вид Perspective.
4. Запускаем скрипт. В новом окне нажимаем кнопку "Zoom Extents Selected".
Код:
rollout igorznag_zoom_extents_selected "Zoom Extents Selected"
(
--GUI
groupBox gb_iterations "Iterations" pos:[5,5] width:280 height:40
spinner sp_main_iterations "Main:" fieldWidth:45 range:[1, 100, 5] pos:[15,20] type:#integer
spinner sp_pan_iterations "Pan:" fieldWidth:45 range:[1, 100, 5] pos:[105,20] type:#integer
spinner sp_zoom_iterations "Zoom:" fieldWidth:45 range:[1, 100, 5] pos:[190,20] type:#integer
groupBox gb_aspect "Aspect" pos:[5,45] width:130 height:40
radiobuttons rb_aspect labels:#("Render","Viewport") default:1 pos:[10,60]
button btn_apply "Zoom Extents Selected" width:130 pos:[145,58] 
--Functions
fn ZE_Cam_max cam objs = 
(
max_z=-1e9 
 for obj in objs do 
(
obj_mesh = snapshotasmesh obj  
for i=1 to obj_mesh.numverts do   
(
vp = (GetVert obj_mesh i)*viewport.getTM()  
--if vp.z >=0 do continue -- if object is behind c amera, skip it 
if(vp.z>max_z)then max_z=vp.z 
)----for i=1 to mesh.numverts do  
delete obj_mesh 
)----for obj in objs  
if(max_z!=-1e9)then 
(
if(viewport.getType()==#view_camera)then (cam.type=#free;in coordsys cam cam.pos.z=cam.pos.z+max_z;)
if(viewport.getType()==#view_persp_user)then
(
view_tm=inverse(viewport.getTM());
view_tm.row4=(view_tm.row4*(inverse view_tm)+[0,0,max_z])*view_tm;
viewport.setTM(inverse view_tm);
)--if(viewport.getType()==#view_persp_user or viewport.getType()==#view_iso_user)then
)--if(max_z!=-1e9)then 
)--fn ZE_Cam_min objs =
-----------------------------
fn ZE_Cam cam objs =
(
local  fov_temp, asp, v, obj_z2, obj_z, delta, v_ar=#(), delta_ar=#()-- declare local variables
if(rb_aspect.state==1)then asp=(renderWidth as float)/renderHeight -- calculate the renderer's image aspect ratio
if(rb_aspect.state==2)then asp=((getViewSize())[1] as float)/(getViewSize())[2]
 for obj in objs do -- loop across all objects except the camera  
(
obj_mesh = snapshotasmesh obj  
for i=1 to obj_mesh.numverts do  
(
vp = (GetVert obj_mesh i)*viewport.getTM() 
--if vp.z >=0 do continue -- if object is behind camera, skip it 
v = amax #((abs vp.x),(abs (vp.y*asp)))
if(viewport.getType()==#view_camera)then fov_temp=cam.fov
if(viewport.getType()==#view_persp_user)then fov_temp=viewport.GetFOV();
obj_z2=v/(tan (fov_temp/2.0)); obj_z=abs vp.z; delta=obj_z2-obj_z
v_angle=2*atan(-v/vp.z); append v_ar v_angle; append delta_ar delta
)----for i=1 to mesh.numverts do 
delete obj_mesh 
)----for obj in objs where obj != cam do -- loop across all objects except the camera 
if(v_ar.count>0)then
(
v_ar_max=amax v_ar; v_ar_max_index=finditem v_ar v_ar_max
delta_v_max=delta_ar[v_ar_max_index];
if(viewport.getType()==#view_camera)then (cam.type=#free;in coordsys cam cam.pos.z=cam.pos.z+delta_v_max;)
if(viewport.getType()==#view_persp_user)then
(
view_tm=inverse(viewport.getTM());
view_tm.row4=(view_tm.row4*(inverse view_tm)+[0,0,delta_v_max])*view_tm;
viewport.setTM(inverse view_tm);
)--if(viewport.getType()==#view_persp_user)then
)--if(v_ar.count>0)then
)----fn ZE_Cam cam objs = 
------------------------------------------------
fn ZE_Cam_Pan cam objs=
(
bmin = [1e9,1e9,0]; bmax = [-1e9,-1e9,0]; z_min=1e9;
gw.setTransform (matrix3 1); transPoint = gw.hTransPoint 
for obj in objs do 
( 
obj_mesh = snapshotasmesh obj 
for v=1 to obj_mesh.numverts do 
( 
vgp=(GetVert obj_mesh v); if((vgp*viewport.getTM()).z<z_min)then z_min=(vgp*viewport.getTM()).z
vp = transPoint  vgp
if vp.x < bmin.x do bmin.x = vp.x; if vp.x > bmax.x do bmax.x = vp.x
if vp.y < bmin.y do bmin.y = vp.y; if vp.y > bmax.y do bmax.y = vp.y
) 
delete obj_mesh
)
if(bmin!=[1e9,1e9,0] and bmax!=[-1e9,-1e9,0])then
(
w = (bmax.x - bmin.x) as integer ; h = (bmax.y - bmin.y) as integer 
rect = box2 bmin.x bmin.y w h 
screen_width=(getViewSize())[1]; screen_height=(getViewSize())[2]; 
center_point=bmin+[w/2,h/2,0]; center_point=[center_point.x,screen_height-center_point.y,0];
screen_center = mapScreenToView [center_point.x,center_point.y] z_min;
screen_center2 = mapScreenToView [screen_width/2,screen_height/2] z_min;
delta=[screen_center2.x,screen_center2.y,0]-[screen_center.x,screen_center.y,0]
if(viewport.getType()==#view_camera)then 
(cam.type=#free;in coordsys cam cam.pos=cam.pos-(delta/sp_pan_iterations.value);)
if(viewport.getType()==#view_persp_user)then
(
view_tm=inverse( viewport.getTM());
view_tm.row4=(view_tm.row4*(inverse view_tm)-(delta/sp_pan_iterations.value))*view_tm;
viewport.setTM(inverse view_tm);
)--if(viewport.getType()==#view_persp_user )then
)--if(bmin!=[1e9,1e9,0] and bmax!=[-1e9,-1e9,0])then
)---fn ZE_Cam_Pan cam objs=
--------------------
-- Event Handlers
on btn_apply pressed do
(
undo on
(
if(rb_aspect.state==1)then displaySafeFrames=true;
if(rb_aspect.state==2)then displaySafeFrames=false;

if(viewport.getType()==#view_camera or viewport.getType()==#view_persp_user)then
(
cam=viewport.getCamera();
fov_temp=0; if(viewport.getType()==#view_camera)then fov_temp=cam.fov
if(viewport.getType()==#view_persp_user)then fov_temp=viewport.GetFOV();
if(fov_temp>=1 and fov_temp<=175)then
(
objs = for obj in selection where iskindof obj GeometryClass collect obj 
if(objs.count>0)then
(
for i=1 to sp_main_iterations.value do
(
ZE_Cam_max cam objs; redrawViews();
for j=1 to sp_zoom_iterations.value do (ZE_Cam cam objs; redrawViews();)
for j=1 to sp_pan_iterations.value do(ZE_Cam_Pan cam objs; redrawViews();)
)--for i=1 to sp_main_iterations.value do
completeRedraw();
)--if(objs.count>0)then
)--if(viewport.GetFOV()>1 and viewport.GetFOV()<175)then
)--if(viewport.getType()==#view_camera or viewport.getType()==#view_persp_user)then
)--undo on
)--on btn_apply pressed do

)
createDialog igorznag_zoom_extents_selected 285 90
 
Рейтинг
82
#7
Возможно не до конца понял.Но разве трудно соединить(Animation/Constraints/Attachement Constraint)taget камеры c нужным объектом(или объектами)?100% результат.
 
Сверху