Add basic workplane control.

Only Y-axis right now. In the future, maybe a tool for creating one workplane for each axis?
This commit is contained in:
David Vierra 2015-06-03 23:15:46 -10:00
parent 4a54d0f5a4
commit 817d42b522
3 changed files with 123 additions and 5 deletions

View File

@ -35,7 +35,7 @@ class VertexArrayBuffer(object):
bl: float32 (with lights=True)
sl: float32 (with lights=True)
rgba:
rgba: uint32 (four uint8s packed with r in the most significant byte)
rgba: uint8 (four uint8s packed with r in the most significant byte)
Access elements using .vertex, .texcoord, .lightcoord, .rgba

View File

@ -0,0 +1,57 @@
"""
workplane
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import logging
from OpenGL import GL
from mcedit2.rendering import scenegraph, rendergraph
from mcedit2.rendering.vertexarraybuffer import VertexArrayBuffer
log = logging.getLogger(__name__)
class WorkplaneNode(scenegraph.Node):
def __init__(self):
super(WorkplaneNode, self).__init__()
self.translateNode = scenegraph.TranslateNode()
self.addChild(self.translateNode)
gridSize = 64
left = -gridSize//2
right = gridSize//2
gridArrayBuffer = VertexArrayBuffer((gridSize * 4,),
GL.GL_LINES, textures=False, lights=False)
gridArrayBuffer.rgba[:] = 255, 255, 255, 100
# y=0, move by translating
gridArrayBuffer.vertex[:, 1] = 0
# left edge
gridArrayBuffer.vertex[0:gridSize*2:2, 2] = left
gridArrayBuffer.vertex[0:gridSize*2:2, 0] = range(left, right)
# right edge
gridArrayBuffer.vertex[1:gridSize*2:2, 2] = right-1
gridArrayBuffer.vertex[1:gridSize*2:2, 0] = range(left, right)
# bottom edge
gridArrayBuffer.vertex[gridSize*2::2, 0] = left
gridArrayBuffer.vertex[gridSize*2::2, 2] = range(left, right)
# top edge
gridArrayBuffer.vertex[gridSize*2+1::2, 0] = right-1
gridArrayBuffer.vertex[gridSize*2+1::2, 2] = range(left, right)
self.vertexNode = scenegraph.VertexNode([gridArrayBuffer])
self.translateNode.addChild(self.vertexNode)
@property
def position(self):
return self.translateNode.translateOffset
@position.setter
def position(self, value):
self.translateNode.translateOffset = value

View File

@ -10,10 +10,14 @@ from math import degrees, atan, tan, radians, cos, sin
import numpy
from PySide.QtCore import Qt
from PySide import QtGui, QtCore
from mcedit2.rendering.workplane import WorkplaneNode
from mcedit2.util import profiler
from mcedit2.util.settings import Settings
from mcedit2.widgets.layout import Column, Row
from mcedit2.widgets.spinslider import SpinSlider
from mceditlib import faces
from mceditlib.geometry import Vector
from mceditlib.util.lazyprop import lazyprop
from mcedit2.worldview.viewcontrols import ViewControls
from mcedit2.worldview.worldview import WorldView, iterateChunks
@ -42,17 +46,29 @@ class CameraWorldViewFrame(QtGui.QWidget):
PerspectiveSetting.connectAndCall(view.setPerspective)
perspectiveInput = QtGui.QCheckBox("Perspective")
perspectiveInput = QtGui.QCheckBox(self.tr("Perspective"))
perspectiveInput.setChecked(view.perspective)
perspectiveInput.toggled.connect(PerspectiveSetting.setValue)
showButton = QtGui.QPushButton("Show...")
showButton = QtGui.QPushButton(self.tr("Show..."))
showButton.setMenu(view.layerToggleGroup.menu)
workplaneCheckbox = QtGui.QCheckBox(self.tr("Work Plane"))
workplaneSpinSlider = SpinSlider()
workplaneSpinSlider.setValue(64)
workplaneSpinSlider.setMinimum(dimension.bounds.miny)
workplaneSpinSlider.setMaximum(dimension.bounds.maxy)
workplaneCheckbox.toggled.connect(view.toggleWorkplane)
workplaneSpinSlider.valueChanged.connect(view.setWorkplaneLevel)
self.setLayout(Column(Row(None,
workplaneCheckbox,
workplaneSpinSlider,
showButton,
perspectiveInput,
QtGui.QLabel("View Distance:"),
QtGui.QLabel(self.tr("View Distance:")),
viewDistanceInput,
self.viewControls.getShowHideButton(), margin=0),
view, margin=0))
@ -198,6 +214,9 @@ class CameraWorldView(WorldView):
self._yawPitch = -45., 25.
self.viewDistance = 32
self.workplaneNode = WorkplaneNode()
self.workplaneNode.visible = False
WorldView.__init__(self, *a, **kw)
self.compassNode.yawPitch = self._yawPitch
self.viewActions = [CameraMoveMouseAction(),
@ -211,6 +230,48 @@ class CameraWorldView(WorldView):
self.discardTimer.setInterval(1000)
self.discardTimer.start()
self.workplaneLevel = 0
self.workplaneEnabled = False
self.viewportMoved.connect(self.updateWorkplane)
def updateWorkplane(self):
distance = 40
pos = self.centerPoint + self.cameraVector * distance
pos = pos.intfloor()
self.workplaneNode.position = Vector(pos[0], self.workplaneLevel, pos[2])
def toggleWorkplane(self, enabled):
self.workplaneNode.visible = enabled
self.workplaneEnabled = enabled
def setWorkplaneLevel(self, level):
self.workplaneLevel = level
self.updateWorkplane()
self.update()
def createSceneGraph(self):
scenegraph = super(CameraWorldView, self).createSceneGraph()
self.matrixNode.addChild(self.workplaneNode)
return scenegraph
def augmentEvent(self, x, y, event):
super(CameraWorldView, self).augmentEvent(x, y, event)
if not self.workplaneEnabled:
return
point = event.ray.atHeight(self.workplaneLevel)
if point != event.ray.point:
direction = point - event.ray.point
if direction.length() >= (event.blockPosition - event.ray.point).length():
return
event.blockPosition = point.intfloor()
if direction.y >= 0:
event.blockFace = faces.FaceDown
else:
event.blockFace = faces.FaceUp
def setViewDistance(self, val):
self.viewDistance = val
self._chunkIter = None