コード例 #1
0
            public void Execute(int index)
            {
                // public void Executea(int index)

                //OYM:获取约束
                ConstraintRead *constraint = pConstraintsRead + index;

                //OYM:获取约束的节点AB
                PointRead *pPointReadA = pReadPoints + constraint->indexA;
                PointRead *pPointReadB = pReadPoints + constraint->indexB;

                //OYM:任意一点都不能小于极小值
                //OYM:if ((WeightA <= EPSILON) && (WeightB <= EPSILON))
                //OYM:获取可读写的点A
                PointReadWrite *pReadWritePointA = pReadWritePoints + constraint->indexA;

                //OYM:获取可读写的点B
                PointReadWrite *pReadWritePointB = pReadWritePoints + constraint->indexB;
                //OYM:获取约束的朝向
                var Direction = pReadWritePointB->position - pReadWritePointA->position;


                float Distance = Direction.magnitude;
                //OYM:力度等于距离减去长度除以弹性,这个值可以不存在,可以大于1但是没有什么卵用
                float Force = (Distance - constraint->length * scale);
                //OYM:是否收缩,意味着力大于0
                bool  IsShrink = Force >= 0.0f;
                float ConstraintPower;//OYM:这个值等于

                switch (constraint->type)
                //OYM:这下面都是一个意思,就是确认约束受到的力,然后根据这个获取杆件约束的属性,计算 ConstraintPower
                //OYM:Shrink为杆件全局值,另外两个值为线性插值获取的值,同理Stretch,所以这里大概可以猜中只是一个简单的不大于1的值
                {
                case ConstraintType.Structural_Vertical:
                    ConstraintPower = IsShrink
                            ? constraint->shrink * (pPointReadA->structuralShrinkVertical + pPointReadB->structuralShrinkVertical)
                            : constraint->stretch * (pPointReadA->structuralStretchVertical + pPointReadB->structuralStretchVertical);
                    break;

                case ConstraintType.Structural_Horizontal:
                    ConstraintPower = IsShrink
                            ? constraint->shrink * (pPointReadA->structuralShrinkHorizontal + pPointReadB->structuralShrinkHorizontal)
                            : constraint->stretch * (pPointReadA->structuralStretchHorizontal + pPointReadB->structuralStretchHorizontal);
                    break;

                case ConstraintType.Shear:
                    ConstraintPower = IsShrink
                            ? constraint->shrink * (pPointReadA->shearShrink + pPointReadB->shearShrink)
                            : constraint->stretch * (pPointReadA->shearStretch + pPointReadB->shearStretch);
                    break;

                case ConstraintType.Bending_Vertical:
                    ConstraintPower = IsShrink
                            ? constraint->shrink * (pPointReadA->bendingShrinkVertical + pPointReadB->bendingShrinkVertical)
                            : constraint->stretch * (pPointReadA->bendingStretchVertical + pPointReadB->bendingStretchVertical);
                    break;

                case ConstraintType.Bending_Horizontal:
                    ConstraintPower = IsShrink
                            ? constraint->shrink * (pPointReadA->bendingShrinkHorizontal + pPointReadB->bendingShrinkHorizontal)
                            : constraint->stretch * (pPointReadA->bendingStretchHorizontal + pPointReadB->bendingStretchHorizontal);
                    break;

                case ConstraintType.Circumference:
                    ConstraintPower = IsShrink
                            ? constraint->shrink * (pPointReadA->circumferenceShrink + pPointReadB->circumferenceShrink)
                            : constraint->stretch * (pPointReadA->circumferenceStretch + pPointReadB->circumferenceStretch);
                    break;

                case ConstraintType.Virtual:
                    ConstraintPower = 1;
                    break;

                default:
                    ConstraintPower = 0.0f;
                    break;
                }


                //OYM:获取AB点重量比值

                float WeightProportion = pPointReadB->weight / (pPointReadA->weight + pPointReadB->weight);

                if (ConstraintPower > 0.0f)//OYM:这里不可能小于0吧(除非有人搞破坏)
                {
                    Vector3 Displacement = Direction.normalized * (Force * ConstraintPower);

                    pReadWritePointA->position += Displacement * WeightProportion;
                    pReadWritePointA->velocity += Displacement * WeightProportion;
                    pReadWritePointB->position -= Displacement * (1 - WeightProportion);
                    pReadWritePointB->velocity -= Displacement * (1 - WeightProportion);
                }

                if (isCollision && constraint->isCollider)
                {
                    for (int i = 0; i < colliderCount; ++i)
                    {
                        ColliderRead *pReadCollider = pReadColliders + i;//OYM:终于到碰撞这里了

                        if (pReadCollider->isOpen && (pPointReadA->colliderChoice & pReadCollider->colliderChoice) != 0)
                        {//OYM:collider是否打开,且pPointReadA->colliderChoice是否包含 pReadCollider->colliderChoice的位
                            ColliderReadWrite *pReadWriteCollider = pReadWriteColliders + i;
                            ComputeCollider(pReadCollider, pReadWriteCollider, pReadWritePointA, pReadWritePointB, WeightProportion, pPointReadA->friction, pPointReadB->friction);
                        }
                    }
                }
            }
