Preview.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. /******************************************************************************/
  4. flt GetDist(C Box &box)
  5. {
  6. Box b=box-box.center(); // center
  7. b|=b*Matrix3().setRotateY(PI_4); // include the box when it's rotated at 45 deg
  8. Vec size=b.size();
  9. flt dist= size.y/(2*Tan(D.viewFovY()/2));
  10. MAX(dist, size.x/(2*Tan(D.viewFovX()/2)));
  11. MAX(dist, size.z/(2*Tan(D.viewFovX()/2)));
  12. return dist;
  13. }
  14. void SetCam(Camera &cam, C Box &box, flt yaw, flt pitch, flt zoom) // require custom 'cam' to calculate correct velocities
  15. {
  16. cam.yaw=yaw;
  17. cam.pitch=pitch;
  18. cam.roll=0;
  19. cam.dist=GetDist(box)*zoom;
  20. cam.at=box.center();
  21. cam.setSpherical().updateVelocities(CAM_ATTACH_FREE).set();
  22. }
  23. /******************************************************************************/
  24. PreviewClass Preview;
  25. /******************************************************************************/
  26. /******************************************************************************/
  27. void PreviewClass::create()
  28. {
  29. Gui+=::EE::Window::create().level(1); // set level so it will be displayed above other editor windows
  30. ball.create(1).parts[0].base.create(Ball(1), VTX_TEX0|VTX_NRM_TAN_BIN, 16);
  31. ball.setRender().setBox();
  32. objs_container.create(S);
  33. }
  34. void PreviewClass::Render() {Preview.render();}
  35. void PreviewClass::render()
  36. {
  37. switch(Renderer())
  38. {
  39. case RM_PREPARE:
  40. {
  41. switch(elm_type)
  42. {
  43. case ELM_OBJ :
  44. case ELM_MESH: if(mesh)
  45. {
  46. SetVariation(mesh_variation); mesh->MeshLod::draw(MatrixIdentity);
  47. SetVariation();
  48. }break;
  49. case ELM_MTRL: ball.draw(MatrixIdentity); break;
  50. case ELM_ANIM: if(mesh)mesh->MeshLod::draw(anim_skel); break;
  51. }
  52. if(elm_type==ELM_WATER_MTRL)LightDir(Matrix3().setRotateXY(PI_4, PI_4).z , 1-D.ambientColor()).add(false);
  53. else LightDir(!(ActiveCam.matrix.z*2 + ActiveCam.matrix.x - ActiveCam.matrix.y), 1-D.ambientColor()).add(false);
  54. }break;
  55. case RM_BLEND:
  56. case RM_PALETTE:
  57. case RM_PALETTE1:
  58. {
  59. // particle
  60. }break;
  61. }
  62. if(Renderer()==RM_BLEND && elm_type==ELM_OBJ && body)body->drawBlend(MatrixIdentity, VecZero, VecZero, &Vec4(1, 1, 1, 0.32f));
  63. if(Renderer()==RM_CLOUD && elm_type==ELM_IMAGE && image && image->mode()==IMAGE_3D)
  64. {
  65. image->drawVolume(WHITE, TRANSPARENT, OBox(Box(1)), 0.05f);
  66. }
  67. }
  68. void PreviewClass::closeElm(C UID &elm_id)
  69. {
  70. if(video_id==elm_id){video.del(); video_id.zero();}
  71. }
  72. void PreviewClass::elmChanged(C UID &elm_id)
  73. {
  74. if(elm_id==objs_last_id)objs_last_id.zero();
  75. if(elm_id== sound_id) sound_id.zero();
  76. if(elm_id== video_id) video_id.zero();
  77. if(elm_id== mini_map_id) mini_map_id.zero();
  78. }
  79. void PreviewClass::clearProj()
  80. {
  81. sound_id.zero();
  82. video_id.zero(); video.del();
  83. mini_map_id.zero();
  84. objs_last_id.zero();
  85. }
  86. void PreviewClass::drawBack(C Rect &rect)
  87. {
  88. if(GuiSkin *skin=Gui.skin())
  89. {
  90. if(skin->region.normal ){skin->region.normal->draw(skin->region.normal_color, rect); return;}
  91. if(skin->region.normal_color.a){ rect.draw(skin->region.normal_color ); return;}
  92. }
  93. rect.draw(Gui.backgroundColor(), true );
  94. rect.draw(Gui. borderColor(), false);
  95. }
  96. void PreviewClass::draw(Elm &elm, C Rect &rect)
  97. {
  98. CurrentEnvironment().set();
  99. AMBIENT_MODE ambient =D. ambientMode(); D. ambientMode(AMBIENT_FLAT);
  100. DOF_MODE dof =D. dofMode(); D. dofMode( DOF_NONE);
  101. bool eye_adapt=D.eyeAdaptation(); D.eyeAdaptation( false);
  102. bool astros =AstrosDraw ; AstrosDraw =false;
  103. bool ocean =Water.draw ; Water.draw =false;
  104. Camera c=ActiveCam; Rect r=D.viewRect(); flt fov=D.viewFov(), from=D.viewFrom(), range=D.viewRange(); // remember
  105. Color rect_color=Gui.borderColor();
  106. mesh_variation=0;
  107. switch(elm_type=elm.type)
  108. {
  109. case ELM_OBJ:
  110. {
  111. if(ElmObj *obj_data=elm.objData())
  112. if(obj=Proj.gamePath(elm.id))
  113. {
  114. UID body_id=UIDZero; if(Elm *mesh_elm=Proj.findElm(obj_data->mesh_id))if(ElmMesh *mesh_data=mesh_elm->meshData())body_id=mesh_data->body_id;
  115. mesh=obj->mesh(); // take this from "obj->mesh" instead of "Proj.gamePath(obj_data.mesh_id)" in case object has its mesh taken from the base
  116. mesh_variation=obj->meshVariationIndex();
  117. body=Proj.gamePath(body_id);
  118. D.viewRect(rect).viewFov(PreviewFOV);
  119. flt dist=Max(0.1f, mesh ? GetDist(mesh->ext) : 0);
  120. D.viewFrom(dist*0.01f).viewRange(dist*5); if(mesh)SetCam(cam, mesh->ext, Time.appTime(), (mesh->ext.size().y<mesh->ext.size().max()*0.3f) ? -PI_4 : 0); // set
  121. Renderer(PreviewClass::Render);
  122. D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
  123. rect.draw(rect_color, false);
  124. }
  125. }break;
  126. case ELM_MESH:
  127. {
  128. mesh=Proj.gamePath(elm.id);
  129. D.viewRect(rect).viewFov(PreviewFOV);
  130. flt dist=Max(0.1f, mesh ? GetDist(mesh->ext) : 0);
  131. D.viewFrom(dist*0.01f).viewRange(dist*5); if(mesh)SetCam(cam, mesh->ext, Time.appTime(), (mesh->ext.size().y<mesh->ext.size().max()*0.3f) ? -PI_4 : 0); // set
  132. Renderer(PreviewClass::Render);
  133. D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
  134. rect.draw(rect_color, false);
  135. }break;
  136. case ELM_MTRL:
  137. {
  138. mtrl=Proj.gamePath(elm.id);
  139. ball.material(mtrl).setShader();
  140. D.viewRect(rect).viewFov(PreviewFOV);
  141. flt dist=GetDist(ball.ext);
  142. D.viewFrom(dist*0.01f).viewRange(dist*3); SetCam(cam, ball.ext, Time.appTime()/2); // set
  143. Renderer(PreviewClass::Render);
  144. D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
  145. rect.draw(rect_color, false);
  146. }break;
  147. case ELM_WATER_MTRL:
  148. {
  149. WaterMtrl temp; Swap(temp, SCAST(WaterMtrl, Water)); PlaneM water_plane=Water.plane; Water.draw=true; Water.plane.set(Vec(0, -1, 0), Vec(0, 1, 0));
  150. if(water_mtrl=Proj.gamePath(elm.id))SCAST(WaterMtrl, Water)=*water_mtrl;
  151. D.viewRect(rect).viewFov(PreviewFOV).viewFrom(0.1f).viewRange(100); SetCam(cam, Box(5), 0, -PI_6); // set
  152. Renderer(PreviewClass::Render);
  153. D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
  154. Swap(temp, SCAST(WaterMtrl, Water)); Water.plane=water_plane;
  155. rect.draw(rect_color, false);
  156. }break;
  157. case ELM_ANIM:
  158. {
  159. UID mesh_id=Proj.animToMesh(&elm); // get mesh from anim->skel->mesh
  160. if(!mesh_id.valid())if(Elm *obj=Proj.firstParent(&elm, ELM_OBJ))if(ElmObj *obj_data=obj->objData())mesh_id=obj_data->mesh_id; // get mesh from firstObjParent->mesh
  161. if( mesh_id.valid())
  162. {
  163. anim=Animations(Proj.gamePath(elm .id));
  164. mesh= Proj.gamePath(mesh_id) ;
  165. skel=mesh->skeleton();
  166. if(skel)
  167. {
  168. if(anim_skel.skeleton()!=skel || anim_skel.bones.elms()!=skel->bones.elms() || anim_skel.slots.elms()!=skel->slots.elms())anim_skel.create(skel);
  169. skel_anim.create(*skel, *anim);
  170. flt time=(anim->length() ? Frac(Time.appTime(), (dbl)anim->length()) : 0);
  171. anim_skel.clear().animate(skel_anim, time).animateRoot(*anim, time).updateMatrix().updateVelocities(false, false);
  172. }else
  173. {
  174. anim_skel.del().updateMatrix().updateVelocities();
  175. }
  176. D.viewRect(rect).viewFov(PreviewFOV);
  177. flt dist=Max(0.1f, mesh ? GetDist(mesh->ext) : 0);
  178. D.viewFrom(dist*0.01f).viewRange(dist*5); if(mesh)SetCam(cam, mesh->ext, Time.appTime()); // set
  179. Renderer(PreviewClass::Render);
  180. D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
  181. rect.draw(rect_color, false);
  182. }
  183. }break;
  184. case ELM_FONT:
  185. {
  186. TextStyle ts; ts.size=rect.h()/16; ts.font(Proj.gamePath(elm.id)); if(Font *font=ts.font()())
  187. {
  188. if(font->images().elms() && font->images()[0].mode()==IMAGE_SOFT)
  189. {
  190. drawBack(rect);
  191. D.text(TextStyleParams(true), rect, "Font is software based\nand can't be previewed");
  192. }else
  193. {
  194. Rect u=rect, d=rect; u.min.y=d.max.y=rect.centerY();
  195. cchar8 *t="ABCDEFGHIJKLMN\nOPQRSTUVWXYZ\nabcdefghijklmn\nopqrstuvwxyz\n0123456789\n!@#$%^&*+-=_()[]{}<>,.:;'\"\\|/?";
  196. u.draw(BLACK); ts.color=WHITE; ts.shadow=255; D.clip(u); D.text(ts, u, t); D.clip();
  197. d.draw(WHITE); ts.color=BLACK; ts.shadow= 0; D.clip(d); D.text(ts, d, t); D.clip();
  198. rect.draw(rect_color, false);
  199. }
  200. }
  201. }break;
  202. case ELM_TEXT_STYLE: if(TextStylePtr ts=Proj.gamePath(elm.id))
  203. {
  204. cchar8 *t="ABCDEFGHIJKLMN\nOPQRSTUVWXYZ\nabcdefghijklmn\nopqrstuvwxyz\n0123456789\n!@#$%^&*+-=_()[]{}<>,.:;'\"\\|/?";
  205. Color c=ColorInverse(ts->color); c.a=255;
  206. rect.draw(c); D.clip(rect); D.text(*ts, rect, t); D.clip();
  207. rect.draw(rect_color, false);
  208. }break;
  209. case ELM_PANEL_IMAGE:
  210. {
  211. drawBack(rect); if(PanelImagePtr panel=Proj.gamePath(elm.id))DrawPanelImage(*panel, rect);
  212. }break;
  213. case ELM_PANEL:
  214. {
  215. drawBack(rect); if(PanelPtr panel=Proj.gamePath(elm.id))panel->draw(Rect_C(rect.center(), rect.size()*0.5f));
  216. }break;
  217. case ELM_GUI_SKIN:
  218. {
  219. if(GuiSkinPtr skin=Proj.gamePath(elm.id))
  220. {
  221. GuiSkinPtr temp=Gui.skin; Gui.skin=skin;
  222. rect.draw(skin->background_color);
  223. Window window; window.create(Rect_C(0, 0, rect.w()*0.75f, rect.h()*0.5f), "Window");
  224. Text text ; text .create(window.clientRect().lerp(0.5f, 0.65f), "Hello!");
  225. Button button; button.create(Rect_C(window.clientRect().lerp(0.5f, 0.35f), 0.3f, 0.06f), "OK");
  226. GuiPC gpc;
  227. gpc.clip=gpc.client_rect=rect;
  228. gpc.visible=gpc.enabled=true;
  229. gpc.offset=rect.center();
  230. window.draw(gpc);
  231. text .draw(gpc);
  232. button.draw(gpc);
  233. rect.draw(rect_color, false);
  234. Gui.skin=temp;
  235. }
  236. }break;
  237. case ELM_GUI:
  238. {
  239. GuiSkinPtr temp=Gui.skin; if(GuiSkinPtr skin=Proj.appGuiSkin())Gui.skin=skin;
  240. if(objs_last_id!=elm.id)
  241. {
  242. objs_last_id=elm.id;
  243. objs.load(Proj.gamePath(elm.id));
  244. objs_container+=objs;
  245. }
  246. rect.draw(BackgroundColor());
  247. GuiPC gpc; gpc.visible=gpc.enabled=true; gpc.offset=(Vec2(0, 0)&rect); gpc.clip=gpc.client_rect=rect; // try to set the 'offset' as close to screen center as possible (so the preview will give similar results to what's actually available)
  248. FREP(objs_container.childNum())objs_container.child(i)->draw(gpc); // draw children manually and in order as they're listed in the parent
  249. Gui.skin=temp;
  250. }break;
  251. case ELM_IMAGE:
  252. {
  253. drawBack(rect);
  254. if(image=Proj.gamePath(elm.id))
  255. {
  256. if(image->mode()==IMAGE_2D )image->drawFit(rect);else
  257. if(image->mode()==IMAGE_CUBE)
  258. {
  259. D.viewRect(rect).viewFov(DefaultFOV); SetCam(cam, Box(0), Time.appTime()/2);
  260. Sky.skybox(image);
  261. Renderer(PreviewClass::Render);
  262. Sky.atmospheric();
  263. D.viewRect(r).viewFov(fov); c.set();
  264. }else
  265. if(image->mode()==IMAGE_3D)
  266. {
  267. D.viewRect(rect).viewFov(PreviewFOV); SetCam(cam, Box(1), Time.appTime()/2);
  268. Renderer(PreviewClass::Render);
  269. D.viewRect(r).viewFov(fov); c.set();
  270. }else D.text(TextStyleParams(true), rect, "Image is software based\nand can't be previewed");
  271. }
  272. }break;
  273. case ELM_IMAGE_ATLAS:
  274. {
  275. drawBack(rect);
  276. if(atlas=Proj.gamePath(elm.id))if(int parts=atlas->parts.elms())
  277. {
  278. int p=(Time.curTimeMs()/400)%parts;
  279. ImageAtlas::Part &part=atlas->parts[p];
  280. if(InRange(part.image_index, atlas->images))
  281. {
  282. Image &image=atlas->images[part.image_index];
  283. Vec2 rect_size=rect.size(), tex_size=part.original_size;
  284. tex_size*=rect_size.x/tex_size.x; // scale to fit X
  285. if(tex_size.y>rect_size.y)tex_size*=rect_size.y/tex_size.y; // scale to fit Y
  286. Vec2 scale=tex_size/part.original_size*0.9f;
  287. D.clip(Rect(rect).extend(-D.pixelToScreenSize()));
  288. Rect_LU draw_rect(rect.center()+part.center_offset*scale, part.trimmed_size*scale);
  289. // draw image
  290. if(part.rotated)image.drawPartVertical(draw_rect, part.tex_rect);
  291. else image.drawPart (draw_rect, part.tex_rect);
  292. Rect_C(rect.center(), part.original_size*scale).draw(GREY, false); // original rect
  293. draw_rect.draw(RED, false); // trimmed rect
  294. flt l=0.03f;
  295. D.lineY(GREEN, rect.centerX(), rect.centerY()-l, rect.centerY()+l); // center
  296. D.lineX(GREEN, rect.centerY(), rect.centerX()-l, rect.centerX()+l);
  297. D.clip();
  298. }
  299. }
  300. }break;
  301. case ELM_ICON:
  302. {
  303. drawBack(rect); if(image=Proj.gamePath(elm.id))image->drawFit(rect);
  304. }break;
  305. case ELM_SOUND:
  306. {
  307. if(sound_id!=elm.id)
  308. {
  309. sound_id=elm.id;
  310. SoundHeader sound; sound.load(Proj.gamePath(elm));
  311. sound_info=S+"Length: "+TextReal(sound.length, -2)+"s\nChannels: "+sound.channels+"\nFrequency: "+sound.frequency+"\nKbps: "+DivRound(sound.bit_rate, 1000)+"\nSize: "+FileSize(FSize(Proj.gamePath(elm)))+"\nCodec: "+sound.codecName();
  312. }
  313. drawBack(rect); D.clip(rect); D.text(TextStyleParams(true), rect, sound_info); D.clip();
  314. }break;
  315. case ELM_VIDEO:
  316. {
  317. if(video_id!=elm.id){video_id=elm.id; video.create(Proj.gamePath(elm), true); video_time=0;} // start from the beginning to avoid freezes
  318. video.update(video_time); video_time+=Time.ad(); // Editor works in background so app time gets updated even when minimized, update time only when actually drawing
  319. rect.draw(BLACK); video.drawFit(rect);
  320. rect.draw(rect_color, false);
  321. }break;
  322. case ELM_ENV:
  323. {
  324. env=Proj.gamePath(elm.id); env->set();
  325. D.viewRect(rect).viewFov(PreviewFOV).viewFrom(0.01f).viewRange(300); SetCam(cam, Box(0), Time.appTime()/2); // set
  326. Renderer(PreviewClass::Render);
  327. D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
  328. rect.draw(rect_color, false);
  329. }break;
  330. case ELM_MINI_MAP:
  331. {
  332. if(mini_map_id!=elm.id)
  333. {
  334. mini_map_id=elm.id;
  335. mini_map.load(Proj.gamePath(elm));
  336. }
  337. drawBack(rect);
  338. D.clip(Rect(rect).extend(-D.pixelToScreenSize()));
  339. for(int y=-4; y<4; y++)
  340. for(int x=-4; x<4; x++)
  341. {
  342. Image &img=mini_map(VecI2(x, y));
  343. if(img.is())img.draw(Rect_LD(x, y, 1, 1)*0.19f+rect.center());
  344. }
  345. D.clip();
  346. }break;
  347. }
  348. D. dofMode(dof );
  349. D. ambientMode(ambient );
  350. D.eyeAdaptation(eye_adapt);
  351. AstrosDraw =astros;
  352. Water.draw =ocean;
  353. if(elm.importing()){TextStyleParams ts; ts.size*=0.6f; ts.align.set(0, 1); D.text(ts, rect.down(), (ImportRemovedElms || elm.finalExists()) ? "Processing" : "Not Processed");}
  354. }
  355. void PreviewClass::clipRect(Rect &rect)
  356. {
  357. flt t=D.h(); if(Mode.visibleTabs())MIN(t, Mode.rect().min.y);
  358. if(rect.max.y> t )rect+=Vec2(0, t -rect.max.y);
  359. if(rect.min.y<-D.h())rect+=Vec2(0, -D.h()-rect.min.y);
  360. }
  361. void PreviewClass::drawAround(Elm &elm, C Rect &rect, flt y)
  362. {
  363. D.clip();
  364. Vec2 size(D.w(), D.h()); size*=0.5f; size=size.avg();
  365. Rect r;
  366. if(rect.min.x-(-D.w())>D.w()-rect.max.x)r=Rect_R(rect.min.x-0.02f, y, size.x, size.y);
  367. else r=Rect_L(rect.max.x+0.02f, y, size.x, size.y);
  368. clipRect(r);
  369. draw(elm, r);
  370. }
  371. GuiObj* PreviewClass::test(C GuiPC &gpc, C Vec2 &pos, GuiObj* &mouse_wheel){return null;}
  372. void PreviewClass::update(C GuiPC &gpc){}
  373. void PreviewClass::draw(C GuiPC &gpc)
  374. {
  375. if(ListElm *list_elm=Proj.list.visToData(Proj.list.lit))
  376. {
  377. CodeEdit.drawPreview(list_elm);
  378. if(Elm *elm=list_elm->elm)
  379. {
  380. D.clip();
  381. Vec2 size(D.w(), D.h()); size*=0.75f; size=size.avg(); if(elm->type==ELM_SOUND)size.set(0.38f, 0.31f);
  382. Rect_L rect(Proj.rect().max.x, Ms.pos().y, size.x, size.y); clipRect(rect);
  383. if(elm->type==ELM_GUI)rect=EditRect();
  384. draw(*elm, rect);
  385. }
  386. }
  387. if(MergeSimilarMaterials::Data *list_elm=MSM.list.visToData(MSM.list.lit))
  388. if(Elm *elm=Proj.findElm(list_elm->id))
  389. {
  390. D.clip();
  391. Vec2 size(D.w(), D.h()); size*=0.75f; size=size.avg();
  392. Rect rect=MSM.region.screenRect();
  393. if(rect.min.x-(-D.w())>D.w()-rect.max.x)rect=Rect_R(rect.min.x-0.02f, Ms.pos().y, size.x, size.y);
  394. else rect=Rect_L(rect.max.x+0.02f, Ms.pos().y, size.x, size.y);
  395. clipRect(rect);
  396. draw(*elm, rect);
  397. }
  398. if(EraseRemovedElms::Elm *list_elm=EraseRemoved.list.visToData(EraseRemoved.list.lit))
  399. if(Elm *elm=Proj.findElm(list_elm->id))
  400. {
  401. D.clip();
  402. Vec2 size(D.w(), D.h()); size*=0.75f; size=size.avg();
  403. Rect rect=EraseRemoved.region.screenRect();
  404. if(rect.min.x-(-D.w())>D.w()-rect.max.x)rect=Rect_R(rect.min.x-0.02f, Ms.pos().y, size.x, size.y);
  405. else rect=Rect_L(rect.max.x+0.02f, Ms.pos().y, size.x, size.y);
  406. clipRect(rect);
  407. draw(*elm, rect);
  408. }
  409. if(MaterialRegion::Texture *tex=CAST(MaterialRegion::Texture, Gui.ms()))
  410. {
  411. D.clip();
  412. Vec2 size(D.w(), D.h()); size=size.avg(); if(tex->type==MaterialRegion::TEX_RFL_ALL)size.x*=4.0f/3;
  413. flt x=D.w();
  414. if( MtrlEdit.visible())MIN(x, MtrlEdit.rect().min.x);
  415. if(WaterMtrlEdit.visible())MIN(x, WaterMtrlEdit.rect().min.x);
  416. Rect_R rect(x, Ms.pos().y, size.x, size.y); clipRect(rect);
  417. tex->draw(rect);
  418. }
  419. if(ObjPaintClass::Object *obj=ObjPaint.objects_list.visToData(ObjPaint.objects_list.lit))
  420. if(Elm *elm=Proj.findElm(obj->id))
  421. {
  422. D.clip();
  423. Vec2 size(D.w(), D.h()); size*=0.5f; size=size.avg();
  424. Rect_R rect(ObjPaint.rect().min.x, Ms.pos().y, size.x, size.y); clipRect(rect);
  425. draw(*elm, rect);
  426. }
  427. // Object Parameter
  428. {
  429. ParamEditor::ParamWindow::Param *param=null;
  430. if(!param)param= ObjClassEdit .findParam(Gui.ms());
  431. if(!param)param= ObjEdit.param_edit.findParam(Gui.ms());
  432. if(!param)param=WorldEdit.param_edit.findParam(Gui.ms());
  433. if( param)
  434. {
  435. if(param->src.type==PARAM_ID && (Gui.ms()==&param->val_textline || Gui.ms()==&param->name))if(Elm *elm=Proj.findElm(param->src.asID()))drawAround(*elm, param->name.screenRect()|param->val_textline.screenRect());
  436. return;
  437. }
  438. }
  439. // textline
  440. if(Gui.ms() && Gui.ms()->type()==GO_TEXTLINE)if(Elm *elm=Proj.findElm(Gui.ms()->asTextLine()()))
  441. {
  442. drawAround(*elm, Gui.ms()->screenRect());
  443. return;
  444. }
  445. }
  446. PreviewClass::PreviewClass() : skel(null), anim(null), sound_id(UIDZero), video_id(UIDZero), mini_map_id(UIDZero), mesh_variation(0), video_time(0), objs_last_id(UIDZero) {}
  447. /******************************************************************************/