def GetDesiredPlaneNormal(self, ray): x_axis = X_AXIS y_axis = Y_AXIS z_axis = Z_AXIS if self.activeManipAxis: if self.activeManipAxis == 'x': ydot = abs(geo2.Vec3Dot(ray, y_axis)) zdot = abs(geo2.Vec3Dot(ray, z_axis)) if zdot > ydot: return z_axis if ydot > zdot: return y_axis elif self.activeManipAxis == 'y': zdot = abs(geo2.Vec3Dot(ray, z_axis)) xdot = abs(geo2.Vec3Dot(ray, x_axis)) if zdot > xdot: return z_axis if xdot > zdot: return x_axis elif self.activeManipAxis == 'z': xdot = abs(geo2.Vec3Dot(ray, x_axis)) ydot = abs(geo2.Vec3Dot(ray, y_axis)) if xdot > ydot: return x_axis if ydot > xdot: return y_axis else: viewMat = trinity.GetViewTransform() return geo2.Vector(viewMat[0][2], viewMat[1][2], viewMat[2][2]) else: return None
def _Hemisphere(self, x, y): dev = trinity.device center = geo2.Vector(self.frontPlaneTranslation[3][0], self.frontPlaneTranslation[3][1], self.frontPlaneTranslation[3][2]) view = trinity.GetViewTransform() proj = trinity.GetProjectionTransform() side = center - geo2.Vector(view[0][0], view[1][0], view[2][0]) center = geo2.Vec3TransformCoord(center, view) center = geo2.Vec3TransformCoord(center, proj) center = geo2.Vector(*center) side = geo2.Vec3TransformCoord(side, view) side = geo2.Vec3TransformCoord(side, proj) side = geo2.Vector(*side) side.x += 1.0 side.y += 1.0 center.x += 1.0 center.y += 1.0 dim = abs(dev.width * (side.x - center.x)) * 0.5 screenx = int((dev.width - 1) * 0.5 * center.x) screeny = dev.height - int((dev.height - 1) * 0.5 * center.y) px = float(x - screenx) / float(dim) py = float(screeny - y) / float(dim) d = math.sqrt(px * px + py * py) if d > 1.0: a = 1.0 / d vec = geo2.Vector(px * a, py * a, 0.0) else: vec = geo2.Vector(px, py, -(1.0 - d)) return geo2.Vec3Normalize(vec)
def PickObject(self, x, y): if self.sceneManager.GetActiveScene() != self.renderScene: return rescale = 1.0 / 10000.0 projection = trinity.TriProjection() projection.PerspectiveFov(trinity.GetFieldOfView(), trinity.GetAspectRatio(), trinity.GetFrontClip(), trinity.GetBackClip()) view = trinity.TriView() view.transform = trinity.GetViewTransform() scaling, rotation, translation = geo2.MatrixDecompose( self.transform.worldTransform) pZ = geo2.Vec3Transform((0, 0, 1), self.transform.worldTransform) surfaceNormal = geo2.Subtract(pZ, translation) cameraZ = geo2.Vector(view.transform[0][2], view.transform[1][2], view.transform[2][2]) if geo2.Vec3Dot(surfaceNormal, cameraZ) < 0: return self.renderObject.translation = geo2.Vec3Scale(translation, rescale) self.renderObject.rotation = rotation self.renderObject.scaling = geo2.Vec3Scale(scaling, rescale) scaling, rotation, translation = geo2.MatrixDecompose(view.transform) translation = geo2.Vec3Scale(translation, rescale) view.transform = geo2.MatrixTransformation(None, None, scaling, None, rotation, translation) return self.renderObject.PickObject(x, y, projection, view, trinity.device.viewport)
def render_cb(dev): global START_TIME current = time.clock() m = geo2.MatrixRotationY((current - START_TIME) * rad_per_sec) trinity.SetViewTransform( geo2.MatrixMultiply(m, trinity.GetViewTransform())) START_TIME = current
def ProjectPointTowardsFrontPlane(point, dist=7.0): ppos = point viewMat = trinity.GetViewTransform() cpos = geo2.Vector(*trinity.GetViewPosition()) dir = geo2.Vec3Normalize(geo2.Subtract(cpos, ppos)) lookat = geo2.Vector(viewMat[0][2], viewMat[1][2], viewMat[2][2]) point = cpos + lookat * dist return RayToPlaneIntersection(ppos, dir, point, lookat)
def CameraFacingMatrix(objtransform): viewMat = trinity.GetViewTransform() objInv = geo2.MatrixInverse(objtransform) viewInv = geo2.MatrixInverse(viewMat) viewInv = geo2.MatrixMultiply(viewInv, objInv) rmat = geo2.MatrixRotationX(math.pi * 0.5) rmat = geo2.MatrixMultiply(rmat, viewInv) rmat = (rmat[0], rmat[1], rmat[2], (0.0, 0.0, 0.0, rmat[3][3])) return rmat
def Render(self): if self.display: viewTrans = trinity.GetViewTransform() view = geo2.Vector(viewTrans[0][2], viewTrans[1][2], viewTrans[2][2]) localpos = self.GetTranslation() campos = geo2.Vector(*trinity.GetViewPosition()) vec = localpos - campos vec = geo2.Vec3Normalize(vec) if geo2.Vec3Dot(vec, view) > 0.0: mat = self.GetTargetPlaneProjectionMatrix() areas = self.geometry.Update(mat) self.geometry.Render(self.Cull(areas))
def _TransformAxis(self, v): viewMat = trinity.GetViewTransform() viewVec = geo2.Vector(viewMat[0][2], viewMat[1][2], viewMat[2][2]) pos = self.GetTranslation() start = self.startPlanePos - pos start = geo2.Vec3Normalize(start) end = self.endPlanePos - pos end = geo2.Vec3Normalize(end) q = geo2.QuaternionIdentity() dot = geo2.Vec3Dot(start, end) if 1.0 - dot < 1e-05: return q dnormal = geo2.Vec3Cross(start, end) if self.activeManipAxis == 'w': worldInv = geo2.MatrixInverse(self.worldTranslation) axis = geo2.Vec3TransformNormal(viewVec, worldInv) axis = geo2.Vector(*axis) rdot = geo2.Vec3Dot(axis, viewVec) ddot = geo2.Vec3Dot(dnormal, axis) if ddot < 0.0 and rdot > 0.0: axis = -axis elif ddot > 0.0 and rdot < 0.0: axis = -axis elif self.activeManipAxis == 'ww': curP = self._Hemisphere(self.curX, self.curY) preP = self._Hemisphere(self.preX, self.preY) viewInverse = geo2.MatrixInverse(viewMat) norm = geo2.Vec3Cross(preP, curP) worldInv = geo2.MatrixInverse(self.worldTranslation) axis = geo2.Vec3TransformNormal(norm, worldInv) axis = geo2.Vec3TransformNormal(axis, viewInverse) dot = geo2.Vec3Dot(curP, preP) else: axis = self.axis[self.activeManipAxis] if geo2.Vec3Dot(dnormal, axis) < 0.0: axis = -axis if self.activeManipAxis == 'x' and self.worldTranslation[0][ 0] < 0.0 or self.activeManipAxis == 'y' and self.worldTranslation[ 1][1] < 0.0 or self.activeManipAxis == 'z' and self.worldTranslation[ 2][2] < 0.0: axis = -axis self.startPlanePos = self.endPlanePos if dot < -1: dot = -1 elif dot > 1: dot = 1 q = geo2.QuaternionRotationAxis(axis, math.acos(dot)) q = geo2.QuaternionNormalize(q) return q
def GetDesiredPlaneNormal(self, ray): viewMat = trinity.GetViewTransform() view = geo2.Vector(viewMat[0][2], viewMat[1][2], viewMat[2][2]) local_axis = {'x': self.GetRightVec(), 'y': self.GetUpVec(), 'z': self.GetFrontVec()} if self.activeManipAxis in local_axis: axis = local_axis[self.activeManipAxis] if geo2.Vec3Dot(view, axis) > 0.0: norm = -axis else: norm = axis else: norm = view norm = geo2.Vec3Normalize(norm) return norm
def Cull(self, areas): pos = geo2.Vector(self.frontPlaneTranslation[3][0], self.frontPlaneTranslation[3][1], self.frontPlaneTranslation[3][2]) viewMat = trinity.GetViewTransform() lookat = geo2.Vector(-viewMat[0][2], -viewMat[1][2], -viewMat[2][2]) x_area = dungeonEditorToolGeometry.area('x', 4294771202L) y_area = dungeonEditorToolGeometry.area('y', 4278385922L) z_area = dungeonEditorToolGeometry.area('z', 4278321917L) x_lines = [] y_lines = [] z_lines = [] for each in iter(areas): name = each.name if name not in ('x', 'y', 'z'): continue b = pos - (each.bounds.updated_center - lookat * each.bounds.radius) if geo2.Vec3Dot(geo2.Vec3Normalize(b), lookat) < 0.0 or not self.axisCulling: if name == 'x': x_area.SetColor(each.GetColor()) x_area.lineset.transform = each.lineset.transform x_lines.extend(each.lines) elif name == 'y': y_area.SetColor(each.GetColor()) y_area.lineset.transform = each.lineset.transform y_lines.extend(each.lines) elif name == 'z': z_area.SetColor(each.GetColor()) z_area.lineset.transform = each.lineset.transform z_lines.extend(each.lines) self.geometry.visible_areas.append(each) x_area.AddToLineSet(x_lines) x_area.lineset.zEnable = False y_area.AddToLineSet(y_lines) y_area.lineset.zEnable = False z_area.AddToLineSet(z_lines) z_area.lineset.zEnable = False return [ x_area, y_area, z_area, self.geometry.GetArea('w'), self.geometry.GetArea('ww') ]
def GetDesiredPlaneNormal(self, ray): """ We need to pick a plane for ray intersection for translation and scaling because the camera might end up in the plane that the selected axis is fixed to. In 3-Dimensions we have 3 perpendicular planes and each axis can be mapped to two of them, so we need to pick the one that we are further away from. x -- YX, ZX y -- ZY, XY z -- XZ, YZ """ x_axis = X_AXIS y_axis = Y_AXIS z_axis = Z_AXIS if self.activeManipAxis: if self.activeManipAxis == 'x': ydot = abs(geo2.Vec3Dot(ray, y_axis)) zdot = abs(geo2.Vec3Dot(ray, z_axis)) if zdot > ydot: return z_axis if ydot > zdot: return y_axis elif self.activeManipAxis == 'y': zdot = abs(geo2.Vec3Dot(ray, z_axis)) xdot = abs(geo2.Vec3Dot(ray, x_axis)) if zdot > xdot: return z_axis if xdot > zdot: return x_axis elif self.activeManipAxis == 'z': xdot = abs(geo2.Vec3Dot(ray, x_axis)) ydot = abs(geo2.Vec3Dot(ray, y_axis)) if xdot > ydot: return x_axis if ydot > xdot: return y_axis else: viewMat = trinity.GetViewTransform() return geo2.Vector(viewMat[0][2], viewMat[1][2], viewMat[2][2]) else: return None
def WndProc(hwnd, message, wParam, lParam): dev = trinity.device if message == WM_DESTROY: blue.os.Terminate() return 0 elif message == WM_CLOSE: blue.os.Terminate() return 0 if message == WM_SIZE: if dev.GetWindow(): rect = RECT() ctypes.windll.user32.GetClientRect(hwnd, ctypes.byref(rect)) viewTrans = trinity.GetViewTransform() fov = trinity.GetFieldOfView() front = trinity.GetFrontClip() back = trinity.GetBackClip() w, h = rect.right, rect.bottom defaultBackBuffer = trinity.device.GetRenderContext().GetDefaultBackBuffer() if w == defaultBackBuffer.width and h == defaultBackBuffer.height: return 0 asp = float(w) / float(h) dev.ChangeBackBufferSize(w, h) trinity.SetPerspectiveProjection(fov, front, back, asp) trinity.SetViewTransform(viewTrans) elif message == WM_LBUTTONDOWN: rect = RECT() ctypes.windll.user32.GetClientRect(hwnd, ctypes.byref(rect)) offset = POINT() ctypes.windll.user32.ClientToScreen(hwnd, ctypes.byref(offset)) ctypes.windll.user32.OffsetRect(ctypes.byref(rect), offset.x, offset.y) ctypes.windll.user32.ClipCursor(ctypes.byref(rect)) PostOnMouse('LEFT_BUTTON_DOWN', wParam, lParam) elif message == WM_LBUTTONUP: ctypes.windll.user32.ClipCursor(0) PostOnMouse('LEFT_BUTTON_UP', wParam, lParam) elif message == WM_LBUTTONDBLCLK: PostOnMouse('LEFT_BUTTON_DBLCLK', wParam, lParam) elif message == WM_RBUTTONUP: PostOnMouse('RIGHT_BUTTON_UP', wParam, lParam) elif message == WM_RBUTTONDOWN: PostOnMouse('RIGHT_BUTTON_DOWN', wParam, lParam) elif message == WM_RBUTTONDBLCLK: PostOnMouse('RIGHT_BUTTON_DBLCLK', wParam, lParam) elif message == WM_MBUTTONUP: PostOnMouse('MIDDLE_BUTTON_UP', wParam, lParam) elif message == WM_MBUTTONDOWN: PostOnMouse('MIDDLE_BUTTON_DOWN', wParam, lParam) elif message == WM_MBUTTONDBLCLK: PostOnMouse('MIDDLE_BUTTON_DBLCLK', wParam, lParam) elif message == WM_MOUSEMOVE: PostOnMouse('MOUSE_MOVE', wParam, lParam) elif message == WM_MOUSEWHEEL: PostOnMouse('MOUSE_WHEEL', wParam, lParam) elif message == WM_ACTIVATE: if not (wParam == WA_ACTIVE and wParam == WA_CLICKACTIVE): ctypes.windll.user32.ClipCursor(0) elif message == WM_SYSCOMMAND: if wParam == SC_KEYMENU: return 0 else: if message == WM_ERASEBKGND: return 0 if message == WM_KEYDOWN: if OnKeyDown is not None and callable(OnKeyDown): OnKeyDown(wParam) elif message == WM_KEYUP: if OnKeyUp is not None and callable(OnKeyUp): OnKeyUp(wParam) elif message == WM_CHAR: if OnChar is not None and callable(OnChar): OnChar(wParam) if uilib is not None: try: return int(uilib.OnAppEvent(message, wParam, lParam)) except: import traceback traceback.print_exc() return 0 else: return ctypes.windll.user32.DefWindowProcA(ctypes.c_int(hwnd), ctypes.c_int(message), ctypes.c_int(wParam), ctypes.c_int(lParam))