本文目的,分析如何產生一個球面上的力(方向垂直於球面)
繼續分析官方demo
在 FrictionlessSphere demo 中,創建了一個球面,由於球面各店的法向量均不相同,相對於上一個demo中平面的力計算要稍微複雜一點點。
力的方向
- 首先判斷裝置位置與球心之間的距離,當距離小於半徑時代表穿透
- 穿透時計算球心指向裝置位置的向量vec,單位化
- 接着根據穿透的程度以及平面硬度(彈簧係數),由胡克定律得到最終的力
demo源碼如下
其中 main 函數沒有變化,只是回調函數的邏輯發生更改
HDCallbackCode HDCALLBACK FrictionlessSphereCallback(void *data)
{
const double sphereRadius = 40.0;
const hduVector3Dd spherePosition(0,0,0);
// 硬度
const double sphereStiffness = .25;
hdBeginFrame(hdGetCurrentDevice());
// device 位置.
hduVector3Dd position;
hdGetDoublev(HD_CURRENT_POSITION, position);
// device 位置和球心距離
double distance = (position-spherePosition).magnitude();
// 當刺破球面時
if (distance < sphereRadius)
{
// 計算穿刺距離
double penetrationDistance = sphereRadius-distance;
// 球心到位置方向向量
hduVector3Dd forceDirection = (position-spherePosition)/distance;
// 計算力
double k = sphereStiffness;
hduVector3Dd x = penetrationDistance*forceDirection;
hduVector3Dd f = k*x;
hdSetDoublev(HD_CURRENT_FORCE, f);
}
hdEndFrame(hdGetCurrentDevice());
HDErrorInfo error;
if (HD_DEVICE_ERROR(error = hdGetError()))
{
hduPrintError(stderr, &error, "Error during main scheduler callback\n");
if (hduIsSchedulerError(&error))
{
return HD_CALLBACK_DONE;
}
}
return HD_CALLBACK_CONTINUE;
}