首页 > 解决方案 > 计算/近似刚体上的速度和旋转冲量,只给定一个位置的力和刚体的质心?

问题描述

我正在开发一个计算着色器,它允许流体粒子引擎(NVidia Flex)和刚体物理引擎(Unity3D Engine)之间的双向物理交互。

基本上对于计算着色器,我使用 5 个输入缓冲区:
(float4)粒子速度/形状接触指数
(float4)形状质心
(int)形状标志 - 动态与静态等
(int)粒子指数
(float4)粒子位置和质量

和 2 个输出缓冲区:
(float3) 速度增量
(float3) 旋转速度增量

我正在寻找的功能是最小的,不需要准确,它只需要有点可信,因为我主要只是将它用于视觉效果。我知道我可以使用 NVidia flex 粒子创建刚体约束并使用它,但在我的情况下,这不切实际,因为我的流体模拟使用非常小的粒子,而中等大小的rigiddodies 将使用 NVidia 刚性约束的粒子比文档多得多建议每个身体说。

所以无论如何,我已经到了这样的程度,在我的着色器中,我需要一个物理公式来获取世界空间中力的原点、力矢量、世界空间中形状的质心,我需要它给我形状的净增量速度(假设密度均匀)和形状的净旋转速度。对于每个形状与粒子之间的每次接触,此功能将多次应用于每个形状。

这是一些伪代码:

// The velocity of the particle at the time of contact
float4 contactVelocity;

// The index of the shape that the particle collided with
int shapeIndex;

// The particle's position in the world (which should be the same as the contact point)
float3 pos;

// The mass of the particle
float mass;

// The shape's center of mass
float3 shapeOrigin;

// TODO: define ApplyVelForce & ApplyRotForce
velDelta[shapeIndex] = velDelta[shapeIndex] + GetVelForce(shapeOrigin, contactVelocity * mass, pos);
rotVelDelta[shapeIndex] = rotVelDelta[shapeIndex] + GetRotForce(shapeOrigin, contactVelocity * mass, pos);

// function definitions
float3 GetVelForce(float3 shapeCentroid, float3 force, float3 forcePoint){ /* TODO define */ }
float3 GetRotForce(float3 shapeCentroid, float3 force, float3 forcePoint){ /* TODO define */ }

如果有人知道一个相对简单的公式来合理有效地计算甚至近似这些速度和旋转力,请告诉我。我搜索了谷歌,但所有关于此的文章似乎都超出了我的想象。我只是认为我没有足够的运动学经验和知识,还无法自己弄清楚这些公式。

标签: physicscompute-shaderrigid-bodieskinematicsnvidia-flex

解决方案


考虑到您想要作为输入的信息,您想要的通常是不确定的。在一般情况下,您需要作为输入:

Input:

center of mass of shape : x_c (changes with time)
orientation of shape in space : U (orthogonal matrix, equivalent to a coordinate frame
                                    attached to and moving with the shape, 
                                    changes with time)
Force vector in world space : f (changes with time)
point of force in world space : x_F (changes with time)
inertia matrix of the shape : J (constant) 
mass of shape : m (constant)

Output:
Velocity of center of mass : v_c (changes with time)
Angular velocity of shape in world frame : o (changes with time)

通常,在任何给定时刻,刚体在世界坐标系中的位置和方向的完整描述如下:

x_c = x_c(t), U = U(t)

其中U是 3×3 正交矩阵,其列是坐标系的 3 个单位向量的坐标,该坐标系牢固地附着在以点 x_c 为原点并随其移动的刚体上。

假设X_F在刚体上的一个点上施加了一些力,其中的坐标X_F位于与刚体相连的框架中(而不是在世界系统中)。在合理的模型中,我们假设他的点X_F在身体固定框架中不随时间变化(当然它在世界框架中变化)。设力的矢量,在附着在身体上的框架中,是F,在身体固定的框架中表示的角速度是O

然后,在世界框架中:

point of force: 
x_F = x_c + U * X_F

force:
f = U*F

angular velocity (along the momentary axis of rotation):
o = U*O

那么运动方程是

d/dt(x_c) = v_c

d/dt(v_c) = U*F / m

d/dt (J*O) = cross(J*O, O) + U.T * cross(X_F, F)

d/dt U = U*matrix(O)

在哪里

x_c = center of mass,  
v_c = velocity of center of mass,  
O = angular velocity in body fixed frame,  
U = 3 by 3 orthogonal a matrix with columns the 
    orientations of the axis of the body fixed system 
F = force in body-fixed frame
X_F = point of force in body fixed frame

因此,产生刚体运动的简单迭代方案是

input:
x_c_in, v_c_in, U_in, O_in, J, m, X_F, F, h = time-step 

x_c_out = x_c_in + h*v_c_in
v_c_out = v_c_in + h*(U_in * F_in)/m
Rot_hO = rotate(h*O_in) 
        (perform rotation around axis determined by vector O and angle h*norm(O))
U_out = U_in * Rot_hO
O_out = O_in + h*inverse(J)*( cross(J*O_in, O_in) + cross(X_F, F) )

output:
x_c_out, v_c_out, U_out, O_out,

某处应该有一个函数来计算F身体固定框架中的力。它可能是F一个简单的常数向量,它可能只是相对于时间改变它的大小和方向F = F(t),或者它通常取决于身体的位置、方向、速度甚至角速度,所以F = F(x_c, v_c, U, O)


推荐阅读