Author Topic: Problems with phi in line transformation  (Read 753 times)

I have a StaticShape object using a model sized 1 by 1 by 1 Torque units, which I'm trying to translate and scale to form a line between two points. I've done this successfully using position and rotation when the line is created, but that's a sub-optimal solution since I'd like to do it with setTransform to move an existing line. I have also succeeded doing this with the object scaled on the Z axis (width width lineDistance), albeit that's not viable since Torque Game Engine refuses to render the shape at certain angles when scaled as such.

function StaticShape::transformLine(%this, %a, %b, %size)
{
   if (%size $= "")
   {
      %size = 0.2;
   }

   %vector = vectorNormalize(vectorSub(%b, %a));
   %vector = vectorCross("0 0 1", %vector);

   %v1 = getWord(%vector, 0);
   %v2 = getWord(%vector, 1);
   %v3 = getWord(%vector, 2);

   %theta = mATan(%v3, mSqrt(%v1 * %v1 + %v2 * %v2));
   %phi = -mATan(%v1, %v2);

   %matrix = matrixCreateFromEuler(%theta SPC 0 SPC %phi);
   %position = vectorScale(vectorAdd(%a, %b), 0.5);

   %this.setTransform(%position SPC getWords(%matrix, 3, 6));
   %this.setScale(vectorDist(%a, %b) SPC %size SPC %size);
}


This works correctly for setting the theta rotation, but fails on orienting by phi at all (it stays horizontal at all times). An example can be seen below.



A line is being created between the player object and the top brick on the stack. Notice how it's phi angle is perfectly level, instead of being properly rotated.

For reference, here's the version working with position and rotation.

%vector = vectorNormalize(vectorSub(%b, %a));

%xyz = vectorNormalize(vectorCross("1 0 0", %vector));
%pow = mRadToDeg(mACos(vectorDot("1 0 0", %vector))) * -1;

%obj = new StaticShape() {
   ...
   scale = vectorLen(%offset) SPC %size SPC %size;

   position = vectorScale(vectorAdd(%a, %b), 0.5);
   rotation = %xyz SPC %pow;
};

You can fix the rendering issues by starting out with a smaller shape
Don't have a value < 1 for scale on any axis and it will work

also instead of this
Code: [Select]
%vector = vectorNormalize(vectorSub(%b, %a));

%xyz = vectorNormalize(vectorCross("1 0 0", %vector));
%pow = mRadToDeg(mACos(vectorDot("1 0 0", %vector))) * -1;

%obj = new StaticShape() {
   ...
   scale = vectorLen(%offset) SPC %size SPC %size;

   position = vectorScale(vectorAdd(%a, %b), 0.5);
   rotation = %xyz SPC %pow;
};

try this

Code: [Select]
%vector = vectorNormalize(vectorSub(%b, %a));

%xyz = vectorNormalize(vectorCross("1 0 0", %vector));
%u = mACos(vectorDot("1 0 0", %vector)) * -1; //no mradtodeg

%position = vectorScale(vectorAdd(%a, %b), 0.5);

shape.setTransform(%position SPC %xyz SPC %u);

note I didn't test it

Surprised that works, but thanks.

Code: [Select]
datablock StaticShapeData(CubeShapeData)
{
shapeFile = "./cube/cube.dts";
};

datablock StaticShapeData(CubeCollisionShapeData)
{
shapeFile = "./cube/cube_collision.dts";
};

datablock StaticShapeData(CubeGlowShapeData)
{
shapeFile = "./cube/cube_glow.dts";
};

datablock StaticShapeData(CubeGlowCollisionShapeData)
{
shapeFile = "./cube/cube_glow_collision.dts";
};

datablock StaticShapeData(ConeShapeData)
{
shapeFile = "./cone/cone.dts";
};

datablock StaticShapeData(ConeCollisionShapeData)
{
shapeFile = "./cone/cone_collision.dts";
};

...

function createShape(%dataBlock, %color)
{
if (%dataBlock $= "")
{
%dataBlock = CubeShapeData;
}

%obj = new StaticShape()
{
dataBlock = %dataBlock;
};

MissionCleanup.add(%obj);

if (%color !$= "")
{
%obj.setNodeColor("ALL", %color);
}

return %obj;
}

function StaticShape::transformLine(%this, %a, %b, %size)
{
if (%size $= "")
{
%size = 0.2;
}

%vector = vectorNormalize(vectorSub(%b, %a));

%xyz = vectorNormalize(vectorCross("1 0 0", %vector));
%u = mACos(vectorDot("1 0 0", %vector)) * -1;

%this.setTransform(vectorScale(vectorAdd(%a, %b), 0.5) SPC %xyz SPC %u);
%this.setScale(vectorDist(%a, %b) SPC %size SPC %size);
}

function StaticShape::transformCube(%this, %transform, %size)
{
%this.setTransform(%position);
%this.setScale(%size SPC %size SPC %size);
}

function StaticShape::transformWorldBox(%this, %box)
{
%neg = getWords(%box, 0, 2);
%pos = getWords(%box, 3, 5);

%x1 = getWord(%neg, 0);
%y1 = getWord(%neg, 1);
%z1 = getWord(%neg, 2);

%x2 = getWord(%pos, 0);
%y2 = getWord(%pos, 1);
%z2 = getWord(%pos, 2);

%xd = %x2 - %x1;
%yd = %y2 - %y1;
%zd = %z2 - %z1;

%rot = getWords(matrixCreateFromEuler(0 SPC 0 SPC 0 SPC $pi / 2), 3, 6);

%this.setTransform(%x1 + %xd / 2 SPC %y1 + %yd / 2 SPC %z1 + %zd / 2 SPC %rot);
%this.setScale(%xd SPC %yd SPC %zd);
}