本文整理汇总了C#中Quaternion.Rotate方法的典型用法代码示例。如果您正苦于以下问题:C# Quaternion.Rotate方法的具体用法?C# Quaternion.Rotate怎么用?C# Quaternion.Rotate使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Quaternion
的用法示例。
在下文中一共展示了Quaternion.Rotate方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: RotateAt
public void RotateAt(Point3D pt, Quaternion q)
{
// transform origin to pt
var copy = Points.Copy();
copy.Offset(-pt.X, -pt.Y, -pt.Z);
center.Offset(-pt.X, -pt.Y, -pt.Z);
// rotate
q.Rotate(copy);
// TODO:???
q.Rotate(ref center);
// transform to original origin
center.Offset(pt.X, pt.Y, pt.Z);
copy.Offset(pt.X, pt.Y, pt.Z);
Points = copy;
}
示例2: PreUpdateField
public override void PreUpdateField(Vector3 position, Quaternion rotation, Vector3 size)
{
fieldSize = size;
fieldPosition = position;
fieldRotation = rotation;
inverseRotation = new Quaternion(-rotation.X, -rotation.Y, -rotation.Z, rotation.W);
mainAxis = new Vector3(0, 1, 0);
rotation.Rotate(ref mainAxis);
}
示例3: AddCornerToAabb
private static void AddCornerToAabb(Vector3 corner, Quaternion rotation, ref Vector3 min, ref Vector3 max)
{
rotation.Rotate(ref corner);
min.X = (corner.X < min.X) ? corner.X : min.X;
min.Y = (corner.Y < min.Y) ? corner.Y : min.Y;
min.Z = (corner.Z < min.Z) ? corner.Z : min.Z;
max.X = (corner.X > max.X) ? corner.X : max.X;
max.Y = (corner.Y > max.Y) ? corner.Y : max.Y;
max.Z = (corner.Z > max.Z) ? corner.Z : max.Z;
}
示例4: BuildVertexBuffer
/// <inheritdoc />
public override unsafe int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter)
{
// Get all the required particle fields
var positionField = sorter.GetField(ParticleFields.Position);
if (!positionField.IsValid())
return 0;
var sizeField = sorter.GetField(ParticleFields.Size);
var orderField = sorter.GetField(ParticleFields.Order);
// Check if the draw space is identity - in this case we don't need to transform the position, scale and rotation vectors
// ReSharper disable once CompareOfFloatsByEqualityOperator
var trsIdentity = (spaceScale == 1f);
trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
trsIdentity = trsIdentity && (spaceRotation.Equals(Quaternion.Identity));
var ribbonizer = new Ribbonizer(this, currentTotalParticles, currentQuadsPerParticle);
var renderedParticles = 0;
bufferState.StartOver();
uint oldOrderValue = 0;
foreach (var particle in sorter)
{
if (orderField.IsValid())
{
var orderValue = (*((uint*)particle[orderField]));
if ((orderValue >> SpawnOrderConst.GroupBitOffset) != (oldOrderValue >> SpawnOrderConst.GroupBitOffset))
{
ribbonizer.Ribbonize(ref bufferState, invViewX, invViewY, QuadsPerParticle);
ribbonizer.RibbonSplit();
}
oldOrderValue = orderValue;
}
var centralPos = particle.Get(positionField);
var particleSize = sizeField.IsValid() ? particle.Get(sizeField) : 1f;
if (!trsIdentity)
{
spaceRotation.Rotate(ref centralPos);
centralPos = centralPos * spaceScale + spaceTranslation;
particleSize *= spaceScale;
}
ribbonizer.AddParticle(ref centralPos, particleSize);
renderedParticles++;
}
ribbonizer.Ribbonize(ref bufferState, invViewX, invViewY, QuadsPerParticle);
ribbonizer.Free();
var vtxPerShape = 4 * QuadsPerParticle;
return renderedParticles * vtxPerShape;
}
示例5: BuildVertexBuffer
/// <inheritdoc />
public override unsafe int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter)
{
// Update the curve samplers if required
base.BuildVertexBuffer(ref bufferState, invViewX, invViewY, ref spaceTranslation, ref spaceRotation, spaceScale, ref sorter);
// Get all required particle fields
var positionField = sorter.GetField(ParticleFields.Position);
if (!positionField.IsValid())
return 0;
var sizeField = sorter.GetField(ParticleFields.Size);
var lifeField = sorter.GetField(ParticleFields.Life);
var angleField = sorter.GetField(ParticleFields.Angle);
var hasAngle = angleField.IsValid() || (SamplerRotation != null);
// Check if the draw space is identity - in this case we don't need to transform the position, scale and rotation vectors
var trsIdentity = (spaceScale == 1f);
trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
trsIdentity = trsIdentity && (spaceRotation.Equals(Quaternion.Identity));
var renderedParticles = 0;
var posAttribute = bufferState.GetAccessor(VertexAttributes.Position);
var texAttribute = bufferState.GetAccessor(bufferState.DefaultTexCoords);
foreach (var particle in sorter)
{
var centralPos = GetParticlePosition(particle, positionField, lifeField);
var particleSize = GetParticleSize(particle, sizeField, lifeField);
if (!trsIdentity)
{
spaceRotation.Rotate(ref centralPos);
centralPos = centralPos * spaceScale + spaceTranslation;
particleSize *= spaceScale;
}
// Use half size to make a Size = 1 result in a Billboard of 1m x 1m
var unitX = invViewX * (particleSize * 0.5f);
var unitY = invViewY * (particleSize * 0.5f);
// Particle rotation. Positive value means clockwise rotation.
if (hasAngle)
{
var rotationAngle = GetParticleRotation(particle, angleField, lifeField);
var cosA = (float)Math.Cos(rotationAngle);
var sinA = (float)Math.Sin(rotationAngle);
var tempX = unitX * cosA - unitY * sinA;
unitY = unitY * cosA + unitX * sinA;
unitX = tempX;
}
// vertex.Size = particleSize;
const float Sqrt3Half = 0.86602540378f;
unitY *= Sqrt3Half;
var halfX = unitX * 0.5f;
var particlePos = centralPos - halfX + unitY;
var uvCoord = new Vector2(0.25f, 0.5f - Sqrt3Half * 0.5f);
// Upper half
// 0f 0f
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 0f
particlePos += unitX;
uvCoord.X = 0.75f;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 1f
particlePos += halfX;
particlePos -= unitY;
uvCoord.X = 1;
uvCoord.Y = 0.5f;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 0f 1f
particlePos -= unitX * 2;
uvCoord.X = 0;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// Upper half
//.........这里部分代码省略.........
示例6: TryGetDebugDrawShape
public override bool TryGetDebugDrawShape(out DebugDrawShape debugDrawShape, out Vector3 translation, out Quaternion rotation, out Vector3 scale)
{
if (!DebugDraw)
return base.TryGetDebugDrawShape(out debugDrawShape, out translation, out rotation, out scale);
debugDrawShape = DebugDrawShape.Cube;
rotation = WorldRotation;
scale = (DirectionMax - DirectionMin);
translation = (DirectionMax + DirectionMin) * 0.5f * WorldScale;
scale *= WorldScale;
rotation.Rotate(ref translation);
translation += WorldPosition;
return true;
}
示例7: BuildVertexBuffer
/// <inheritdoc />
public unsafe override int BuildVertexBuffer(ParticleVertexBuilder vtxBuilder, Vector3 invViewX, Vector3 invViewY,
ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ParticleSorter sorter)
{
// Get all the required particle fields
var positionField = sorter.GetField(ParticleFields.Position);
if (!positionField.IsValid())
return 0;
var sizeField = sorter.GetField(ParticleFields.Size);
var directionField = sorter.GetField(ParticleFields.Direction);
// Check if the draw space is identity - in this case we don't need to transform the position, scale and rotation vectors
var trsIdentity = (spaceScale == 1f);
trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
trsIdentity = trsIdentity && (spaceRotation.Equals(Quaternion.Identity));
var renderedParticles = 0;
vtxBuilder.RestartBuffer();
uint oldOrderValue = 0;
var orderField = sorter.GetField(ParticleFields.Order);
foreach (var particle in sorter)
{
if (orderField.IsValid())
{
var orderValue = (*((uint*)particle[orderField]));
if ((orderValue >> 16) != (oldOrderValue >> 16))
{
ribbonizer.Ribbonize(vtxBuilder, QuadsPerParticle);
ribbonizer.RibbonSplit();
}
oldOrderValue = orderValue;
}
var centralPos = particle.Get(positionField);
var particleSize = sizeField.IsValid() ? particle.Get(sizeField) : 1f;
var particleDirection = directionField.IsValid() ? particle.Get(directionField) * particleSize : new Vector3(0f, particleSize, 0f);
if (!trsIdentity)
{
spaceRotation.Rotate(ref centralPos);
centralPos = centralPos * spaceScale + spaceTranslation;
// Direction
spaceRotation.Rotate(ref particleDirection);
particleDirection *= spaceScale;
}
ribbonizer.AddParticle(ref centralPos, ref particleDirection);
renderedParticles++;
}
ribbonizer.Ribbonize(vtxBuilder, QuadsPerParticle);
var vtxPerShape = 4 * QuadsPerParticle;
return renderedParticles * vtxPerShape;
}
示例8: BuildVertexBuffer
/// <inheritdoc />
public unsafe override int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter)
{
// Update the curve samplers if required
base.BuildVertexBuffer(ref bufferState, invViewX, invViewY, ref spaceTranslation, ref spaceRotation, spaceScale, ref sorter);
// Get all required particle fields
var positionField = sorter.GetField(ParticleFields.Position);
if (!positionField.IsValid())
return 0;
var lifeField = sorter.GetField(ParticleFields.Life);
var sizeField = sorter.GetField(ParticleFields.Size);
var rotField = sorter.GetField(ParticleFields.Quaternion);
var hasRotation = rotField.IsValid() || (SamplerRotation != null);
// Check if the draw space is identity - in this case we don't need to transform the position, scale and rotation vectors
var trsIdentity = (spaceScale == 1f);
trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
trsIdentity = trsIdentity && (spaceRotation.Equals(Quaternion.Identity));
var renderedParticles = 0;
var posAttribute = bufferState.GetAccessor(VertexAttributes.Position);
var texAttribute = bufferState.GetAccessor(bufferState.DefaultTexCoords);
foreach (var particle in sorter)
{
var centralPos = GetParticlePosition(particle, positionField, lifeField);
var particleSize = GetParticleSize(particle, sizeField, lifeField);
var unitX = new Vector3(1, 0, 0);
var unitY = new Vector3(0, 0, 1);
if (hasRotation)
{
var particleRotation = GetParticleRotation(particle, rotField, lifeField);
particleRotation.Rotate(ref unitX);
particleRotation.Rotate(ref unitY);
}
// The TRS matrix is not an identity, so we need to transform the quad
if (!trsIdentity)
{
spaceRotation.Rotate(ref centralPos);
centralPos = centralPos * spaceScale + spaceTranslation;
particleSize *= spaceScale;
spaceRotation.Rotate(ref unitX);
spaceRotation.Rotate(ref unitY);
}
// Use half size to make a Size = 1 result in a Billboard of 1m x 1m
unitX *= (particleSize * 0.5f);
unitY *= (particleSize * 0.5f);
var particlePos = centralPos - unitX + unitY;
var uvCoord = new Vector2(0, 0);
// 0f 0f
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 0f
particlePos += unitX * 2;
uvCoord.X = 1;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 1f
particlePos -= unitY * 2;
uvCoord.Y = 1;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 0f 1f
particlePos -= unitX * 2;
uvCoord.X = 0;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
renderedParticles++;
}
var vtxPerShape = 4 * QuadsPerParticle;
return renderedParticles * vtxPerShape;
}
示例9: GetDistanceToCenter
public override float GetDistanceToCenter(
Vector3 particlePosition, Vector3 particleVelocity,
out Vector3 alongAxis, out Vector3 aroundAxis, out Vector3 awayAxis)
{
// Along - following the main axis
alongAxis = mainAxis;
// Toward - tawards the main axis
awayAxis = particlePosition - fieldPosition;
awayAxis.Normalize();
// Around - around the main axis, following the right hand rule
aroundAxis = Vector3.Cross(alongAxis, awayAxis);
particlePosition -= fieldPosition;
var inverseRotation = new Quaternion(-fieldRotation.X, -fieldRotation.Y, -fieldRotation.Z, fieldRotation.W);
inverseRotation.Rotate(ref particlePosition);
particlePosition /= fieldSize;
// Start of code for Cube
var maxDist = Math.Max(Math.Abs(particlePosition.X) / halfSideX, Math.Abs(particlePosition.Y) / halfSideY);
maxDist = Math.Max(maxDist, Math.Abs(particlePosition.Z) / halfSideZ);
// End of code for Cube
return maxDist;
}
示例10: TryGetDebugDrawShape
/// <inheritdoc/>
public override bool TryGetDebugDrawShape(out DebugDrawShape debugDrawShape, out Vector3 translation, out Quaternion rotation, out Vector3 scale)
{
if (!DebugDraw)
return base.TryGetDebugDrawShape(out debugDrawShape, out translation, out rotation, out scale);
rotation = Quaternion.Identity;
scale = new Vector3(1, 1, 1);
translation = new Vector3(0, 0, 0);
debugDrawShape = FieldShape?.GetDebugDrawShape(out translation, out rotation, out scale) ?? DebugDrawShape.None;
rotation *= WorldRotation;
scale *= WorldScale;
translation *= WorldScale;
rotation.Rotate(ref translation);
translation += WorldPosition;
return true;
}
示例11: BuildVertexBuffer
/// <inheritdoc />
public unsafe override int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter)
{
// Update the curve samplers if required
base.BuildVertexBuffer(ref bufferState, invViewX, invViewY, ref spaceTranslation, ref spaceRotation, spaceScale, ref sorter);
// Get all the required particle fields
var positionField = sorter.GetField(ParticleFields.Position);
if (!positionField.IsValid())
return 0;
var lifeField = sorter.GetField(ParticleFields.Life);
var sizeField = sorter.GetField(ParticleFields.Size);
var directionField = sorter.GetField(ParticleFields.Direction);
// Check if the draw space is identity - in this case we don't need to transform the position, scale and rotation vectors
var trsIdentity = (spaceScale == 1f);
trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
trsIdentity = trsIdentity && (spaceRotation.Equals(Quaternion.Identity));
var renderedParticles = 0;
var posAttribute = bufferState.GetAccessor(VertexAttributes.Position);
var texAttribute = bufferState.GetAccessor(bufferState.DefaultTexCoords);
Vector3 invViewZ;
Vector3.Cross(ref invViewX, ref invViewY, out invViewZ);
invViewZ.Normalize();
foreach (var particle in sorter)
{
var centralPos = GetParticlePosition(particle, positionField, lifeField);
var centralOffset = (directionField.IsValid()) ? particle.Get(directionField) : new Vector3(0, 1, 0);
var particleSize = GetParticleSize(particle, sizeField, lifeField);
if (!trsIdentity)
{
spaceRotation.Rotate(ref centralPos);
centralPos = centralPos * spaceScale + spaceTranslation;
spaceRotation.Rotate(ref centralOffset);
centralOffset = centralOffset * spaceScale;
particleSize *= spaceScale;
}
var unitX = invViewX;
var unitY = invViewY;
{
var centralAxis = centralOffset;
float dotZ;
Vector3.Dot(ref centralAxis, ref invViewZ, out dotZ);
centralAxis -= invViewZ*dotZ;
centralAxis.Normalize();
float dotX;
Vector3.Dot(ref centralAxis, ref unitX, out dotX);
float dotY;
Vector3.Dot(ref centralAxis, ref unitY, out dotY);
unitX = unitX*dotY - unitY*dotX;
unitX.Normalize();
unitY = centralOffset;
}
// Use half size to make a Size = 1 result in a Billboard of 1m x 1m
unitX *= (particleSize * 0.5f);
if (ScaleLength)
{
unitY *= (LengthFactor * particleSize * 0.5f);
}
else
{
unitY *= (LengthFactor * 0.5f);
}
var particlePos = centralPos - unitX + unitY;
var uvCoord = new Vector2(0, 0);
// 0f 0f
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 0f
particlePos += unitX * 2;
uvCoord.X = 1;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 1f
//.........这里部分代码省略.........
示例12: BuildVertexBuffer
/// <inheritdoc />
public override unsafe int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter)
{
// Step 1 - get all required fields to build the particle shapes. Some fields may not exist if no initializer or updater operates on them
// In that case we just decide on a default value for that field and skip the update
var positionField = sorter.GetField(ParticleFields.Position);
if (!positionField.IsValid())
return 0; // We can't display the particles without position. All other fields are optional
var sizeField = sorter.GetField(ParticleFields.Size);
var angleField = sorter.GetField(ParticleFields.Angle);
var hasAngle = angleField.IsValid();
var rectField = sorter.GetField(CustomParticleFields.RectangleXY);
var isRectangle = rectField.IsValid();
// In case of Local space particles they are simulated in local emitter space, but drawn in world space
// If the draw space is identity (i.e. simulation space = draw space) skip transforming the particle's location later
var trsIdentity = (spaceScale == 1f);
trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
trsIdentity = trsIdentity && (spaceRotation.Equals(new Quaternion(0, 0, 0, 1)));
// Custom feature - fix the Y axis to always point up in world space rather than screen space
if (FixYAxis)
{
invViewY = new Vector3(0, 1, 0);
invViewX.Y = 0;
invViewX.Normalize();
}
var renderedParticles = 0;
var posAttribute = bufferState.GetAccessor(VertexAttributes.Position);
var texAttribute = bufferState.GetAccessor(bufferState.DefaultTexCoords);
foreach (var particle in sorter)
{
var centralPos = particle.Get(positionField);
var particleSize = sizeField.IsValid() ? particle.Get(sizeField) : 1f;
if (!trsIdentity)
{
spaceRotation.Rotate(ref centralPos);
centralPos = centralPos * spaceScale + spaceTranslation;
particleSize *= spaceScale;
}
var unitX = invViewX * particleSize;
var unitY = invViewY * particleSize;
if (isRectangle)
{
var rectSize = particle.Get(rectField);
unitX *= rectSize.X;
unitY *= rectSize.Y;
}
// Particle rotation. Positive value means clockwise rotation.
if (hasAngle)
{
var rotationAngle = particle.Get(angleField);
var cosA = (float)Math.Cos(rotationAngle);
var sinA = (float)Math.Sin(rotationAngle);
var tempX = unitX * cosA - unitY * sinA;
unitY = unitY * cosA + unitX * sinA;
unitX = tempX;
}
var particlePos = centralPos - unitX + unitY;
var uvCoord = new Vector2(0, 0);
// 0f 0f
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 0f
particlePos += unitX * 2;
uvCoord.X = 1;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 1f 1f
particlePos -= unitY * 2;
uvCoord.Y = 1;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
bufferState.NextVertex();
// 0f 1f
particlePos -= unitX * 2;
uvCoord.X = 0;
bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
//.........这里部分代码省略.........
示例13: GetLocalTransform
/// <inheritdoc/>
protected override void GetLocalTransform(JointBody body, out Vector3 position, out Quaternion rotation)
{
position = commonData.positions[(int)body];
rotation = commonData.rotations[(int)body];
Rigidbody rigidbody = commonData.bodies[(int)body];
if (rigidbody == null) // Get world space transform if not relative to any body
{
Quaternion worldRot = SceneObject.Rotation;
rotation = worldRot * rotation;
position = worldRot.Rotate(position) + SceneObject.Position;
}
else
{
// Use only the offset for positioning, but for rotation use both the offset and target SO rotation.
// (Needed because we need to rotate the joint SO in order to orient the slider direction, so we need an
// additional transform that allows us to orient the object)
position = rotation.Rotate(position);
rotation = (rigidbody.SceneObject.Rotation*rotation).Inverse*SceneObject.Rotation;
}
}
示例14: TryGetDebugDrawShape
public override bool TryGetDebugDrawShape(out DebugDrawShape debugDrawShape, out Vector3 translation, out Quaternion rotation, out Vector3 scale)
{
if (!DebugDraw)
return base.TryGetDebugDrawShape(out debugDrawShape, out translation, out rotation, out scale);
debugDrawShape = DebugDrawShape.Cone;
rotation = WorldRotation;
scale = new Vector3(1, -1, 1);
translation = new Vector3(0, Strength + 1, 0);
var radiusToStrength = (float)Math.Tan((Angle * Math.PI / 180f)) * (Strength + 1);
var coneScale = new Vector3(radiusToStrength, Strength + 1, radiusToStrength);
scale *= WorldScale * coneScale;
rotation.Rotate(ref translation);
translation += WorldPosition;
return true;
}