奇妙的Pairing Function

在实际项目里,我们经常需要把二维坐标 (x, y)、或两个整型键合成一个“唯一”的整型键,方便做哈希表/数组索引;又希望能在需要时还原回原来的两个键。这样一个反直觉的需求真的有解决方案吗?“配对函数”(Pairing Function)隆重登场。 ...

关于AI产品和个人能力的小思考

最近一两年,用AI的方式变化得太快了。每当我指望它“一次给出完美答案”,十有八九会失望;可当我把任务拆成几步,允许它犯错、允许我随时插话校准,结果反而稳、而且更快。这件小事让我意识到:我们真正迫切需要的,或许不只是“更强的模型”,而是“更好的协作方式”。 ...

软件的未来

近期看了一些大佬对AI时代软件形态的探讨,记录一些感悟。 编写软件不再只是程序员可以做的酷酷的事。 过去几十年的发展,“机器”的形态发生了巨大变化,现在,LLM本身也变成了“机器”。 ...

Quality Design 🍎

本文源自对Apple WWDC 2018 的一次公开分享的记录提炼。什么是优秀的设计,它为什么重要,如何追求品质感……这些话题不仅是设计师需要考虑的专业问题,也是每个人打造自己的生活需要知道的内在规律。Video ...

WebGL平台的性能限制和解决方案(以微信小游戏为例)

前几日参加了Unite上海2024,受益颇多。本篇先就相对感兴趣的小游戏平台WebGL技术方案为引子,引出一些关于WebAssembly, IL2CPP, 以及.NET 8对Web平台支持等话题。 ...

带物理交互的CharacterController设计与实现

本文也是PhysX物理引擎系列的番外篇。介绍了笔者基于CharacterController(CCT)设计的一个新的角色控制器,在修补Unity/PhysX的CCT的缺陷外,还增添了若干和物理交互相关的有趣特性。代码已经过实际项目验证,这里仅保留和具体业务无关的部分。 背景和需求 前文结尾处提到一些PhysX自带的CCT(Unity也是基于此二次封装出CharacterController组件)在实际游戏开发中的缺点,这里再次总结: CCT不参与碰撞系统的检测。仅当CCT自身移动时会判断是否被其他刚体或CCT阻挡。这就造成一个BUG:CCT自身静止时,其他运动物体会穿过CCT且没有事件触发。官方论坛上有苦主持续8年向Unity反馈这个问题但无法解决,目前已知的唯一绕过方式是每帧给CCT附加一个微小的位移(下文中的SlightMove)。 Unity提供的接口CharacterController.isGrounded效果很不稳定。其内部只是判断CCT上次运动后底部是否触碰物体。即collisionFlags & eCOLLISION_DOWN::eCOLLISION_DOWN。但在上下坡或崎岖地形时,很容易出现侧面触碰或短暂浮空。如果用该接口驱动动画表现甚至跑跳逻辑,效果很差。需要自行基于SceneQuery封装出更加稳定的判定着地的函数。 Unity没有暴露CCT.upVector,角色总是竖直向上的。要实现反重力鞋在任意斜面上行走或像马里奥银河那样在曲面上跑跳穿梭,只能放弃使用CCT但也放弃了其在操作手感上的改善。其实拿到Unity的源码后,只用了十分钟将底层字段暴露到C#层就解决了该问题。 新的角色控制器需要增加的物理交互特性有: ...

PhysX物理引擎(4)Character Controller

本文主要介绍PhysX角色控制器相关的内部机制和使用方法。 PhysX物理引擎系列记录了在实际项目中使用Nvdia PhysX 3.4物理引擎(Code, Doc)的一些经验,有不少对官方资料的补充。 Warm-up Character Controller (a.k.a CCT) is a special physical object handling player movement. In PhysX, CCT is not a Rigidbody, which means it does not integrate seamlessly in collision system. However, there is a kinematic actor underlying in CCT, and you can attach custom data via PxController::getActor()->userData. ...

PhysX物理引擎(3)Rigidbody Dynamics

本文主要介绍PhysX刚体动力学相关的内部机制和使用方法。 PhysX物理引擎系列记录了在实际项目中使用Nvdia PhysX 3.4物理引擎(Code, Doc)的一些经验,有不少对官方资料的补充。 Warm-up Let’s start with some key concepts: Both Kinematic and Dynamic rigidbodies are represented as PxRigidDynamic in PhysX. You can switch between them at runtime using PxRigidBody::setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true). Kinematic and Static actors remain stationary unless explicitly moved in code. Moving Static actors can result in incorrect collision behavior with dynamic actors. When moving Kinematic actors, always use PxRigidDynamic::setKinematicTarget each frame instead of PxRigidActor::setGlobalPose to ensure correct collision detection with dynamic actors. This post focuses on dynamic rigidbody movement, covering topics such as force and torque, gravity, sleeping, and more. ...

PhysX物理引擎(2)Collision

本文主要介绍PhysX碰撞检测的一些内部机制和使用方法。 PhysX物理引擎系列记录了在实际项目中使用Nvdia PhysX 3.4物理引擎(Code, Doc)的一些经验,有不少对官方资料的补充。 Warm-up Static, Kinematic & Dynamic Static colliders are non-movable. In fact, they are not rigidbody, just PxRigidStatic. Kinematic and dynamic rigidbody are both PxRigidDynamic, and can switch to each other at runtime by setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true/false). The biggest difference is that kinematic rigidbody behaves like infinite mass, and will not move by external force. Instead, you call MovePosition on it. Dynamic rigidbody is the only type we can AddForce to, which has mass, center of mass, and inertia tensor to simulate a natural movement with Newton’s laws of motion. classDiagram PxRigidActor <-- PxRigidStatic PxRigidActor <-- PxRigidBody PxRigidBody <-- PxRigidDynamic PxRigidActor *.. PxShape class PxRigidBody { PxRigidBodyFlag } class PxShape { PxShapeFlag } We cannot make a rigidbody without a shape. Shapes are tangible, with a real size. ...

深入 LossyScale

本文是PhysX物理引擎系列的番外篇,其实要弄明白一个3D数学问题:如何处理父节点带有非均匀缩放、子节点带有旋转时,子节点的最终大小和形态。 问题源自笔者在修改物理引擎为其添加scale属性时遇到的一个bug。解决后对WorldScale为什么叫做LossyScale、空间变换和基变换有了更深的理解。 ...