Есть целенаправленная камера. Программно в сцену помещается объект.
Как программно проверить попадает ли объект в поле зрения камеры?
И если не попадает, то как программно подогнать?
Решается это с помощью настроек FOV камеры, но главное - как узнать насколько виден объект в объективе камеры?
С опозданием, но все же. Simulating Zoom Extents All не подходит((
Направление примерно то, но логику расчет FOV не могу понять.
Нужно чтобы максимальная сторона баундинг бокса, с точки зрения камеры, умещалась в итоговое frame window. В примере выше это почти так, но камера так же захватывает кучу пустого пространства, которое не нужно.
В идеале, смотря из камеры, мы должны видеть набор объектов, четко умещенных в frame window.
Например, есть башня. В frame window она должна упираться в верхнюю и в нижнюю границы. Выше и ниже не должно быть пустого пространства. Справа и слева пустое пространство, логично, может быть (беря во внимание стандартные размеры frame window).
Буду очень признателен. если кто еще что подскажет.
нашел вот такой скрипт:
(работает просто прекрасно! но без камеры, рисует рамку вокруг объектов во вьюпорте)
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😮range
gw.enlargeUpdateRect rect
gw.updateScreen()
)
)
registerRedrawViewsCallback easyViewSelectionBBox
completeRedraw()
Написал простой скрипт. Проверьте как он работает.
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
Возможно не до конца понял.Но разве трудно соединить(Animation/Constraints/Attachement Constraint)taget камеры c нужным объектом(или объектами)?100% результат.
Доступ к резюме доступен только по пакетному доступу HR менеджерам зарегистрированных компаний. Узнать о вариантах корпоративных пакетов можно по ссылке.
Vatis
Как программно проверить попадает ли объект в поле зрения камеры?
И если не попадает, то как программно подогнать?
Решается это с помощью настроек FOV камеры, но главное - как узнать насколько виден объект в объективе камеры?
у меня ступор.. Помогите, плиз!
igorznag
Vatis
Vatis
Направление примерно то, но логику расчет FOV не могу понять.
Нужно чтобы максимальная сторона баундинг бокса, с точки зрения камеры, умещалась в итоговое frame window. В примере выше это почти так, но камера так же захватывает кучу пустого пространства, которое не нужно.
В идеале, смотря из камеры, мы должны видеть набор объектов, четко умещенных в frame window.
Например, есть башня. В frame window она должна упираться в верхнюю и в нижнюю границы. Выше и ниже не должно быть пустого пространства. Справа и слева пустое пространство, логично, может быть (беря во внимание стандартные размеры frame window).
Буду очень признателен. если кто еще что подскажет.
Vatis
(работает просто прекрасно! но без камеры, рисует рамку вокруг объектов во вьюпорте)
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😮range
gw.enlargeUpdateRect rect
gw.updateScreen()
)
)
registerRedrawViewsCallback easyViewSelectionBBox
completeRedraw()
igorznag
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 90diwian diwian