public void AccumulateTarget(ref BoingEffector.Params effector) { for (int iChain = 0; iChain < BoneData.Length; ++iChain) { var chain = BoneChains[iChain]; var aBone = BoneData[iChain]; if (aBone == null) { continue; } if (!chain.EffectorReaction) { continue; } foreach (var bone in aBone) { if (chain.ParamsOverride == null) { bone.Instance.AccumulateTarget(ref Params, ref effector); } else { Bits32 bits = chain.ParamsOverride.Params.Bits; chain.ParamsOverride.Params.Bits = Params.Bits; bone.Instance.AccumulateTarget(ref chain.ParamsOverride.Params, ref effector); chain.ParamsOverride.Params.Bits = bits; } } } }
public bool Intersects(ref BoingEffector.Params effector) { return (effector.Bits.IsBitSet(BoingWork.EffectorFlags.ContinuousMotion) ? Intersects ( FromPoints ( effector.PrevPosition, effector.CurrPosition ).Expand(effector.Radius) ) : Intersects ( FromPoints ( effector.CurrPosition ).Expand(effector.Radius) )); }
public void AccumulateTarget(ref BoingEffector.Params effector) { Instance.AccumulateTarget(ref this, ref effector); }
public void AccumulateTarget(ref Params p, ref BoingEffector.Params effector) { Vector3 effectRefPos = effector.Bits.IsBitSet(BoingWork.EffectorFlags.ContinuousMotion) ? VectorUtil.GetClosestPointOnSegment(PositionOrigin, effector.PrevPosition, effector.CurrPosition) : effector.CurrPosition; Vector3 deltaPos = PositionOrigin - effectRefPos; Vector3 deltaPos3D = deltaPos; if (p.Bits.IsBitSet(ReactorFlags.TwoDDistanceCheck)) { switch (p.TwoDPlane) { case TwoDPlaneEnum.XY: deltaPos.z = 0.0f; break; case TwoDPlaneEnum.XZ: deltaPos.y = 0.0f; break; case TwoDPlaneEnum.YZ: deltaPos.x = 0.0f; break; } } bool inRange = Mathf.Abs(deltaPos.x) <= effector.Radius && Mathf.Abs(deltaPos.y) <= effector.Radius && Mathf.Abs(deltaPos.z) <= effector.Radius && deltaPos.sqrMagnitude <= effector.Radius * effector.Radius; if (!inRange) { return; } float deltaDist = deltaPos.magnitude; float tDeltaDist = effector.Radius - effector.FullEffectRadius > MathUtil.Epsilon ? 1.0f - Mathf.Clamp01((deltaDist - effector.FullEffectRadius) / (effector.Radius - effector.FullEffectRadius)) : 1.0f; Vector3 upWsPos = m_upWs; Vector3 upWsRot = m_upWs; Vector3 deltaDirPos = VectorUtil.NormalizeSafe(deltaPos3D, m_upWs); Vector3 deltaDirRot = deltaDirPos; if (p.Bits.IsBitSet(ReactorFlags.TwoDPositionInfluence)) { switch (p.TwoDPlane) { case TwoDPlaneEnum.XY: deltaDirPos.z = 0.0f; upWsPos.z = 0.0f; break; case TwoDPlaneEnum.XZ: deltaDirPos.y = 0.0f; upWsPos.y = 0.0f; break; case TwoDPlaneEnum.YZ: deltaDirPos.x = 0.0f; upWsPos.x = 0.0f; break; } if (upWsPos.sqrMagnitude < MathUtil.Epsilon) { switch (p.TwoDPlane) { case TwoDPlaneEnum.XY: upWsPos = Vector3.up; break; case TwoDPlaneEnum.XZ: upWsPos = Vector3.forward; break; case TwoDPlaneEnum.YZ: upWsPos = Vector3.up; break; } } else { upWsPos.Normalize(); } deltaDirPos = VectorUtil.NormalizeSafe(deltaDirPos, upWsPos); } if (p.Bits.IsBitSet(ReactorFlags.TwoDRotationInfluence)) { switch (p.TwoDPlane) { case TwoDPlaneEnum.XY: deltaDirRot.z = 0.0f; upWsRot.z = 0.0f; break; case TwoDPlaneEnum.XZ: deltaDirRot.y = 0.0f; upWsRot.y = 0.0f; break; case TwoDPlaneEnum.YZ: deltaDirRot.x = 0.0f; upWsRot.x = 0.0f; break; } if (upWsRot.sqrMagnitude < MathUtil.Epsilon) { switch (p.TwoDPlane) { case TwoDPlaneEnum.XY: upWsRot = Vector3.up; break; case TwoDPlaneEnum.XZ: upWsRot = Vector3.forward; break; case TwoDPlaneEnum.YZ: upWsRot = Vector3.up; break; } } else { upWsRot.Normalize(); } deltaDirRot = VectorUtil.NormalizeSafe(deltaDirRot, upWsRot); } if (p.Bits.IsBitSet(ReactorFlags.EnablePositionEffect)) { Vector3 moveVec = tDeltaDist * p.MoveReactionMultiplier * effector.MoveDistance * deltaDirPos; PositionTarget += moveVec; PositionSpring.Velocity += tDeltaDist * p.LinearImpulseMultiplier * effector.LinearImpulse * effector.LinearVelocityDir; } if (p.Bits.IsBitSet(ReactorFlags.EnableRotationEffect)) { Vector3 rotAxis = VectorUtil.NormalizeSafe(Vector3.Cross(upWsRot, deltaDirRot), VectorUtil.FindOrthogonal(upWsRot)); Vector3 rotVec = tDeltaDist * p.RotationReactionMultiplier * effector.RotateAngle * rotAxis; RotationTarget += QuaternionUtil.ToVector4(QuaternionUtil.FromAngularVector(rotVec)); Vector3 angularImpulseDir = VectorUtil.NormalizeSafe(Vector3.Cross(effector.LinearVelocityDir, deltaDirRot - 0.01f * Vector3.up), rotAxis); float angularImpulseMag = tDeltaDist * p.AngularImpulseMultiplier * effector.AngularImpulse; Vector4 angularImpulseDirQuat = QuaternionUtil.ToVector4(QuaternionUtil.FromAngularVector(angularImpulseDir)); RotationSpring.VelocityVec += angularImpulseMag * angularImpulseDirQuat; } ++m_numEffectors; }
internal static void UpdateReactorsLateUpdate ( Dictionary <int, BoingEffector> effectorMap, Dictionary <int, BoingReactor> reactorMap, Dictionary <int, BoingReactorField> fieldMap, Dictionary <int, BoingReactorFieldCPUSampler> cpuSamplerMap ) { float dt = Time.deltaTime; // gather reactor job if (s_reactorJobNeedsGather) { Profiler.BeginSample("Gather Reactor Job"); if (s_aEffectors.Length > 0 && s_aReactorExecParams.Length > 0) { s_hReactorJob.Complete(); Profiler.BeginSample("Pull Data"); for (int iReactor = 0, n = s_aReactorExecParams.Length; iReactor < n; ++iReactor) { s_aReactorExecOutput[iReactor].PullResults(reactorMap); } Profiler.EndSample(); } s_aEffectors.Dispose(); s_aReactorExecParams.Dispose(); s_aReactorExecOutput.Dispose(); Profiler.EndSample(); s_reactorJobNeedsGather = false; } // kick reactor job Profiler.BeginSample("Kick Reactor Job"); s_aEffectors = new NativeArray <BoingEffector.Params>(effectorMap.Count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); s_aReactorExecParams = new NativeArray <BoingWork.Params>(reactorMap.Count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); s_aReactorExecOutput = new NativeArray <BoingWork.Output>(reactorMap.Count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); { Profiler.BeginSample("Push Data"); int iEffector = 0; var eep = new BoingEffector.Params(); foreach (var itEffector in effectorMap) { var effector = itEffector.Value; eep.Fill(itEffector.Value); s_aEffectors[iEffector++] = eep; } int iReactor = 0; foreach (var itReactor in reactorMap) { var reactor = itReactor.Value; reactor.PrepareExecute(); s_aReactorExecParams[iReactor++] = reactor.Params; } Profiler.EndSample(); } if (s_aEffectors.Length > 0 && s_aReactorExecParams.Length > 0) { var job = new ReactorJob() { Effectors = s_aEffectors, Params = s_aReactorExecParams, Output = s_aReactorExecOutput, DeltaTime = dt }; s_hReactorJob = job.Schedule(s_aReactorExecParams.Length, 32); JobHandle.ScheduleBatchedJobs(); } Profiler.EndSample(); Profiler.BeginSample("Update Fields (CPU)"); foreach (var itField in fieldMap) { var field = itField.Value; switch (field.HardwareMode) { case BoingReactorField.HardwareModeEnum.CPU: field.ExecuteCpu(dt); break; } } Profiler.EndSample(); Profiler.BeginSample("Update Field Samplers"); foreach (var itSampler in cpuSamplerMap) { var sampler = itSampler.Value; sampler.SampleFromField(); } Profiler.EndSample(); s_reactorJobNeedsGather = true; }