public void Execute(int index, TransformAccess transform) { /* * } * public void TryExecute(TransformAccessArray transforms, JobHandle job) * { * if (!job.IsCompleted) * { * job.Complete(); * } * for (int i = 0; i < transforms.length; i++) * { * Execute(i, transforms[i]); * } * } * public void Execute(int index, Transform transform) * { */ PointReadWrite *pReadWritePoint = pReadWritePoints + index; //OYM:获取每个读写点 PointRead * pReadPoint = pReadPoints + index; //OYM:获取每个只读点 if (!(pReadPoint->fixedIndex == index || pReadPoint->isVirtual)) //OYM:不是fix点 { transform.position = pReadWritePoint->position; } if (pReadPoint->childFirstIndex > -1) { SetRotation(index, transform, pReadWritePoint, pReadPoint);//OYM:设置旋转 } }
void SetRotation(int index, TransformAccess transform, PointReadWrite *pReadWrite, PointRead *pRead) { transform.localRotation = pRead->localRotation; var child = pReadWritePoints + pRead->childFirstIndex; var parent = pReadWritePoints + pRead->parent; var childRead = pReadPoints + pRead->childFirstIndex; Vector3 ToDirection = child->position - pReadWrite->position;//OYM:朝向等于面向子节点的方向 Vector3 FixedDirection = parent->position - pReadWrite->position; if (ToDirection.sqrMagnitude > EPSILON * EPSILON)//OYM:两点不再一起 { Vector3 FromDirection; if (childRead->isVirtual) { FromDirection = childRead->boneAxis;//OYM:将BoneAxis按照transform.rotation进行旋转 } else { FromDirection = transform.rotation * childRead->boneAxis;//OYM:将BoneAxis按照transform.rotation进行旋转 } Quaternion AimRotation = Quaternion.FromToRotation(FromDirection, ToDirection);//OYM:我仔细考虑了下,fromto用在这里不一定是最好,但是一定是最快 transform.rotation = AimRotation * transform.rotation; } }
//OYM: public void Execute(int index) { PointRead *pReadPoint = pReadPoints + index; if (pReadPoint->fixedIndex != index) { PointReadWrite *pReadWritePoint = pReadWritePoints + index; PointReadWrite *pParentReadWritePoint = pReadWritePoints + (pReadPoint->parent); pReadWritePoint->velocity += pReadPoint->gravity * scale * (0.5f * deltaTime * deltaTime) / iteration;//OYM:重力(要计算iteration次所以除以个iteration) pReadWritePoint->velocity += windForcePower * pReadPoint->windScale / (iteration * pReadPoint->weight); pReadWritePoint->position += pReadWritePoint->velocity / iteration; } }
void SetRotation(int index, TransformAccess transform, PointReadWrite *pReadWrite, PointRead *pRead) { transform.localRotation = pRead->localRotation; var child = pReadWritePoints + pRead->childFirstIndex; var childRead = pReadPoints + pRead->childFirstIndex; var Direction = child->position - pReadWrite->position; //OYM:朝向等于面向子节点的方向 if (Direction.sqrMagnitude > EPSILON * EPSILON) //OYM:两点不再一起 { Vector3 AimVector = transform.rotation * childRead->boneAxis; //OYM:将BoneAxis按照transform.rotation进行旋转 Quaternion AimRotation = Quaternion.FromToRotation(AimVector, Direction); //OYM:我觉得这里应该用lookRotation transform.rotation = AimRotation * transform.rotation; //OYM:旋转过去 } }
//OYM: public void Execute(int index) { PointRead *pReadPoint = pReadPoints + index; if (pReadPoint->fixedIndex != index) { PointReadWrite *pReadWritePoint = pReadWritePoints + index; PointReadWrite *pParentReadWritePoint = pReadWritePoints + (pReadPoint->parent); //OYM:这个函数运转效果并不是很好,这很容易理解,你不能要求一个弹簧又拉又伸,这在逻辑上是行不通的 pReadWritePoint->velocity += pReadPoint->gravity * scale * (0.5f * deltaTime * deltaTime) / iteration; //OYM:重力(要计算iteration次所以除以个iteration) pReadWritePoint->velocity += (pReadPoint->initialPosition - (pReadWritePoint->position - pParentReadWritePoint->position)) * pReadPoint->freeze / iteration; //OYM:freeze力(超过0.1的效果都很有问题,暂时先放这里) pReadWritePoint->velocity += windForcePower * pReadPoint->windScale / (iteration * pReadPoint->weight); pReadWritePoint->position += pReadWritePoint->velocity / iteration; } }
void DistributionPower(Vector3 pushout, float radius, PointReadWrite *pReadWritePointA, PointReadWrite *pReadWritePointB, float WeightProportion, float lengthPropotion, float frictionA, float frictionB, CollideFunc collideFunc) { float sqrPushout = pushout.sqrMagnitude; switch (collideFunc) { case CollideFunc.Outside: if (!(sqrPushout < radius * radius && sqrPushout != 0)) { return; } break; case CollideFunc.Inside: if (sqrPushout < radius * radius && sqrPushout != 0) { return; } break; case CollideFunc.Freeze: break; } //OYM:把pushout方向多余的力给减掉 pReadWritePointA->velocity -= pushout * (Vector3.Dot(pushout, pReadWritePointA->velocity) / sqrPushout); pReadWritePointB->velocity -= pushout * (Vector3.Dot(pushout, pReadWritePointB->velocity) / sqrPushout); pReadWritePointA->velocity *= (1 - frictionA); pReadWritePointB->velocity *= (1 - frictionB); pushout = pushout * (radius / Mathf.Sqrt(sqrPushout) - 1); // float Propotion = WeightProportion * lengthPropotion / (1 - WeightProportion - lengthPropotion + 2 * WeightProportion * lengthPropotion); if (WeightProportion < EPSILON) { pReadWritePointA->position += (pushout * (1 - lengthPropotion)); pReadWritePointA->velocity += (pushout * (1 - lengthPropotion)); } else { lengthPropotion = 1; } pReadWritePointB->position += (pushout * lengthPropotion); pReadWritePointB->velocity += (pushout * lengthPropotion); }
public void Execute(int index, TransformAccess transform) { /* * } * public void TryExecute(TransformAccessArray transforms, JobHandle job) * { * if (!job.IsCompleted) * { * job.Complete(); * } * for (int i = 0; i < transforms.length; i++) * { * Execute(i, transforms[i]); * } * } * * public void Execute(int index, Transform transform) * { */ PointRead * pReadPoint = pReadPoints + index; PointRead * pFixedPointRead = (pReadPoints + pReadPoint->fixedIndex); PointReadWrite *pReadWritePoint = pReadWritePoints + index; PointReadWrite *pFixedPointReadWrite = (pReadWritePoints + pReadPoint->fixedIndex); (pReadWritePoint)->velocity *= pReadPoint->mass; if (pReadPoint->fixedIndex == index)//OYM:fixedpoint { pReadWritePoint->velocity = transform.position - (pReadWritePoints + index)->position; pReadWritePoint->position = transform.position; } else { Vector3 move = pFixedPointReadWrite->velocity * pReadPoint->moveByFixedPoint; pReadWritePoint->position += pFixedPointReadWrite->velocity * pReadPoint->distanceCompensation; Vector3 freezeVector = (pReadWritePoint->position - pFixedPointReadWrite->position) - pReadPoint->initialPosition; pReadWritePoint->position += pFixedPointRead->freeze * freezeVector; pReadWritePoint->velocity -= move; } }
public void Execute(int index, TransformAccess transform) { /* * } * public void TryExecute(TransformAccessArray transforms, JobHandle job) * { * if (!job.IsCompleted) * { * job.Complete(); * } * for (int i = 0; i < transforms.length; i++) * { * Execute(i, transforms[i]); * } * } * * public void Execute(int index, Transform transform) * { */ PointRead * pReadPoint = pReadPoints + index; PointReadWrite *pReadWritePoint = pReadWritePoints + index; (pReadWritePoint)->velocity *= pReadPoint->mass; if (pReadPoint->fixedIndex == index)//OYM:fixedpoint { (pReadWritePoints + index)->velocity = transform.position - (pReadWritePoints + index)->position; (pReadWritePoints + index)->position = transform.position; } else { PointReadWrite *pFixedPointReadWrite = (pReadWritePoints + pReadPoint->fixedIndex); PointReadWrite *pParentReadWrite = (pReadWritePoints + pReadPoint->parent); Vector3 move = pFixedPointReadWrite->velocity * pReadPoint->airResistance + pParentReadWrite->velocity * pReadPoint->lazy; pReadWritePoint->position += move; pReadWritePoint->velocity -= move / pReadPoint->weight; } }
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; } }
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); } } } }