Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Perspective/Orthographic Mode Toggle and FOV Adjustment #253

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions makehuman/core/mhmain.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ def onModified(event):
self.updateFilenameCaption()

#self.modelCamera = mh.Camera()
#self.modelCamera.switchToOrtho()
self.modelCamera = mh.OrbitalCamera()
self.modelCamera.switchToOrtho()
#self.modelCamera.debug = True

@self.modelCamera.mhEvent
Expand Down Expand Up @@ -731,7 +731,9 @@ def _updateBackgroundDimensions(self, width=G.windowWidth, height=G.windowHeight
height = cam.getScale()
aspect = cam.getAspect()
width = height * aspect
self.backgroundGradient.mesh.resize(2.1*width, 2.1*height)
factor = 2.1 if cam._projection == 0 else 79.1

self.backgroundGradient.mesh.resize(factor*width, factor*height)

self.backgroundGradient.setPosition([0, 0, -0.85*cam.farPlane])

Expand Down
93 changes: 68 additions & 25 deletions makehuman/lib/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
TODO
"""

from logging import setLogRecordFactory
import math
import numpy as np

Expand Down Expand Up @@ -441,12 +442,15 @@ def __init__(self):
self.radius = 1.0
self._fovAngle = 90.0

self.minRadius = 10
self.maxRadius = 20

self.fixedRadius = False
self.noAutoScale = False
self.scaleTranslations = True # Enable to make translations depend on zoom factor (only work when zoomed in)

# Ortho mode
self._projection = 0 # TODO properly test with projection mode as well
self._projection = 1 # TODO properly test with projection mode as well

self._horizontalRotation = 0.0
self._verticalInclination = 0.0
Expand Down Expand Up @@ -567,7 +571,9 @@ def updateCamera(self):
maxDistance = math.sqrt( -distances[ np.argsort(distances)[0] ] )

# Set radius as max distance from bounding box
self.radius = maxDistance + 1
self.minRadius = maxDistance
self.maxRadius = maxDistance + 10
self.radius = maxDistance + 1 if not self.projection else self.radius

if self.debug:
import log
Expand Down Expand Up @@ -654,36 +660,73 @@ def setZoomFactor(self, zoomFactor):
else:
self.zoomFactor = zoomFactor

def setRadius(self, radius):
if radius < self.minRadius:
self.radius = self.minRadius
elif radius > self.maxRadius:
self.radius = self.maxRadius
else:
self.radius = radius

def addZoom(self, amount):
self.setZoomFactor(self.zoomFactor - (amount/4.0))
if self.debug:
import log
log.debug("OrbitalCamera zoom: %s", self.zoomFactor)

if self.pickedPos is not None:
if not self.scaleTranslations and -amount < 0.0:
amount = abs(amount) / max(1.0, min(5.0, self.zoomFactor))
for i in range(3):
if self.translation[i] < 0.0:
self.translation[i] += amount
self.translation[i] = min(self.translation[i], 0.0)
elif self.translation[i] > 0.0:
self.translation[i] -= amount
self.translation[i] = max(self.translation[i], 0.0)
if not self.projection:
if self.pickedPos is not None:
if not self.scaleTranslations and -amount < 0.0:
amount = abs(amount) / max(1.0, min(5.0, self.zoomFactor))
for i in range(3):
if self.translation[i] < 0.0:
self.translation[i] += amount
self.translation[i] = min(self.translation[i], 0.0)
elif self.translation[i] > 0.0:
self.translation[i] -= amount
self.translation[i] = max(self.translation[i], 0.0)
else:
#amount = abs(amount/4.0)
#amount = abs(amount) / self.zoomFactor
amount = abs(amount) / max(1.0, min(5.0, self.zoomFactor))
#amount = abs(amount) / max(1.0, 0.3 * self.zoomFactor)
for i in range(3):
if self.translation[i] < self.pickedPos[i]:
self.translation[i] += amount
self.translation[i] = min(self.translation[i], self.pickedPos[i])
elif self.translation[i] > self.pickedPos[i]:
self.translation[i] -= amount
self.translation[i] = max(self.translation[i], self.pickedPos[i])
if self.pickedPos == self.translation:
self.pickedPos = None

else:
x, y, z = 0, 1, 2

dir = np.array([
self.pickedPos[x] - self.translation[x],
self.pickedPos[y] - self.translation[y],
self.pickedPos[z] - self.translation[z],
]) if self.pickedPos else 0.2

# rot, incl = getRotationForDirection(dir)

if isinstance(self.translation, list):
self.translation = np.array(self.translation)

if amount > 0:
pos = self._getTranslationForPosition(self.translation + dir)
else:
#amount = abs(amount/4.0)
#amount = abs(amount) / self.zoomFactor
amount = abs(amount) / max(1.0, min(5.0, self.zoomFactor))
#amount = abs(amount) / max(1.0, 0.3 * self.zoomFactor)
for i in range(3):
if self.translation[i] < self.pickedPos[i]:
self.translation[i] += amount
self.translation[i] = min(self.translation[i], self.pickedPos[i])
elif self.translation[i] > self.pickedPos[i]:
self.translation[i] -= amount
self.translation[i] = max(self.translation[i], self.pickedPos[i])
if self.pickedPos == self.translation:
self.pickedPos = None
pos = self._getTranslationForPosition(self.translation - dir)

self.setRadius(self.radius + amount)
self.setPosition(pos)

#Update
G.app.redraw()
G.app.processEvents()


self.changed()

def getMatrices(self, eye=None):
Expand Down
94 changes: 94 additions & 0 deletions makehuman/plugins/5_settings_camera.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
**Project Name:** MakeHuman

**Product Home Page:** http://www.makehumancommunity.org/

**Github Code Home Page:** https://github.com/makehumancommunity/

**Authors:** Joel Palmius, Marc Flerackers

**Copyright(c):** MakeHuman Team 2001-2020

**Licensing:** AGPL3

This file is part of MakeHuman (www.makehumancommunity.org).

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.


Abstract
--------

TODO
"""


import gui3d
import mh
import gui


class CameraActionsTaskView(gui3d.TaskView):
def __init__(self, category) -> None:
super().__init__(self, category, 'Camera')

self.cameraBox = self.addLeftWidget(gui.GroupBox('Camera'))


self.orthogonal = self.cameraBox.addWidget(
gui.CheckBox(
label = "Orthogonal/Perspective",
selected = True if gui3d.app.modelCamera.getProjection() == 0 else False
)
)

self.fovAngle = self.cameraBox.addWidget(
gui.Slider(
value = gui3d.app.modelCamera.getFovAngle(),
min = 1, max = 171,
label = ["Fov Angle",": %d"]
)
)


@self.orthogonal.mhEvent
def onClicked(event):
if self.orthogonal.selected == True:
gui3d.app.modelCamera.switchToOrtho()
else:
gui3d.app.modelCamera.switchToPerspective()


@self.fovAngle.mhEvent
def onChange(value):
gui3d.app.modelCamera.setFovAngle(value)

def onShow(self, event):
gui3d.TaskView.onShow(self, event)
# gui3d.app.statusPersist("Change camera settings")

def onHide(self, event):
# gui3d.app.statusPersist("")
gui3d.TaskView.onHide(self, event)


def load(app):
category = app.getCategory('Settings')
taskview = category.addTask(CameraActionsTaskView(category))

def unload(app):
pass