Example #1
0
            public void Execute(int index, TransformAccess transform)
            {
                ParticleInfo particleInfo = ParticleArray[index];

                // ParticleInfo pp = ParticleArray[particleInfo.ParentIndexInGlobalArray];



                particleInfo.WorldPosition = particleInfo.TempWorldPosition;
                transform.position         = particleInfo.WorldPosition;
                transform.rotation         = particleInfo.WorldRotation;
                ParticleArray[index]       = particleInfo;
            }
Example #2
0
            public void Execute(int index)
            {
                int      headIndex   = index / MaxParticleLimit;
                HeadInfo curHeadInfo = HeadArray[headIndex];

                int offset = index % MaxParticleLimit;

                //每个Head及其Particle只需要计算一次就够了!
                if (offset == 0)
                {
                    float3     parentPosition = curHeadInfo.RootParentBoneWorldPosition;
                    quaternion parentRotation = curHeadInfo.RootParentBoneWorldRotation;

                    for (int j = 0; j < curHeadInfo.ParticleCount; j++)
                    {
                        int          pIdx = curHeadInfo.DataOffsetInGlobalArray + j;
                        ParticleInfo p    = ParticleArray[pIdx];



                        float3     localPosition = p.LocalPosition * p.ParentScale;
                        quaternion localRotation = p.LocalRotation;
                        float3     worldPosition =
                            Util.LocalToWorldPosition(parentPosition, parentRotation, localPosition);
                        quaternion worldRotation =
                            Util.LocalToWorldRotation(parentRotation, localRotation);



                        parentPosition = p.WorldPosition = worldPosition;
                        parentRotation = p.WorldRotation = worldRotation;

                        ParticleArray[pIdx] = p;
                    }
                }

                //如果遍历到空的部分就直接跳过就好了
                if (offset >= curHeadInfo.ParticleCount)
                {
                    return;
                }

                int          particleId = curHeadInfo.DataOffsetInGlobalArray + offset;
                ParticleInfo particle   = ParticleArray[particleId];


                if (particle.ParentIndex >= 0)
                {
                    float3 v     = particle.TempWorldPosition - particle.TempPrevWorldPosition;
                    float3 rMove = curHeadInfo.ObjectMove * particle.Inert;
                    particle.TempPrevWorldPosition = particle.TempWorldPosition + rMove;

                    float damping = particle.Damping;
                    if (particle.IsCollide)
                    {
                        damping += particle.Friction;
                        if (damping > 1)
                        {
                            damping = 1;
                        }
                        particle.IsCollide = false;
                    }

                    particle.TempWorldPosition += v * (1 - damping) + curHeadInfo.FinalForce + rMove;
                }
                else
                {
                    particle.TempPrevWorldPosition = particle.TempWorldPosition;
                    particle.TempWorldPosition     = particle.WorldPosition;
                }

                ParticleArray[particleId] = particle;
            }
Example #3
0
            public void Execute(int index)
            {
                //避免IndexOutOfRangeException:Index {0} is out of restricted IJobParallelFor range [{1}...{2] in ReadWriteBuffer.
                if (index % MaxParticleLimit == 0)
                {
                    return;
                }

                int      headIndex   = index / MaxParticleLimit;
                HeadInfo curHeadInfo = HeadArray[headIndex];

                //遍历到那些空的Particle就不用再计算了
                int offset = index % MaxParticleLimit;

                if (offset >= curHeadInfo.ParticleCount)
                {
                    return;
                }

                int          particleId   = curHeadInfo.DataOffsetInGlobalArray + offset;
                ParticleInfo particleInfo = ParticleArray[particleId];

                int          parentParticleIndex = curHeadInfo.DataOffsetInGlobalArray + particleInfo.ParentIndex;
                ParticleInfo parentParticleInfo  = ParticleArray[parentParticleIndex];

                float3 pos       = particleInfo.WorldPosition;
                float3 parentPos = parentParticleInfo.WorldPosition;


                //TODO:尾节点的长度计算方法需要用math修改
                Matrix4x4 m = float4x4.TRS(parentParticleInfo.TempWorldPosition, parentParticleInfo.WorldRotation,
                                           particleInfo.ParentScale);

                float restLen = !particleInfo.IsEndBone
                    ? math.distance(parentPos, pos)
                    : m.MultiplyVector(particleInfo.EndOffset).magnitude;


                float stiffness = math.lerp(1.0f, particleInfo.Stiffness, curHeadInfo.Weight);

                if (stiffness > 0 || particleInfo.Elasticity > 0)
                {
                    float4x4 em0 = float4x4.TRS(parentParticleInfo.TempWorldPosition, parentParticleInfo.WorldRotation,
                                                particleInfo.ParentScale);
                    float3 restPos = math.mul(em0, new float4(particleInfo.LocalPosition.xyz, 1)).xyz;

                    float3 d = restPos - particleInfo.TempWorldPosition;
                    particleInfo.TempWorldPosition += d * particleInfo.Elasticity;

                    if (stiffness > 0)
                    {
                        d = restPos - particleInfo.TempWorldPosition;
                        float len    = math.length(d);
                        float maxLen = restLen * (1 - stiffness) * 2;
                        if (len > maxLen)
                        {
                            particleInfo.TempWorldPosition += d * ((len - maxLen) / len);
                        }
                    }
                }

                // //与指定的非全局碰撞器进行计算,会过滤掉挂载的全局碰撞器防止重复计算
                // NativeMultiHashMap<int, int>.Enumerator enumerator = BoneColliderMatchMap.GetValuesForKey(headIndex);
                // while (enumerator.MoveNext())
                // {
                //     if (ColliderArray[enumerator.Current].IsGlobal) continue;
                //     particleInfo.IsCollide =
                //         DynamicBoneCollider.HandleCollision(ColliderArray[enumerator.Current],
                //             ref particleInfo.TempWorldPosition,
                //             in particleInfo.Radius);
                // }
                //
                // //与所有的全局碰撞器进行计算
                // for (int i = 0; i < ColliderArray.Length; i++)
                // {
                //     if (!ColliderArray[i].IsGlobal) continue;
                //     particleInfo.IsCollide =
                //         DynamicBoneCollider.HandleCollision(ColliderArray[i],
                //             ref particleInfo.TempWorldPosition,
                //             in particleInfo.Radius);
                // }


                // particleInfo.WorldPosition = particleInfo.TempWorldPosition;

                float3 dd   = parentParticleInfo.TempWorldPosition - particleInfo.TempWorldPosition;
                float  leng = math.length(dd);

                if (leng > 0)
                {
                    particleInfo.TempWorldPosition += dd * ((leng - restLen) / leng);
                }


                ParticleArray[particleId] = particleInfo;
            }