| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- /******************************************************************************/
- #include "stdafx.h"
- /******************************************************************************/
- flt GetDist(C Box &box)
- {
- Box b=box-box.center(); // center
- b|=b*Matrix3().setRotateY(PI_4); // include the box when it's rotated at 45 deg
- Vec size=b.size();
- flt dist= size.y/(2*Tan(D.viewFovY()/2));
- MAX(dist, size.x/(2*Tan(D.viewFovX()/2)));
- MAX(dist, size.z/(2*Tan(D.viewFovX()/2)));
- return dist;
- }
- void SetCam(Camera &cam, C Box &box, flt yaw, flt pitch, flt zoom) // require custom 'cam' to calculate correct velocities
- {
- cam.yaw=yaw;
- cam.pitch=pitch;
- cam.roll=0;
- cam.dist=GetDist(box)*zoom;
- cam.at=box.center();
- cam.setSpherical().updateVelocities(CAM_ATTACH_FREE).set();
- }
- /******************************************************************************/
- PreviewClass Preview;
- /******************************************************************************/
- /******************************************************************************/
- void PreviewClass::create()
- {
- Gui+=::EE::Window::create().level(1); // set level so it will be displayed above other editor windows
- ball.create(1).parts[0].base.create(Ball(1), VTX_TEX0|VTX_NRM_TAN_BIN, 16);
- ball.setRender().setBox();
- objs_container.create(S);
- }
- void PreviewClass::Render() {Preview.render();}
- void PreviewClass::render()
- {
- switch(Renderer())
- {
- case RM_PREPARE:
- {
- switch(elm_type)
- {
- case ELM_OBJ :
- case ELM_MESH: if(mesh)
- {
- SetVariation(mesh_variation); mesh->MeshLod::draw(MatrixIdentity);
- SetVariation();
- }break;
- case ELM_MTRL: ball.draw(MatrixIdentity); break;
- case ELM_ANIM: if(mesh)mesh->MeshLod::draw(anim_skel); break;
- }
- if(elm_type==ELM_WATER_MTRL)LightDir(Matrix3().setRotateXY(PI_4, PI_4).z , 1-D.ambientColor()).add(false);
- else LightDir(!(ActiveCam.matrix.z*2 + ActiveCam.matrix.x - ActiveCam.matrix.y), 1-D.ambientColor()).add(false);
- }break;
- case RM_BLEND:
- case RM_PALETTE:
- case RM_PALETTE1:
- {
- // particle
- }break;
- }
- if(Renderer()==RM_BLEND && elm_type==ELM_OBJ && body)body->drawBlend(MatrixIdentity, VecZero, VecZero, &Vec4(1, 1, 1, 0.32f));
- if(Renderer()==RM_CLOUD && elm_type==ELM_IMAGE && image && image->mode()==IMAGE_3D)
- {
- image->drawVolume(WHITE, TRANSPARENT, OBox(Box(1)), 0.05f);
- }
- }
- void PreviewClass::closeElm(C UID &elm_id)
- {
- if(video_id==elm_id){video.del(); video_id.zero();}
- }
- void PreviewClass::elmChanged(C UID &elm_id)
- {
- if(elm_id==objs_last_id)objs_last_id.zero();
- if(elm_id== sound_id) sound_id.zero();
- if(elm_id== video_id) video_id.zero();
- if(elm_id== mini_map_id) mini_map_id.zero();
- }
- void PreviewClass::clearProj()
- {
- sound_id.zero();
- video_id.zero(); video.del();
- mini_map_id.zero();
- objs_last_id.zero();
- }
- void PreviewClass::drawBack(C Rect &rect)
- {
- if(GuiSkin *skin=Gui.skin())
- {
- if(skin->region.normal ){skin->region.normal->draw(skin->region.normal_color, rect); return;}
- if(skin->region.normal_color.a){ rect.draw(skin->region.normal_color ); return;}
- }
- rect.draw(Gui.backgroundColor(), true );
- rect.draw(Gui. borderColor(), false);
- }
- void PreviewClass::draw(Elm &elm, C Rect &rect)
- {
- CurrentEnvironment().set();
- AMBIENT_MODE ambient =D. ambientMode(); D. ambientMode(AMBIENT_FLAT);
- DOF_MODE dof =D. dofMode(); D. dofMode( DOF_NONE);
- bool eye_adapt=D.eyeAdaptation(); D.eyeAdaptation( false);
- bool astros =AstrosDraw ; AstrosDraw =false;
- bool ocean =Water.draw ; Water.draw =false;
- Camera c=ActiveCam; Rect r=D.viewRect(); flt fov=D.viewFov(), from=D.viewFrom(), range=D.viewRange(); // remember
- Color rect_color=Gui.borderColor();
- mesh_variation=0;
- switch(elm_type=elm.type)
- {
- case ELM_OBJ:
- {
- if(ElmObj *obj_data=elm.objData())
- if(obj=Proj.gamePath(elm.id))
- {
- 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;
- 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
- mesh_variation=obj->meshVariationIndex();
- body=Proj.gamePath(body_id);
- D.viewRect(rect).viewFov(PreviewFOV);
- flt dist=Max(0.1f, mesh ? GetDist(mesh->ext) : 0);
- 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
- Renderer(PreviewClass::Render);
- D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
- rect.draw(rect_color, false);
- }
- }break;
- case ELM_MESH:
- {
- mesh=Proj.gamePath(elm.id);
- D.viewRect(rect).viewFov(PreviewFOV);
- flt dist=Max(0.1f, mesh ? GetDist(mesh->ext) : 0);
- 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
- Renderer(PreviewClass::Render);
- D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
- rect.draw(rect_color, false);
- }break;
- case ELM_MTRL:
- {
- mtrl=Proj.gamePath(elm.id);
- ball.material(mtrl).setShader();
- D.viewRect(rect).viewFov(PreviewFOV);
- flt dist=GetDist(ball.ext);
- D.viewFrom(dist*0.01f).viewRange(dist*3); SetCam(cam, ball.ext, Time.appTime()/2); // set
- Renderer(PreviewClass::Render);
- D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
- rect.draw(rect_color, false);
- }break;
- case ELM_WATER_MTRL:
- {
- 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));
- if(water_mtrl=Proj.gamePath(elm.id))SCAST(WaterMtrl, Water)=*water_mtrl;
- D.viewRect(rect).viewFov(PreviewFOV).viewFrom(0.1f).viewRange(100); SetCam(cam, Box(5), 0, -PI_6); // set
- Renderer(PreviewClass::Render);
- D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
- Swap(temp, SCAST(WaterMtrl, Water)); Water.plane=water_plane;
- rect.draw(rect_color, false);
- }break;
- case ELM_ANIM:
- {
- UID mesh_id=Proj.animToMesh(&elm); // get mesh from anim->skel->mesh
- 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
- if( mesh_id.valid())
- {
- anim=Animations(Proj.gamePath(elm .id));
- mesh= Proj.gamePath(mesh_id) ;
- skel=mesh->skeleton();
- if(skel)
- {
- if(anim_skel.skeleton()!=skel || anim_skel.bones.elms()!=skel->bones.elms() || anim_skel.slots.elms()!=skel->slots.elms())anim_skel.create(skel);
- skel_anim.create(*skel, *anim);
- flt time=(anim->length() ? Frac(Time.appTime(), (dbl)anim->length()) : 0);
- anim_skel.clear().animate(skel_anim, time).animateRoot(*anim, time).updateMatrix().updateVelocities(false, false);
- }else
- {
- anim_skel.del().updateMatrix().updateVelocities();
- }
- D.viewRect(rect).viewFov(PreviewFOV);
- flt dist=Max(0.1f, mesh ? GetDist(mesh->ext) : 0);
- D.viewFrom(dist*0.01f).viewRange(dist*5); if(mesh)SetCam(cam, mesh->ext, Time.appTime()); // set
- Renderer(PreviewClass::Render);
- D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
- rect.draw(rect_color, false);
- }
- }break;
- case ELM_FONT:
- {
- TextStyle ts; ts.size=rect.h()/16; ts.font(Proj.gamePath(elm.id)); if(Font *font=ts.font()())
- {
- if(font->images().elms() && font->images()[0].mode()==IMAGE_SOFT)
- {
- drawBack(rect);
- D.text(TextStyleParams(true), rect, "Font is software based\nand can't be previewed");
- }else
- {
- Rect u=rect, d=rect; u.min.y=d.max.y=rect.centerY();
- cchar8 *t="ABCDEFGHIJKLMN\nOPQRSTUVWXYZ\nabcdefghijklmn\nopqrstuvwxyz\n0123456789\n!@#$%^&*+-=_()[]{}<>,.:;'\"\\|/?";
- u.draw(BLACK); ts.color=WHITE; ts.shadow=255; D.clip(u); D.text(ts, u, t); D.clip();
- d.draw(WHITE); ts.color=BLACK; ts.shadow= 0; D.clip(d); D.text(ts, d, t); D.clip();
- rect.draw(rect_color, false);
- }
- }
- }break;
- case ELM_TEXT_STYLE: if(TextStylePtr ts=Proj.gamePath(elm.id))
- {
- cchar8 *t="ABCDEFGHIJKLMN\nOPQRSTUVWXYZ\nabcdefghijklmn\nopqrstuvwxyz\n0123456789\n!@#$%^&*+-=_()[]{}<>,.:;'\"\\|/?";
- Color c=ColorInverse(ts->color); c.a=255;
- rect.draw(c); D.clip(rect); D.text(*ts, rect, t); D.clip();
- rect.draw(rect_color, false);
- }break;
- case ELM_PANEL_IMAGE:
- {
- drawBack(rect); if(PanelImagePtr panel=Proj.gamePath(elm.id))DrawPanelImage(*panel, rect);
- }break;
- case ELM_PANEL:
- {
- drawBack(rect); if(PanelPtr panel=Proj.gamePath(elm.id))panel->draw(Rect_C(rect.center(), rect.size()*0.5f));
- }break;
- case ELM_GUI_SKIN:
- {
- if(GuiSkinPtr skin=Proj.gamePath(elm.id))
- {
- GuiSkinPtr temp=Gui.skin; Gui.skin=skin;
- rect.draw(skin->background_color);
- Window window; window.create(Rect_C(0, 0, rect.w()*0.75f, rect.h()*0.5f), "Window");
- Text text ; text .create(window.clientRect().lerp(0.5f, 0.65f), "Hello!");
- Button button; button.create(Rect_C(window.clientRect().lerp(0.5f, 0.35f), 0.3f, 0.06f), "OK");
- GuiPC gpc;
- gpc.clip=gpc.client_rect=rect;
- gpc.visible=gpc.enabled=true;
- gpc.offset=rect.center();
- window.draw(gpc);
- text .draw(gpc);
- button.draw(gpc);
- rect.draw(rect_color, false);
- Gui.skin=temp;
- }
- }break;
- case ELM_GUI:
- {
- GuiSkinPtr temp=Gui.skin; if(GuiSkinPtr skin=Proj.appGuiSkin())Gui.skin=skin;
- if(objs_last_id!=elm.id)
- {
- objs_last_id=elm.id;
- objs.load(Proj.gamePath(elm.id));
- objs_container+=objs;
- }
- rect.draw(BackgroundColor());
- 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)
- FREP(objs_container.childNum())objs_container.child(i)->draw(gpc); // draw children manually and in order as they're listed in the parent
- Gui.skin=temp;
- }break;
- case ELM_IMAGE:
- {
- drawBack(rect);
- if(image=Proj.gamePath(elm.id))
- {
- if(image->mode()==IMAGE_2D )image->drawFit(rect);else
- if(image->mode()==IMAGE_CUBE)
- {
- D.viewRect(rect).viewFov(DefaultFOV); SetCam(cam, Box(0), Time.appTime()/2);
- Sky.skybox(image);
- Renderer(PreviewClass::Render);
- Sky.atmospheric();
- D.viewRect(r).viewFov(fov); c.set();
- }else
- if(image->mode()==IMAGE_3D)
- {
- D.viewRect(rect).viewFov(PreviewFOV); SetCam(cam, Box(1), Time.appTime()/2);
- Renderer(PreviewClass::Render);
- D.viewRect(r).viewFov(fov); c.set();
- }else D.text(TextStyleParams(true), rect, "Image is software based\nand can't be previewed");
- }
- }break;
- case ELM_IMAGE_ATLAS:
- {
- drawBack(rect);
- if(atlas=Proj.gamePath(elm.id))if(int parts=atlas->parts.elms())
- {
- int p=(Time.curTimeMs()/400)%parts;
- ImageAtlas::Part &part=atlas->parts[p];
- if(InRange(part.image_index, atlas->images))
- {
- Image &image=atlas->images[part.image_index];
- Vec2 rect_size=rect.size(), tex_size=part.original_size;
- tex_size*=rect_size.x/tex_size.x; // scale to fit X
- if(tex_size.y>rect_size.y)tex_size*=rect_size.y/tex_size.y; // scale to fit Y
- Vec2 scale=tex_size/part.original_size*0.9f;
- D.clip(Rect(rect).extend(-D.pixelToScreenSize()));
- Rect_LU draw_rect(rect.center()+part.center_offset*scale, part.trimmed_size*scale);
- // draw image
- if(part.rotated)image.drawPartVertical(draw_rect, part.tex_rect);
- else image.drawPart (draw_rect, part.tex_rect);
- Rect_C(rect.center(), part.original_size*scale).draw(GREY, false); // original rect
- draw_rect.draw(RED, false); // trimmed rect
- flt l=0.03f;
- D.lineY(GREEN, rect.centerX(), rect.centerY()-l, rect.centerY()+l); // center
- D.lineX(GREEN, rect.centerY(), rect.centerX()-l, rect.centerX()+l);
- D.clip();
- }
- }
- }break;
- case ELM_ICON:
- {
- drawBack(rect); if(image=Proj.gamePath(elm.id))image->drawFit(rect);
- }break;
- case ELM_SOUND:
- {
- if(sound_id!=elm.id)
- {
- sound_id=elm.id;
- SoundHeader sound; sound.load(Proj.gamePath(elm));
- 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();
- }
- drawBack(rect); D.clip(rect); D.text(TextStyleParams(true), rect, sound_info); D.clip();
- }break;
- case ELM_VIDEO:
- {
- 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
- 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
- rect.draw(BLACK); video.drawFit(rect);
- rect.draw(rect_color, false);
- }break;
- case ELM_ENV:
- {
- env=Proj.gamePath(elm.id); env->set();
- D.viewRect(rect).viewFov(PreviewFOV).viewFrom(0.01f).viewRange(300); SetCam(cam, Box(0), Time.appTime()/2); // set
- Renderer(PreviewClass::Render);
- D.viewRect(r).viewFov(fov).viewFrom(from).viewRange(range); c.set(); // restore
- rect.draw(rect_color, false);
- }break;
- case ELM_MINI_MAP:
- {
- if(mini_map_id!=elm.id)
- {
- mini_map_id=elm.id;
- mini_map.load(Proj.gamePath(elm));
- }
- drawBack(rect);
- D.clip(Rect(rect).extend(-D.pixelToScreenSize()));
- for(int y=-4; y<4; y++)
- for(int x=-4; x<4; x++)
- {
- Image &img=mini_map(VecI2(x, y));
- if(img.is())img.draw(Rect_LD(x, y, 1, 1)*0.19f+rect.center());
- }
- D.clip();
- }break;
- }
- D. dofMode(dof );
- D. ambientMode(ambient );
- D.eyeAdaptation(eye_adapt);
- AstrosDraw =astros;
- Water.draw =ocean;
- 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");}
- }
- void PreviewClass::clipRect(Rect &rect)
- {
- flt t=D.h(); if(Mode.visibleTabs())MIN(t, Mode.rect().min.y);
- if(rect.max.y> t )rect+=Vec2(0, t -rect.max.y);
- if(rect.min.y<-D.h())rect+=Vec2(0, -D.h()-rect.min.y);
- }
- void PreviewClass::drawAround(Elm &elm, C Rect &rect, flt y)
- {
- D.clip();
- Vec2 size(D.w(), D.h()); size*=0.5f; size=size.avg();
- Rect r;
- if(rect.min.x-(-D.w())>D.w()-rect.max.x)r=Rect_R(rect.min.x-0.02f, y, size.x, size.y);
- else r=Rect_L(rect.max.x+0.02f, y, size.x, size.y);
- clipRect(r);
- draw(elm, r);
- }
- GuiObj* PreviewClass::test(C GuiPC &gpc, C Vec2 &pos, GuiObj* &mouse_wheel){return null;}
- void PreviewClass::update(C GuiPC &gpc){}
- void PreviewClass::draw(C GuiPC &gpc)
- {
- if(ListElm *list_elm=Proj.list.visToData(Proj.list.lit))
- {
- CodeEdit.drawPreview(list_elm);
- if(Elm *elm=list_elm->elm)
- {
- D.clip();
- Vec2 size(D.w(), D.h()); size*=0.75f; size=size.avg(); if(elm->type==ELM_SOUND)size.set(0.38f, 0.31f);
- Rect_L rect(Proj.rect().max.x, Ms.pos().y, size.x, size.y); clipRect(rect);
- if(elm->type==ELM_GUI)rect=EditRect();
- draw(*elm, rect);
- }
- }
- if(MergeSimilarMaterials::Data *list_elm=MSM.list.visToData(MSM.list.lit))
- if(Elm *elm=Proj.findElm(list_elm->id))
- {
- D.clip();
- Vec2 size(D.w(), D.h()); size*=0.75f; size=size.avg();
- Rect rect=MSM.region.screenRect();
- 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);
- else rect=Rect_L(rect.max.x+0.02f, Ms.pos().y, size.x, size.y);
- clipRect(rect);
- draw(*elm, rect);
- }
- if(EraseRemovedElms::Elm *list_elm=EraseRemoved.list.visToData(EraseRemoved.list.lit))
- if(Elm *elm=Proj.findElm(list_elm->id))
- {
- D.clip();
- Vec2 size(D.w(), D.h()); size*=0.75f; size=size.avg();
- Rect rect=EraseRemoved.region.screenRect();
- 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);
- else rect=Rect_L(rect.max.x+0.02f, Ms.pos().y, size.x, size.y);
- clipRect(rect);
- draw(*elm, rect);
- }
- if(MaterialRegion::Texture *tex=CAST(MaterialRegion::Texture, Gui.ms()))
- {
- D.clip();
- Vec2 size(D.w(), D.h()); size=size.avg(); if(tex->type==MaterialRegion::TEX_RFL_ALL)size.x*=4.0f/3;
- flt x=D.w();
- if( MtrlEdit.visible())MIN(x, MtrlEdit.rect().min.x);
- if(WaterMtrlEdit.visible())MIN(x, WaterMtrlEdit.rect().min.x);
- Rect_R rect(x, Ms.pos().y, size.x, size.y); clipRect(rect);
- tex->draw(rect);
- }
- if(ObjPaintClass::Object *obj=ObjPaint.objects_list.visToData(ObjPaint.objects_list.lit))
- if(Elm *elm=Proj.findElm(obj->id))
- {
- D.clip();
- Vec2 size(D.w(), D.h()); size*=0.5f; size=size.avg();
- Rect_R rect(ObjPaint.rect().min.x, Ms.pos().y, size.x, size.y); clipRect(rect);
- draw(*elm, rect);
- }
- // Object Parameter
- {
- ParamEditor::ParamWindow::Param *param=null;
- if(!param)param= ObjClassEdit .findParam(Gui.ms());
- if(!param)param= ObjEdit.param_edit.findParam(Gui.ms());
- if(!param)param=WorldEdit.param_edit.findParam(Gui.ms());
- if( param)
- {
- if(param->src.type==PARAM_ID && (Gui.ms()==¶m->val_textline || Gui.ms()==¶m->name))if(Elm *elm=Proj.findElm(param->src.asID()))drawAround(*elm, param->name.screenRect()|param->val_textline.screenRect());
- return;
- }
- }
- // textline
- if(Gui.ms() && Gui.ms()->type()==GO_TEXTLINE)if(Elm *elm=Proj.findElm(Gui.ms()->asTextLine()()))
- {
- drawAround(*elm, Gui.ms()->screenRect());
- return;
- }
- }
- 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) {}
- /******************************************************************************/
|