public void CalculateStartPosition(float elapsedTime, MatrixD worldMatrix, Vector3 userAxisScale, float userScale, out Vector3D startOffset, out Vector3D startPosition) { Vector3 currentOffsetUntransformed; Offset.GetInterpolatedValue <Vector3>(elapsedTime, out currentOffsetUntransformed); Vector3 currentRotation; Rotation.GetInterpolatedValue <Vector3>(elapsedTime, out currentRotation); float currentSize; Size.GetInterpolatedValue <float>(elapsedTime, out currentSize); currentSize *= MyUtils.GetRandomFloat(RadiusMin, RadiusMax) * userScale; Vector3 currentAxisScale = userAxisScale * AxisScale; Vector3 localPos = Vector3.Zero; Vector3D worldOffset; Vector3D.Transform(ref currentOffsetUntransformed, ref worldMatrix, out worldOffset); switch (Type) { case MyParticleEmitterType.Point: localPos = Vector3.Zero; break; case MyParticleEmitterType.Line: localPos = Vector3.Forward * MyUtils.GetRandomFloat(0.0f, currentSize) * currentAxisScale; break; case MyParticleEmitterType.Sphere: if (LimitAngle.GetKeysCount() > 0) { float angle; LimitAngle.GetInterpolatedValue <float>(elapsedTime, out angle); angle = MathHelper.ToRadians(angle); localPos = MyUtils.GetRandomVector3MaxAngle(angle) * currentSize * currentAxisScale; } else { localPos = MyUtils.GetRandomVector3Normalized() * currentSize * currentAxisScale; } break; case MyParticleEmitterType.Box: float currentSizeHalf = currentSize * 0.5f; localPos = new Vector3( MyUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf), MyUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf), MyUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf) ) * currentAxisScale; break; case MyParticleEmitterType.Hemisphere: localPos = MyUtils.GetRandomVector3HemisphereNormalized(Vector3.Forward) * currentSize * currentAxisScale; break; case MyParticleEmitterType.Circle: localPos = MyUtils.GetRandomVector3CircleNormalized() * currentSize * currentAxisScale; break; default: System.Diagnostics.Debug.Assert(false); break; } //if ((LimitAngle < 90 && (Type == MyParticleEmitterType.Hemisphere)) || // (LimitAngle < 180 && ((Type == MyParticleEmitterType.Sphere) || (Type == MyParticleEmitterType.Box)))) //{ // var angleScaleFactor = Type == MyParticleEmitterType.Hemisphere ? LimitAngle / 90.0f : LimitAngle / 180.0f; // var normalizedPos = Vector3.Normalize(localPos); // var dotProduct = Vector3.Dot(Vector3.Forward, normalizedPos); // var currentAngle = (float)Math.Acos(dotProduct); // var finalAngle = currentAngle * angleScaleFactor; // var rotationAxis = Vector3.Cross(Vector3.Forward,localPos); // var rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, finalAngle - currentAngle); // Vector3.TransformNormal(ref localPos, ref rotationMatrix, out localPos); //} if (currentRotation.LengthSquared() > 0) { Matrix rotationMatrix = Matrix.CreateRotationX(MathHelper.ToRadians(currentRotation.X)); rotationMatrix = rotationMatrix * Matrix.CreateRotationY(MathHelper.ToRadians(currentRotation.Y)); rotationMatrix = rotationMatrix * Matrix.CreateRotationZ(MathHelper.ToRadians(currentRotation.Z)); Vector3.TransformNormal(ref localPos, ref rotationMatrix, out localPos); } Vector3D worldPos; if (DirToCamera) { if (MyUtils.IsZero(MyTransparentGeometry.Camera.Forward)) { startPosition = Vector3.Zero; startOffset = Vector3.Zero; return; } MatrixD WorldView = worldMatrix * MyTransparentGeometry.CameraView; WorldView.Translation += currentOffsetUntransformed; MatrixD newWorld = WorldView * MatrixD.Invert(MyTransparentGeometry.CameraView); Vector3D dir = MyTransparentGeometry.Camera.Translation - newWorld.Translation; dir.Normalize(); MatrixD matrix = MatrixD.CreateFromDir(dir); matrix.Translation = newWorld.Translation; Vector3D.Transform(ref localPos, ref matrix, out worldPos); startOffset = newWorld.Translation; startPosition = worldPos; } else { Vector3D.TransformNormal(ref localPos, ref worldMatrix, out worldPos); startOffset = worldOffset; startPosition = worldOffset + worldPos; } }
public static Vector3D Transform(this Vector3D vector, SerializableBlockOrientation orientation) { var matrix = MatrixD.CreateFromDir(Base6Directions.GetVector(orientation.Forward), Base6Directions.GetVector(orientation.Up)); return(Vector3D.Transform(vector, matrix)); }