コード例 #2
0
            private void ComputeCollider(ColliderRead *pReadCollider, ColliderReadWrite *pReadWriteCollider, PointReadWrite *pReadWritePointA, PointReadWrite *pReadWritePointB, float WeightProportion,
                                         float frictionA, float frictionB)
            {
                switch (pReadCollider->colliderType)
                {
                case ColliderType.Sphere:
                {
                    Vector3 pointOnLine = ConstrainToSegment(pReadWriteCollider->position, pReadWritePointA->position, pReadWritePointB->position - pReadWritePointA->position, out float t);
                    DistributionPower(pointOnLine - pReadWriteCollider->position, pReadCollider->radius, pReadWritePointA, pReadWritePointB, WeightProportion, t, frictionA, frictionB, pReadCollider->collideFunc);
                }

                break;

                case ColliderType.Capsule:
                {
                    SqrComputeNearestPoints(pReadWriteCollider->position, pReadWriteCollider->direction, pReadWritePointA->position, pReadWritePointB->position - pReadWritePointA->position, out _, out float t, out Vector3 pointOnCollider, out Vector3 pointOnLine);
                    DistributionPower(pointOnLine - pointOnCollider, pReadCollider->radius, pReadWritePointA, pReadWritePointB, WeightProportion, t, frictionA, frictionB, pReadCollider->collideFunc);
                }

                break;

                case ColliderType.OBB:
                {
                    SegmentToOBB(pReadWritePointA->position, pReadWritePointB->position, pReadWriteCollider->position, -pReadCollider->boxSize, pReadCollider->boxSize, Quaternion.Inverse(pReadWriteCollider->normal), out float t1, out float t2);
                    Vector3 dir = pReadWritePointB->position - pReadWritePointA->position;
                    t1 = Clamp01(t1);
                    t2 = Clamp01(t2);
                    Vector3 pointOnLineA = pReadWritePointA->position + dir * t1;
                    Vector3 pointOnLineB = pReadWritePointA->position + dir * t2;
                    bool    bHit         = t1 >= 0f && t2 > t1 && t2 <= 1.0f;
                    if (bHit)
                    {
                        float   t            = (t1 + t2) * 0.5f;
                        Vector3 nearestPoint = pReadWritePointA->position + dir * t;
                        Vector3 pushout      = Quaternion.Inverse(pReadWriteCollider->normal) * (nearestPoint - pReadWriteCollider->position);
                        float   pushoutX     = pushout.x > 0 ? pReadCollider->boxSize.x - pushout.x : -pReadCollider->boxSize.x - pushout.x;
                        float   pushoutY     = pushout.y > 0 ? pReadCollider->boxSize.y - pushout.y : -pReadCollider->boxSize.y - pushout.y;
                        float   pushoutZ     = pushout.z > 0 ? pReadCollider->boxSize.z - pushout.z : -pReadCollider->boxSize.z - pushout.z;
                        //OYM:这里我自己都不太记得了 XD
                        //OYM:还是不写Insideblablabla了
                        if (Abs(pushoutZ) < Abs(pushoutY) && Abs(pushoutZ) < Abs(pushoutX))
                        {
                            pushout = pReadWriteCollider->normal * new Vector3(0, 0, pushoutZ);
                        }
                        else if (Abs(pushoutY) < Abs(pushoutX) && Abs(pushoutY) < Abs(pushoutZ))
                        {
                            pushout = pReadWriteCollider->normal * new Vector3(0, pushoutY, 0);
                        }
                        else
                        {
                            pushout = pReadWriteCollider->normal * new Vector3(pushoutX, 0, 0);
                        }
                        if (pushout.sqrMagnitude != 0)
                        {
                            float inverse1Velocity = Vector3.Dot(pushout, pReadWritePointA->velocity) / pushout.sqrMagnitude;
                            pReadWritePointA->velocity -= pushout * inverse1Velocity;
                            pReadWritePointB->velocity -= pushout * inverse1Velocity;
                            pReadWritePointA->velocity *= (1 - frictionA);
                            pReadWritePointB->velocity *= (1 - frictionB);

                            //float Propotion = WeightProportion * t / (1 - WeightProportion - t + 2 * WeightProportion * t);
                            if (WeightProportion > EPSILON)
                            {
                                pReadWritePointA->position += (pushout * t);
                                pReadWritePointA->velocity += (pushout * t);
                            }
                            else
                            {
                                t = 1;
                            }
                            pReadWritePointB->position += (pushout * (1 - t));
                            pReadWritePointB->velocity += (pushout * (1 - t));
                        }
                    }
                    break;
                }

                default:
                    return;
                }
            }
