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; }
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; }
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; }