载入中...
搜索中...
未找到
PcgFreeCamera.cpp
浏览该文件的文档.
9Result<void> PcgFreeCamera::configure(bool e,bool l,bool h,float look,float move,float sprint,bool scroll,float inc,float roll){if(!finite(look)||!finite(move)||!finite(sprint)||!finite(inc)||!finite(roll)||look<0||move<0||sprint<move||inc<0)return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"invalid free-camera configuration","camera.pcgFree.configure"));enabled_=e;lockCursor_=l;holdRight_=h;lookSpeed_=look;moveSpeed_=move;sprintSpeed_=sprint;scrollIncrease_=scroll;increase_=inc;roll_=roll;if(!e)captured_=false;return Result<void>::success();}
10Result<void> PcgFreeCamera::capture(graphics::Camera3D*c){if(!c)return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"camera is required","camera.pcgFree.capture"));float dx=c->getTargetX()-c->getEyeX(),dy=c->getTargetY()-c->getEyeY(),dz=c->getTargetZ()-c->getEyeZ();float len=std::sqrt(dx*dx+dy*dy+dz*dz);if(len<=1e-6f)return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"camera direction is degenerate","camera.pcgFree.capture"));yaw_=std::atan2(dx,dz)*180/glm::pi<float>();pitch_=std::asin(dy/len)*180/glm::pi<float>();captured_=enabled_;return Result<void>::success();}
11Result<void> PcgFreeCamera::setRoll(float r){if(!finite(r))return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"roll must be finite","camera.pcgFree.roll"));roll_=r;return Result<void>::success();}
12Result<void> PcgFreeCamera::update(graphics::Camera3D*c,const PcgFreeCameraInput&i,float dt){if(!c)return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"camera is required","camera.pcgFree.update"));if(!finite(dt)||dt<0||!finite(i.mouseX)||!finite(i.mouseY)||!finite(i.scroll)||!finite(i.forward)||!finite(i.right)||!finite(i.up))return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"free-camera input and dt must be finite","camera.pcgFree.update"));if(!enabled_)return Result<void>::success();if(captured_&&!i.focused)captured_=false;if(!captured_&&((!holdRight_&&i.leftPressed)||(holdRight_&&i.rightPressed))){auto r=capture(c);if(!r)return r;}if(!captured_)return Result<void>::success();if(scrollIncrease_){sprintSpeed_+=i.scroll/500.f*increase_;if(sprintSpeed_<moveSpeed_)sprintSpeed_=moveSpeed_;}if((!holdRight_&&i.escapePressed)||(holdRight_&&i.rightReleased)){captured_=false;return Result<void>::success();}yaw_=std::fmod(yaw_+lookSpeed_*(i.mouseX/20.f),360.f);pitch_=std::fmod(pitch_-lookSpeed_*(i.mouseY/10.f),360.f);float y=glm::radians(yaw_),p=glm::radians(pitch_),rr=glm::radians(roll_);glm::vec3 f(std::cos(p)*std::sin(y),std::sin(p),std::cos(p)*std::cos(y));glm::vec3 right=glm::normalize(glm::cross(f,glm::vec3(0,1,0)));glm::vec3 baseUp=glm::normalize(glm::cross(right,f));glm::vec3 up=baseUp*std::cos(rr)+right*std::sin(rr);right=right*std::cos(rr)-baseUp*std::sin(rr);float speed=dt*(i.sprint?sprintSpeed_:moveSpeed_);glm::vec3 eye(c->getEyeX(),c->getEyeY(),c->getEyeZ());eye+=f*(speed*i.forward)+right*(speed*i.right)+glm::vec3(0,1,0)*(speed*i.up);c->setEye(eye.x,eye.y,eye.z);c->setTarget(eye.x+f.x*100,eye.y+f.y*100,eye.z+f.z*100);c->setUp(up.x,up.y,up.z);return Result<void>::success();}
13void exposePcgFreeCameraBindings(ssq::Table&t){auto in=t.addClass("PcgFreeCameraInput",ssq::Class::Ctor<PcgFreeCameraInput()>());in.addVar("mouseX",&PcgFreeCameraInput::mouseX);in.addVar("mouseY",&PcgFreeCameraInput::mouseY);in.addVar("scroll",&PcgFreeCameraInput::scroll);in.addVar("forward",&PcgFreeCameraInput::forward);in.addVar("right",&PcgFreeCameraInput::right);in.addVar("up",&PcgFreeCameraInput::up);in.addVar("sprint",&PcgFreeCameraInput::sprint);in.addVar("rightPressed",&PcgFreeCameraInput::rightPressed);in.addVar("rightReleased",&PcgFreeCameraInput::rightReleased);in.addVar("leftPressed",&PcgFreeCameraInput::leftPressed);in.addVar("escapePressed",&PcgFreeCameraInput::escapePressed);in.addVar("focused",&PcgFreeCameraInput::focused);auto m=t.addClass("PcgFreeCamera",ssq::Class::Ctor<PcgFreeCamera()>());auto vm=t.getHandle();m.addFunc("configure",[vm](PcgFreeCamera*s,bool e,bool l,bool h,float a,float b,float c,bool d,float f,float r){return eve::script::projectResult(vm,s->configure(e,l,h,a,b,c,d,f,r));});m.addFunc("capture",[vm](PcgFreeCamera*s,graphics::Camera3D*c){return eve::script::projectResult(vm,s->capture(c));});m.addFunc("release",[](PcgFreeCamera*s){s->release();});m.addFunc("update",[vm](PcgFreeCamera*s,graphics::Camera3D*c,const PcgFreeCameraInput*i,float dt){return eve::script::projectResult(vm,i?s->update(c,*i,dt):Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"input is required","camera.pcgFree.update")));});m.addFunc("setRoll",[vm](PcgFreeCamera*s,float r){return eve::script::projectResult(vm,s->setRoll(r));});m.addFunc("getCaptured",[](const PcgFreeCamera*s){return s->getCaptured();});m.addFunc("getSprintSpeed",[](const PcgFreeCamera*s){return s->getSprintSpeed();});m.addFunc("getYaw",[](const PcgFreeCamera*s){return s->getYaw();});m.addFunc("getPitch",[](const PcgFreeCamera*s){return s->getPitch();});m.addFunc("getRoll",[](const PcgFreeCamera*s){return s->getRoll();});}
The single Squirrel projection for common Result, Status and Value.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Caller-owned six-degree free-camera state ported from Pcg FreeCamera.
Definition PcgFreeCamera.h:6
Result< void > configure(bool enabled, bool lockCursor, bool holdRight, float lookSpeed, float moveSpeed, float sprintSpeed, bool scrollIncrease, float increase, float roll)
Configure capture and movement settings atomically.
Definition PcgFreeCamera.cpp:9
Result< void > capture(graphics::Camera3D *camera)
Capture input and initialize pose from a live camera.
Definition PcgFreeCamera.cpp:10
Result< void > setRoll(float roll)
Change roll and immediately update orientation on the next frame.
Definition PcgFreeCamera.cpp:11
Result< void > update(graphics::Camera3D *camera, const PcgFreeCameraInput &input, float dt)
Process one input snapshot and update the live camera.
Definition PcgFreeCamera.cpp:12
Definition CameraController.cpp:20
void exposePcgFreeCameraBindings(ssq::Table &t)
Register Pcg free-camera bindings.
Definition PcgFreeCamera.cpp:13
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
Definition SquirrelBinding.cpp:470
@ InvalidArgument
Device-independent input snapshot for Pcg free-camera movement.
Definition PcgFreeCamera.h:4