/*OpenGL坐标轴方向: * x轴:屏幕左下角->右下角 * y轴:屏幕左下角->左上角 * z轴:向外 * 物体摆放方向:面向x轴正方向,头顶朝向y轴正方向 */ Camera::Camera() { SetEyePos(0.0f, 0.0f, 0.0f); SetTargetPos(1.0f, 0.0f, 0.0f); m_aspect = 90.0f; m_ratioWH = 1.3333333f; //大约对应于宽640,高480 m_near = 0.1f; m_far = 700.0f; }
void C3dCamera::ReInit() { SetLookAtPos(0.0f, 0.0f, 0.0f); SetEyePos(9.0f, 9.0f, 9.0f); SetFocalLength(9.0f); SetRotationAboutLookAt(-30.0f, 0.0f, -30.0f); SetUpVector(0.0f, 0.0f, 1.0f); // Z-Axis is up m_fPitch = 0.0f; m_fYaw = 0.0f; m_fRoll = 0.0f; m_fFovY = 45.0f; m_fNear = 1.0f; m_fFar = 10000.0f; m_bPerspective = TRUE; m_bBuildLists = TRUE; m_iDisplayLists = 0; m_bResetClippingPlanes = TRUE; // Clear our modelview and projection matrix memset(&m_dModelViewMatrix, 0, sizeof(GLdouble)*16); memset(&m_dProjectionMatrix, 0, sizeof(GLdouble)*16); }
void Camera::Update() { //float dt = TheTimer::Instance()->GetDt(); Vec3f pos; if (m_target) { pos = m_target->GetPos(); // yRotAuto = 0; #ifdef AUTO_ROTATE // Swing behind target float dir = m_target->GetDir() + 180.0f; float angleDiff = yRotAuto - dir; // Rotate to face m_dir, taking the shortest route (CW or CCW) if (fabs(angleDiff) < 0.1f) // TODO CONFIG { yRotAuto = dir; } else { float ROT_SPEED = 1.0f; // TODO CONFIG if (yRotAuto > dir) { yRotAuto -= ROT_SPEED * dt * fabs(angleDiff); } else if (yRotAuto < dir) { yRotAuto += ROT_SPEED * dt * fabs(angleDiff); } } #endif // AUTO_ROTATE #ifdef PORTAL_ROTATE // TODO Get closest portal static PGameObject lastportal = 0; // We want to get the closest portal to the target, even if they have never intersected it. int pid = m_target->GetIgnorePortalId(); if (pid > -1) { lastportal = TheGame::Instance()->GetGameObject(pid); } else { // Look for portals in this room, find closest. // TODO Optimise // just check periodically ? Portals portals = GetPortals(); float bestSqDist = 999999.9f; for (Portals::iterator it = portals.begin(); it != portals.end(); ++it) { Portal* p = *it; float sqDist = (p->GetPos() - pos).SqLen(); if (sqDist < bestSqDist) { bestSqDist = sqDist; lastportal = p; } } } if (lastportal) { float pdist = (pos - lastportal->GetPos()).SqLen(); // sq dist from portal to player static const float MAX_DIST = ROConfig()->GetFloat("portal-max-dist", 200.0f); static const float MAX_SQ_DIST = MAX_DIST * MAX_DIST; if (pdist < MAX_SQ_DIST) { yRotAuto = atan2(-pos.x, pos.z) * (1.0f - pdist / MAX_SQ_DIST); //std::cout << "SQ Dist from portal: " << pdist << " pos.z=" << pos.z << " pos.x=" << pos.x << " yRotAuto degs=" << RadToDeg(yRotAuto) << "\n"; } } #endif // PORTAL_ROTATE } else { pos = posNoTarget; } pos += posOffset; float y = DegToRad(yRotAuto + yRotUser); SetEyePos(Vec3f( pos.x + sin(y) * cos(xRot) * zDist, pos.y + sin(xRot) * zDist, pos.z + cos(y) * cos(xRot) * zDist)); SetLookAtPos(pos); }