
MouseInput 运算符深度解析用鼠标/触控板实时驱动 TiXL 任意参数【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3导读本文围绕 TiXLt3开源实时动态图形软件中Lib.io.input运算符库的MouseInput运算符展开讲解如何将鼠标指针位置、左键按下状态实时转换为可驱动任意运算符参数的信号。读完本文你将掌握 MouseInput 的三个输入参数DoUpdate、OutputMode、Scale与三个输出Position、IsLeftButtonDown、Position3d的语义理解四种坐标输出模式归一化、带符号坐标、世界 XY 平面、世界地面平面背后的源码实现原理并学会将其与其他运算符组合实现交互式图形。文档原文见 .help/docs/operators/lib/io/input/MouseInput.md所属运算符库索引为 .help/docs/operators/lib/io/input/README.md。运算符是什么MouseInput 属于 TiXL 的输入类运算符位于Operators/Lib/Symbols/io/input/目录其定位是允许使用鼠标 / 触控板对任意数值进行实时操控。当鼠标指针移动到输出窗口Output Window上方时鼠标移动的 X 轴与 Y 轴数值会被求值并可用于控制任意函数同时鼠标左键的按下状态可被求值为布尔值Boolean。其官方描述原文为Allows the real-time manipulation of any values using the mouse / trackpad如果鼠标指针位于输出窗口之外运算符输出的位置值将停留在最后一次采样结果上对应源码中直接读取静态缓存T3.SystemUi.MouseInput.LastPosition见下文“数据从哪来”一节。输入参数名称相关度与类型说明DoUpdateBoolean允许强制持续更新OutputModeInt32定义指针位置的求值方式即坐标转换模式ScaleSingle对输出值进行乘法 / 放大DoUpdate强制持续更新DoUpdate为布尔输入默认值为false见 MouseInput.t3 中DefaultValue: false。当该输入为true时即使没有任何下游输出被求值运算符也会被强制每帧更新从而确保位置输出始终是最新的。OutputMode指针位置的求值方式OutputMode是 Int32 类型输入但其真实语义由一个枚举约束。在源码 MouseInput.cs 中定义了四种模式private enum OutputModes { Normalized, SignedPosition, OnWorldXYPlane, OnWorldFloorPlane }该输入在源码中使用MappedType typeof(OutputModes)标记MouseInput.cs因此在编辑器界面中会以枚举下拉列表形式呈现而非裸整数。默认值为1即SignedPosition模式。各模式的具体数学行为见下文“四种输出模式”一节。Scale输出放大Scale为 Single单精度浮点输入默认值为1.0。在SignedPosition模式下它直接乘以输出位置向量源码(lastPosition - new Vector2(0.5f, 0.5f)) * new Vector2(aspectRatio, -1) * scale用于放大或缩小鼠标移动对目标参数的影响幅度。输出名称类型PositionSystem.Numerics.Vector2IsLeftButtonDownSystem.BooleanPosition3dSystem.Numerics.Vector3三个输出在源码中均标记为DirtyFlagTrigger.AnimatedMouseInput.cs即任何一帧鼠标状态发生变化都会使输出标记为脏并触发下游求值这正是“实时操控”能够流畅驱动的关键机制。Position二维坐标输出其取值范围与坐标系由OutputMode决定归一化 0~1 或带符号坐标等。IsLeftButtonDown当前是否按住鼠标左键可直接接入布尔型输入配合BoolToFloat等做条件触发。Position3d三维坐标输出。在归一化与带符号模式下它只是把二维坐标映射为(X, Y, 0)而在世界平面模式下则是射线与平面相交得到的世界坐标点。四种输出模式详解源码级Update方法的完整逻辑位于 MouseInput.cs其核心流程为读取模式 → 读取缩放 → 计算输出宽高比 → 读取全局鼠标缓存 → 按模式分支计算。Normalized归一化case OutputModes.Normalized: Position.Value lastPosition; Position3d.Value new Vector3(lastPosition.X, lastPosition.Y, 0); break;直接输出原始相对坐标(0,0)为输出窗口左上角(1,1)为右下角。适合将鼠标位置直接映射到纹理 UV 或 0~1 范围参数。SignedPosition带符号位置默认模式case OutputModes.SignedPosition: Position.Value (lastPosition - new Vector2(0.5f, 0.5f)) * new Vector2(aspectRatio, -1) * scale; Position3d.Value new Vector3(lastPosition.X, lastPosition.Y, 0); break;将归一化坐标平移到以窗口中心为原点然后X 轴乘以输出宽高比aspectRatio RequestedResolution.Width / RequestedResolution.HeightMouseInput.cs使不同分辨率下 X/Y 的“像素尺度”保持一致Y 轴乘以-1将屏幕坐标系向下为正翻转为数学坐标系向上为正再整体乘以Scale。这是默认模式.t3中DefaultValue: 1适合将鼠标映射到以原点为中心的 2D 参数空间例如控制粒子的发射方向或图形的平移偏移。OnWorldXYPlane世界 XY 平面与 OnWorldFloorPlane世界地面平面case OutputModes.OnWorldXYPlane: case OutputModes.OnWorldFloorPlane: { Matrix4x4.Invert(context.CameraToClipSpace, out var clipSpaceToCamera); Matrix4x4.Invert(context.WorldToCamera, out var cameraToWorld); var clipSpaceToWorld clipSpaceToCamera * cameraToWorld; var posInClip (lastPosition - new Vector2(0.5f, 0.5f)) * new Vector2(2, -2); var posInWorld GraphicsMath.TransformCoordinate(new Vector3(posInClip, 0f), clipSpaceToWorld); var targetInWorld GraphicsMath.TransformCoordinate(new Vector3(posInClip, 1f), clipSpaceToWorld); var ray new Ray(posInWorld, targetInWorld - posInWorld); var planeNormal mode OutputModes.OnWorldXYPlane ? Vector3.UnitZ : Vector3.UnitY; var xyPlane PlaneExtensions.CreateFromPointAndNormal(Vector3.Zero, planeNormal); if (xyPlane.Intersects(ray, out Vector3 intersectionPoint)) { Position.Value new Vector2(intersectionPoint.X, intersectionPoint.Y); Position3d.Value intersectionPoint; } break; }这两种模式把屏幕上的鼠标位置反投影到 3D 世界实现“鼠标点哪里世界坐标就落在哪里”通过求逆CameraToClipSpace与WorldToCamera矩阵合成ClipSpaceToWorld变换将归一化坐标映射到裁剪空间×2扩展到[-1,1]Y 取负翻转分别在近远两个深度上构造两个世界点从而得到一条从摄像机射出的射线Ray用该射线与过原点、法向量为UnitZXY 平面即垂直于 Z 轴的正视平面或UnitY地面平面即垂直于 Y 轴的俯视地面的平面求交交点即为世界坐标Position3d输出完整三维交点Position取其 X、Y 分量。从源码结构可以推断这两种模式专用于 3D 场景交互场景例如配合Transform、TransformMesh在 XY 平面或地面上拖拽对象或拾取地形上的点生成粒子。鼠标数据从哪来一条完整的输入链路MouseInput 运算符本身并不直接监听系统鼠标事件而是读取一个全局静态缓存。这条数据链路贯穿 Player、Editor 与 SystemUi 三个模块静态缓存SystemUi/MouseInput.cs定义了静态类T3.SystemUi.MouseInput持有LastPosition默认Vector2.Zero与IsLeftButtonDown两个属性以及供编辑器使用的SelectedChildId。其Set()方法注释明确指出“需要由 Imgui 或 Program 调用”public static void Set(Vector2 newPosition, bool isLeftButtonDown) { LastPosition newPosition; IsLeftButtonDown isLeftButtonDown; }Player 端独立运行播放器在 Player/Program.Input.cs 中MouseMoveHandler订阅渲染窗口的MouseMove与MouseClick事件将鼠标位置换算为相对于窗体尺寸的归一化坐标(e.X / form.Size.Width, e.Y / form.Size.Height)后调用MouseInput.Set(...)左键状态取自e.Button MouseButtons.Left。Editor 端编辑器输出窗口在 Editor/Gui/Windows/ImageOutputCanvas.cs 中当鼠标悬停在图像输出画布上时同样以归一化方式计算相对位置并调用MouseInput.Set(relativePosition, ImGui.IsMouseDown(ImGuiMouseButton.Left))。无论运行于 Player 还是 Editor鼠标状态最终都会汇聚到同一个全局缓存再由运算符的Update方法读取MouseInput.cs因此两种运行环境下的行为完全一致。常用组合与关联运算符官方文档明确列出了常用组合[Vec2ToVec3]把二维Position扩展为三维向量便于驱动三维运算符[Vector2Components]将Position拆分为独立的 X、Y 浮点值分别控制两个参数[BoolToFloat]把IsLeftButtonDown布尔值转为 0/1 浮点用于乘法调制或条件混合[Transform] / [TransformMesh]将鼠标位置作为平移、旋转或缩放目标实现拖拽式交互。同时参见同库中的KeyboardInput键盘按键驱动任意数值与MidiInputMIDI 控制器驱动三者共同构成 TiXL 的实时输入运算符家族更完整的输入类运算符清单见 Lib.io.input 索引。运算符的注册与默认配置MouseInput 的实例定义在 MouseInput.t3FormatVersion 3默认值如下{ FormatVersion: 3, Id: eff2ffff-dc39-4b90-9b1c-3c0a9a0108c6 /*MouseInput*/, Inputs: [ { Id: 1327525c-716c-43e4-a5d1-58cf35440462 /*OutputMode*/, DefaultValue: 1 }, { Id: 49775cc2-35b7-4c9f-a502-59fe8fbbe2a7 /*DoUpdate*/, DefaultValue: false }, { Id: 6b1e81bd-2430-4439-ad0c-859b2433c38b /*Scale*/, DefaultValue: 1.0 } ], Children: [], Connections: [] }运算符的 C# 实现通过[Guid(eff2ffff-dc39-4b90-9b1c-3c0a9a0108c6)]与 .t3 文件中的Id关联三个输出槽与三个输入槽均有各自独立的 GUID见 MouseInput.cs。该运算符位于Lib.io.input命名空间随Operators/Lib项目一起编译其 UI 描述文件为同目录下的 MouseInput.t3ui。快速上手让画面跟随鼠标下面给出一个最小的实战路径在编辑器图表面板中搭建在运算符搜索框输入MouseInput并放置到画布将其Position输出接入目标运算符的参数例如经Vector2Components拆分后分别接到某个 2D 变换的 X/Y 平移输入保持OutputMode默认值SignedPosition1即可得到以窗口中心为原点、Y 轴向上的“带符号”坐标——适合直接作为平移量若只需 0~1 的 UV 类映射将OutputMode切到Normalized调节Scale默认 1.0控制灵敏度若画面无响应检查DoUpdate是否需要置true以强制持续更新若需响应鼠标点击将IsLeftButtonDown经BoolToFloat接入混合权重实现“按住左键才生效”的交互。需要注意的是该运算符依赖输出窗口中的鼠标悬停事件见上文 Player/Editor 两条数据链路因此运行或预览时必须确保鼠标位于输出窗口或编辑器图像输出画布内位置输出才会更新。小结MouseInput 是 TiXL 中实现“鼠标即控制器”的核心输入运算符上层由 Player/Editor 将窗口鼠标位置归一化后写入全局缓存T3.SystemUi.MouseInput下层由运算符按四种OutputMode将其转换为归一化坐标、带符号 2D 坐标或反投影的世界坐标配合Scale与DoUpdate精确控制更新行为。结合Vec2ToVec3、Vector2Components、BoolToFloat、Transform等运算符即可快速搭建出实时响应鼠标的交互式动态图形。【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考