コード例 #3
0
            public void Execute(int index)
            {
                if (!isCollider)
                {
                    return;
                }
                float throwTemp;
                var   pReadWritePoint = pReadWritePoints + index;
                var   pPointRead      = pReadPoints + index;

                //OYM:获取可写点
                for (int i = 0; i < colliderCount; ++i)
                {
                    ColliderRead *     pReadCollider      = pReadColliders + i;
                    ColliderReadWrite *pReadWriteCollider = pReadWriteColliders + i;
                    //OYM:条件判断
                    if (pReadCollider->isOpen && (pPointRead->colliderChoice & pReadCollider->colliderChoice) == 0)
                    {
                        continue;
                    }

                    Vector3 pushout;
                    float   sqrPushout;
                    switch (pReadCollider->colliderType)
                    {
                    case ColliderType.Sphere:
                        pushout    = pReadWritePoint->position - pReadWriteCollider->position;
                        sqrPushout = pushout.sqrMagnitude;
                        if (sqrPushout < pReadCollider->radius * pReadCollider->radius)
                        {
                            pushout = pushout * (pReadCollider->radius / Mathf.Sqrt(sqrPushout) - 1);
                            pReadWritePoint->position += pushout;
                            pReadWritePoint->velocity += pushout;
                        }
                        break;

                    case ColliderType.Capsule:
                        pushout    = pReadWritePoint->position - ConstrainToSegment(pReadWritePoint->position, pReadWriteCollider->position, pReadWriteCollider->direction, out throwTemp);
                        sqrPushout = pushout.sqrMagnitude;
                        if (sqrPushout < pReadCollider->radius * pReadCollider->radius)
                        {
                            pushout = pushout * (pReadCollider->radius / Mathf.Sqrt(sqrPushout) - 1);
                            pReadWritePoint->position += pushout;
                            pReadWritePoint->velocity += pushout;
                        }
                        break;

                    case ColliderType.OBB:
                        pushout = Quaternion.Inverse(pReadWriteCollider->normal) * (pReadWritePoint->position - pReadWriteCollider->position);
                        if (-pReadCollider->boxSize.x < pushout.x && pushout.x < pReadCollider->boxSize.x &&
                            -pReadCollider->boxSize.y < pushout.y && pushout.y < pReadCollider->boxSize.y &&
                            -pReadCollider->boxSize.z < pushout.z && pushout.z < pReadCollider->boxSize.z
                            )
                        {
                            float pushoutX = pushout.x > 0 ? pReadCollider->boxSize.x - pushout.x : -pReadCollider->boxSize.x - pushout.x;
                            float pushoutY = pushout.y > 0 ? pReadCollider->boxSize.y - pushout.y : -pReadCollider->boxSize.y - pushout.y;
                            float pushoutZ = pushout.z > 0 ? pReadCollider->boxSize.z - pushout.z : -pReadCollider->boxSize.z - pushout.z;

                            if (Abs(pushoutZ) < Abs(pushoutY) && Abs(pushoutZ) < Abs(pushoutX))
                            {
                                pushout = pReadWriteCollider->normal * new Vector3(0, 0, pushoutZ);
                            }
                            else if (Abs(pushoutY) < Abs(pushoutX) && Abs(pushoutY) < Abs(pushoutZ))
                            {
                                pushout = pReadWriteCollider->normal * new Vector3(0, pushoutY, 0);
                            }
                            else
                            {
                                pushout = pReadWriteCollider->normal * new Vector3(pushoutX, 0, 0);
                            }
                            pReadWritePoint->position += pushout;
                            pReadWritePoint->velocity += pushout;
                        }
                        break;

                    default:
                        return;
                    }
                }
            }