// 同一 Scene3D 在透视/正交视口中展示;相机控制独立,网格业务变换由两边共享。 // 三维内容与普通 Endor 二维控件一起排版,viewport 有限尺寸不限制场景世界坐标。 // 保存左侧视口和共享立方体;动作可改相机位置或真实网格变换。 class SceneActions { view: Viewport3D cube: Mesh3D // 把左相机放到 z=6 正面,保持相机既有 target。 function front(self: SceneActions): Unit { self.view.camera.x = 0 self.view.camera.y = 0 self.view.camera.z = 6 } // 把同一相机移到侧上方,右侧正交相机保持原设置。 function side(self: SceneActions): Unit { self.view.camera.x = 6 self.view.camera.y = 2 self.view.camera.z = 0 } // 修改共享 cube 的欧拉旋转,因此两个视口都看到物体变化。 function rotate(self: SceneActions): Unit { self.cube.rotate(0, 15, 0) } // 示范 Event.hit.mesh 的真实托管网格材质写入;此文件尚未把 select 注册到视口。 function select(self: SceneActions, event: Event): Unit { event.hit.mesh.color = "#6B9B81" } } // 先构造并变换两个 Box3D,再由 Group3D 组成场景节点;几何与相机是不同对象。 cube = Box3D(1.6, 1.6, 1.6, "#6687AB") cube.rotationY = 25 cube.rotationX = 15 small = Box3D(0.7, 0.7, 0.7, "#DBA36E") small.x = 1.8 small.z = -0.8 group = Group3D(cube, small) // 薄盒作地面,方向光与 ambient 一起影响材质颜色,不是二维背景矩形。 floor = Box3D(6, 0.08, 4, "#D8DEE6") floor.y = -1.1 light = DirectionalLight(-1, -2, -3, "#FFFFFF", 0.9) scene = Scene3D(group, floor, light) scene.ambient = 0.35 // 左视口使用默认透视相机,右视口显式换成 OrthographicCamera 并设置可见高度。 perspective = Viewport3D(480, 360, scene) perspective.camera.z = 6 orthographic = Viewport3D(320, 360, scene) orthographic.camera = OrthographicCamera() orthographic.camera.height = 5 orthographic.camera.x = 4 orthographic.camera.y = 2 orthographic.camera.z = 5 // 按钮绑定零参数方法;页面文字说明原生默认控制器的交互,代码可继续替换 controller。 actions = SceneActions(perspective, cube) front = Button("正面") front.onClick(actions.front) side = Button("侧面") side.onClick(actions.side) rotate = Button("物体旋转 +15°") rotate.onClick(actions.rotate) page = Page() page.title = "场景、视口和摄像机" page.render(Column(24, 16, TextBlock("同一个 3D 场景,两个摄像机", 2), Row(0, 16, perspective, orthographic), Row(0, 12, front, side, rotate), TextBlock("左键拖动旋转 · 中键或空格拖动平移 · 滚轮缩放\n摄像机和控制器都是可编程对象;2D 控件由 Endor 自己排版。")))