/// <summary> /// Gets output for angle. /// </summary> /// <param name="translation">Translation.</param> /// <param name="parameter">Parameter.</param> /// <param name="particles">Particles.</param> /// <param name="particleIndex">Index of particle.</param> /// <returns>Output value.</returns> private float GetOutputAngle( Vector2 translation, CubismParameter parameter, CubismPhysicsParticle[] particles, int particleIndex ) { var parentGravity = -CubismPhysics.Gravity; if (CubismPhysics.UseAngleCorrection && (particleIndex - 1) != 0) { parentGravity = particles[particleIndex - 2].Position - particles[particleIndex - 1].Position; } translation.y *= -1.0f; var outputValue = CubismPhysicsMath.DirectionToRadian(-parentGravity, -translation); outputValue = (((-translation.x) - (-parentGravity.x)) > 0.0f) ? -outputValue : outputValue; if (IsInverted) { outputValue *= -1.0f; } return(outputValue); }
/// <summary> /// Gets Normalized parameter value from input rotation. /// </summary> /// <param name="targetTranslation">Result of translation.</param> /// <param name="targetAngle">Result of rotation.</param> /// <param name="parameter">Parameter.</param> /// <param name="normalization">Normalized components.</param> /// <param name="weight">Weight.</param> private void GetInputAngleFromNormalizedParameterValue( ref Vector2 targetTranslation, ref float targetAngle, CubismParameter parameter, CubismPhysicsNormalization normalization, float weight ) { targetAngle += CubismPhysicsMath.Normalize( parameter, normalization.Angle.Minimum, normalization.Angle.Maximum, normalization.Angle.Default, IsInverted ) * weight; }
/// <summary> /// Gets output for angle. /// </summary> /// <param name="translation">Translation.</param> /// <param name="parameter">Parameter.</param> /// <param name="particles">Particles.</param> /// <param name="particleIndex">Index of particle.</param> /// <param name="gravity">Gravity.</param> /// <returns>Output value.</returns> private float GetOutputAngle( Vector2 translation, CubismParameter parameter, CubismPhysicsParticle[] particles, int particleIndex, Vector2 gravity ) { var parentGravity = Vector2.zero; if (CubismPhysics.UseAngleCorrection) { if (particleIndex < 2) { parentGravity = gravity; parentGravity.y *= -1.0f; } else { parentGravity = particles[particleIndex - 1].Position - particles[particleIndex - 2].Position; } } else { parentGravity = gravity; parentGravity.y *= -1.0f; } var outputValue = CubismPhysicsMath.DirectionToRadian(parentGravity, translation); if (IsInverted) { outputValue *= -1.0f; } return(outputValue); }
/// <summary> /// Evalute rig in every frame. /// </summary> /// <param name="deltaTime"></param> public void Evaluate(float deltaTime) { var totalAngle = 0.0f; var totalTranslation = Vector2.zero; for (var i = 0; i < Input.Length; ++i) { var weight = Input[i].Weight / CubismPhysics.MaximumWeight; if (Input[i].Source == null) { Input[i].Source = Rig.Controller.Parameters.FindById(Input[i].SourceId); } var parameter = Input[i].Source; Input[i].GetNormalizedParameterValue( ref totalTranslation, ref totalAngle, parameter, Normalization, weight ); } var radAngle = CubismPhysicsMath.DegreesToRadian(-totalAngle); var translationX = totalTranslation.x; var translationY = totalTranslation.y; totalTranslation.x = (translationX * Mathf.Cos(radAngle) - translationY * Mathf.Sin(radAngle)); totalTranslation.y = (translationX * Mathf.Sin(radAngle) + translationY * Mathf.Cos(radAngle)); UpdateParticles( Particles, totalTranslation, totalAngle, CubismPhysics.Wind, CubismPhysics.MovementThreshold * Normalization.Position.Maximum, deltaTime ); for (var i = 0; i < Output.Length; ++i) { var particleIndex = Output[i].ParticleIndex; if (particleIndex < 1 || particleIndex >= Particles.Length) { break; } if (Output[i].Destination == null) { Output[i].Destination = Rig.Controller.Parameters.FindById(Output[i].DestinationId); } var parameter = Output[i].Destination; var translation = Particles[particleIndex - 1].Position - Particles[particleIndex].Position; var outputValue = Output[i].GetValue( translation, parameter, Particles, particleIndex ); UpdateOutputParameterValue(parameter, outputValue, Output[i]); } }
/// <summary> /// Updates particles in every frame. /// </summary> /// <param name="strand">Particles.</param> /// <param name="totalTranslation">Total translation.</param> /// <param name="totalAngle">Total angle.</param> /// <param name="wind">Direction of wind.</param> /// <param name="thresholdValue">Value of threshold.</param> /// <param name="deltaTime">Time of delta.</param> private void UpdateParticles( CubismPhysicsParticle[] strand, Vector2 totalTranslation, float totalAngle, Vector2 wind, float thresholdValue, float deltaTime ) { strand[0].Position = totalTranslation; var totalRadian = CubismPhysicsMath.DegreesToRadian(totalAngle); var currentGravity = CubismPhysicsMath.RadianToDirection(totalRadian); currentGravity.Normalize(); for (var i = 1; i < strand.Length; ++i) { strand[i].Force = (currentGravity * strand[i].Acceleration) + wind; strand[i].LastPosition = strand[i].Position; // The Cubism Editor expects 30 FPS so we scale here by 30... var delay = strand[i].Delay * deltaTime * 30.0f; var direction = strand[i].Position - strand[i - 1].Position; var distance = Vector2.Distance(Vector2.zero, direction); var angle = CubismPhysicsMath.DirectionToDegrees(strand[i].LastGravity, currentGravity); var radian = CubismPhysicsMath.DegreesToRadian(angle); radian /= CubismPhysics.AirResistance; direction.x = ((Mathf.Cos(radian) * direction.x) - (direction.y * Mathf.Sin(radian))); direction.y = ((Mathf.Sin(radian) * direction.x) + (direction.y * Mathf.Cos(radian))); direction.Normalize(); strand[i].Position = strand[i - 1].Position + (direction * distance); var velocity = strand[i].Velocity * delay; var force = strand[i].Force * delay * delay; strand[i].Position = strand[i].Position + velocity + force; var newDirection = strand[i].Position - strand[i - 1].Position; newDirection.Normalize(); strand[i].Position = strand[i - 1].Position + newDirection * strand[i].Radius; if (Mathf.Abs(strand[i].Position.x) < thresholdValue) { strand[i].Position.x = 0.0f; } if (delay != 0.0f) { strand[i].Velocity = ((strand[i].Position - strand[i].LastPosition) / delay) * strand[i].Mobility; } else { strand[i].Velocity = Vector2.zero; } strand[i].Force = Vector2.zero; strand[i].LastGravity = currentGravity; } }