dCustomUpVector Bug

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

dCustomUpVector Bug

Postby Lax » Fri Mar 14, 2025 4:20 pm

Hi julio,

I'm using the dCustomUpVector for player so that he cannot fall down. It does work well if moving on a plane or terrain. But now I'm using planetary scenarios, in which the axis is alternating (gravityDirection towards planet). So I call in an update function each time:

upVector->setPin(-gravityDirection)

The issue is, that it does not work at all, the pin is not changed.

I have an really early newton version, and OgreNewt, in which this scenario did work.

Can this be fixed somehow for newton-dynamics 3.x version?
I think this could also be useful for newton-dynamics 4.x

Best Regards
Lax
Please support SecondEarthTechnicBase built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd17-5ff5-40a0-ac6f-44b97b79be62
Image
Lax
 
Posts: 182
Joined: Sat Jan 08, 2011 8:24 am

Re: dCustomUpVector Bug

Postby Julio Jerez » Tue Mar 18, 2025 12:42 pm

have you stepped inside the function to see what it does?
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: dCustomUpVector Bug

Postby Lax » Fri Mar 21, 2025 8:33 am

Hi,

I think calling:

void dCustomUpVector::SetPinDir(const dVector& pin, NewtonBody* child)

at runtime repeately for a gravity vector to (direction from player to center of a planet).

Does not actualize all matrizes?
But I'm no expert here.

I also tried to extend the dPlayerController with dVector m_gravityDirection, in order to have a player controller running on a sphere mesh (planet), but the player will use automatically up vector of (0, 1, 0, 0), which makes it impossible to use for such an scenario. I know, it was not designed for that. I tried some things with chatgpt, but failed.

So maybe this would be also a great scenario for newton3.14 and newton4.xxx. The showcase could be:

Having a sphere and a player controller, which can move on that sphere :D

I have it already working with a usual body.

Best Regards
Lax
Please support SecondEarthTechnicBase built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd17-5ff5-40a0-ac6f-44b97b79be62
Image
Lax
 
Posts: 182
Joined: Sat Jan 08, 2011 8:24 am

Re: dCustomUpVector Bug

Postby Julio Jerez » Fri Mar 21, 2025 3:09 pm

there are two classes
void dCustomUpVector::SetPinDir (const dVector& pin)
void dgUpVectorConstraint::SetPinDir (const dgVector& pin)


are you using ?
void dCustomUpVector::SetPinDir (const dVector& pin)
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: dCustomUpVector Bug

Postby Lax » Sun Mar 23, 2025 8:01 am

I use:

dCustomUpVector

Up til now, I did not even know, dgUpVectorConstraint does exist, but indeed it does :)

I will write the corresponding OgreNewt wrapper for it and test this one.

Best Regards
Lax
Please support SecondEarthTechnicBase built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd17-5ff5-40a0-ac6f-44b97b79be62
Image
Lax
 
Posts: 182
Joined: Sat Jan 08, 2011 8:24 am

Re: dCustomUpVector Bug

Postby Julio Jerez » Sun Mar 23, 2025 11:24 am

dCustomUpVector is the one to use.

this is the update function

Code: Select all
void dCustomUpVector::SubmitConstraints (dFloat timestep, int threadIndex)
{
   dMatrix matrix0;
   dMatrix matrix1;

   // calculate the position of the pivot point and the Jacobian direction vectors, in global space.
   CalculateGlobalMatrix (matrix0, matrix1);
 
   // if the body has rotated by some amount, the there will be a plane of rotation
   dVector lateralDir (matrix0.m_front.CrossProduct(matrix1.m_front));
   dFloat mag = lateralDir.DotProduct3(lateralDir);
   if (mag > 1.0e-6f) {
      // if the side vector is not zero, it means the body has rotated
      mag = dSqrt (mag);
      lateralDir = lateralDir.Scale (1.0f / mag);
      dFloat angle = dAsin (mag);

      // add an angular constraint to correct the error angle
      NewtonUserJointAddAngularRow (m_joint, angle, &lateralDir[0]);

      // in theory only one correction is needed, but this produces instability as the body may move sideway.
      // a lateral correction prevent this from happening.
      dVector frontDir (lateralDir.CrossProduct(matrix1.m_front));
      NewtonUserJointAddAngularRow (m_joint, 0.0f, &frontDir[0]);
    } else {
      // if the angle error is very small then two angular correction along the plane axis do the trick
      NewtonUserJointAddAngularRow (m_joint, 0.0f, &matrix0.m_up[0]);
      NewtonUserJointAddAngularRow (m_joint, 0.0f, &matrix0.m_right[0]);
   }
}


you can set a break point on thsi line

// if the side vector is not zero, it means the body has rotated
mag = dSqrt (mag);

and you can check that when that top up vector are no colinear,
the joint interpolate the upvetor of body0 until it matches the up vector of body1

if the break point does not hit, them there is a bug, but as I remember, it does hit when the vectors are at an angle.
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: dCustomUpVector Bug

Postby Lax » Sun Mar 23, 2025 4:08 pm

Hi,

ok, I set a breakpoint at that line, but the breakpoint is never hit.
So there seems to be a bug?

Best Regards
Lax
Please support SecondEarthTechnicBase built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd17-5ff5-40a0-ac6f-44b97b79be62
Image
Lax
 
Posts: 182
Joined: Sat Jan 08, 2011 8:24 am

Re: dCustomUpVector Bug

Postby Julio Jerez » Sun Mar 23, 2025 6:19 pm

Ok, it is cally the function at all?

Set the breakpoint at the begining of the function.
See if it called.

Also the function setpindir is in the same file,
My guess is that it is not setting the pin
Set a break point there.
Them check the the front of matrix 1 is changing.
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: dCustomUpVector Bug

Postby Lax » Mon Mar 24, 2025 9:31 am

Yes, its calling at all, just the if case is not called.
Please support SecondEarthTechnicBase built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd17-5ff5-40a0-ac6f-44b97b79be62
Image
Lax
 
Posts: 182
Joined: Sat Jan 08, 2011 8:24 am

Re: dCustomUpVector Bug

Postby Julio Jerez » Mon Mar 24, 2025 11:14 am

add a trace

Code: Select all
void dCustomUpVector::SubmitConstraints (dFloat timestep, int threadIndex)
{
   dMatrix matrix0;
   dMatrix matrix1;

   // calculate the position of the pivot point and the Jacobian direction vectors, in global space.
   CalculateGlobalMatrix (matrix0, matrix1);

ndTrace ((f0("%f %f %f %f)  f1("%f %f %f %f)\n"
                , matrix[0][0],  matrix[0][1],  matrix[0][2],  matrix[0][3]
                , matrix[1][0],  matrix[1][1],  matrix[1][2],  matrix[1][3]));


and see if they are changing as they are espected.


, matrix[0][0]
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: dCustomUpVector Bug

Postby Lax » Tue Mar 25, 2025 4:19 pm

Trace was not an option for my. I debugged it instead. And yes, the values are changing, but the mag remains near to zero.

Code: Select all
-      matrix0   {m_front={...} m_up={...} m_right={...} ...}   dMatrix
-      m_front   {...}   dVector
+      TemplateVector<float>   {m_x=-0.427665710 m_y=-0.287857831 m_z=-0.856878161 ...}   TemplateVector<float>
-      m_up   {...}   dVector
+      TemplateVector<float>   {m_x=-0.222331613 m_y=-0.885322630 m_z=0.408378541 ...}   TemplateVector<float>
-      m_right   {...}   dVector
+      TemplateVector<float>   {m_x=-0.876168251 m_y=0.365160495 m_z=0.314621985 ...}   TemplateVector<float>
-      m_posit   {...}   dVector
+      TemplateVector<float>   {m_x=37.6436729 m_y=0.322899938 m_z=38.1013832 ...}   TemplateVector<float>
-      matrix1   {m_front={...} m_up={...} m_right={...} ...}   dMatrix
-      m_front   {...}   dVector
+      TemplateVector<float>   {m_x=-0.427661270 m_y=-0.287850857 m_z=-0.856882572 ...}   TemplateVector<float>
-      m_up   {...}   dVector
+      TemplateVector<float>   {m_x=0.380464554 m_y=-0.917206943 m_z=0.118229561 ...}   TemplateVector<float>
-      m_right   {...}   dVector
+      TemplateVector<float>   {m_x=-0.819971085 m_y=-0.275451243 m_z=0.501770914 ...}   TemplateVector<float>
-      m_posit   {...}   dVector
+      TemplateVector<float>   {m_x=0.00000000 m_y=0.00000000 m_z=0.00000000 ...}   TemplateVector<float>


-      matrix0   {m_front={...} m_up={...} m_right={...} ...}   dMatrix
-      m_front   {...}   dVector
+      TemplateVector<float>   {m_x=-0.427665472 m_y=-0.287858218 m_z=-0.856877983 ...}   TemplateVector<float>
-      m_up   {...}   dVector
+      TemplateVector<float>   {m_x=-0.0722797215 m_y=-0.934014797 m_z=0.349846005 ...}   TemplateVector<float>
-      m_right   {...}   dVector
+      TemplateVector<float>   {m_x=-0.901042700 m_y=0.211551845 m_z=0.378639489 ...}   TemplateVector<float>
-      m_posit   {...}   dVector
+      TemplateVector<float>   {m_x=37.4419479 m_y=-0.0584351569 m_z=38.3383026 ...}   TemplateVector<float>
-      matrix1   {m_front={...} m_up={...} m_right={...} ...}   dMatrix
-      m_front   {...}   dVector
+      TemplateVector<float>   {m_x=-0.427661270 m_y=-0.287850857 m_z=-0.856882572 ...}   TemplateVector<float>
-      m_up   {...}   dVector
+      TemplateVector<float>   {m_x=0.380464554 m_y=-0.917206943 m_z=0.118229561 ...}   TemplateVector<float>
-      m_right   {...}   dVector
+      TemplateVector<float>   {m_x=-0.819971085 m_y=-0.275451243 m_z=0.501770914 ...}   TemplateVector<float>
-      m_posit   {...}   dVector
+      TemplateVector<float>   {m_x=0.00000000 m_y=0.00000000 m_z=0.00000000 ...}   TemplateVector<float>



      mag   8.98643382e-11   float
-      matrix0   {m_front={...} m_up={...} m_right={...} ...}   dMatrix
-      m_front   {...}   dVector
+      TemplateVector<float>   {m_x=-0.427665174 m_y=-0.287858307 m_z=-0.856878221 ...}   TemplateVector<float>
-      m_up   {...}   dVector
+      TemplateVector<float>   {m_x=0.0772588849 m_y=-0.956111431 m_z=0.282634884 ...}   TemplateVector<float>
-      m_right   {...}   dVector
+      TemplateVector<float>   {m_x=-0.900629580 m_y=0.0546716750 m_z=0.431135029 ...}   TemplateVector<float>
-      m_posit   {...}   dVector
+      TemplateVector<float>   {m_x=36.9629860 m_y=-0.827413201 m_z=38.8549728 ...}   TemplateVector<float>
-      matrix1   {m_front={...} m_up={...} m_right={...} ...}   dMatrix
-      m_front   {...}   dVector
+      TemplateVector<float>   {m_x=-0.427661270 m_y=-0.287850857 m_z=-0.856882572 ...}   TemplateVector<float>
-      m_up   {...}   dVector
+      TemplateVector<float>   {m_x=0.380464554 m_y=-0.917206943 m_z=0.118229561 ...}   TemplateVector<float>
-      m_right   {...}   dVector
+      TemplateVector<float>   {m_x=-0.819971085 m_y=-0.275451243 m_z=0.501770914 ...}   TemplateVector<float>
-      m_posit   {...}   dVector
+      TemplateVector<float>   {m_x=0.00000000 m_y=0.00000000 m_z=0.00000000 ...}   TemplateVector<float>
      threadIndex   0   int
      timestep   0.0166666675   float



Or is it, because I use the UpVector and set the pin indirectly in the movecallback, which I use for force calculation:

Code: Select all
void PhysicsActiveComponent::moveCallback(OgreNewt::Body* body, Ogre::Real timeStep, int threadIndex)
{
...
if (false == this->gravitySourceCategory->getString().empty())
{
   // If there is a gravity source GO, calculate gravity in that direction of the source, but only work with the nearest object, else the force will mess up
   auto gravitySourceGameObjects = AppStateManager::getSingletonPtr()->getGameObjectController()->getGameObjectsFromCategory(this->gravitySourceCategory->getString());
   for (size_t i = 0; i < gravitySourceGameObjects.size(); i++)
   {
      wholeForce = this->getPosition() - gravitySourceGameObjects[i]->getPosition();
      Ogre::Real squaredDistanceToGravitySource = wholeForce.squaredLength();
      if (squaredDistanceToGravitySource < nearestPlanetDistance)
      {
         nearestPlanetDistance = squaredDistanceToGravitySource;
         nearestGravitySourceObject = gravitySourceGameObjects[i];
      }
   }

   // Only do calculation for the nearest planet
   if (nullptr != nearestGravitySourceObject)
   {
      auto& gravitySourcePhysicsComponentPtr = NOWA::makeStrongPtr(nearestGravitySourceObject->getComponent<PhysicsComponent>());
      if (nullptr != gravitySourcePhysicsComponentPtr)
      {
         Ogre::Vector3 directionToPlanet = this->getPosition() - gravitySourcePhysicsComponentPtr->getPosition();
         directionToPlanet.normalise();

         // Ensures constant acceleration of e.g. -19.8 m/s²
         Ogre::Real gravityAcceleration = -this->gravity->getVector3().length(); // Should be e.g. 19.8

         this->gravityDirection = -directionToPlanet;
         wholeForce = directionToPlanet * (mass * gravityAcceleration); // F = m * a

         // Store the current gravity strength for jump normalization
         this->currentGravityStrength = gravityAcceleration;
         // Mark gravity as updated
         this->gravityUpdated.test_and_set();

         this->setConstraintDirection(this->gravityDirection);

      }
   }
   else
   {
      this->gravityDirection = Ogre::Vector3::NEGATIVE_UNIT_Y;
      this->currentGravityStrength = 0.0f;

      this->gravityUpdated.clear();
   }
}
...
body->addForce(wholeForce);
}


The constraint direction sets the UpVector pin inside that function, which is used in the movecallback:
Code: Select all
void PhysicsActiveComponent::setConstraintDirection(const Ogre::Vector3& constraintDirection)
{
   if (true == constraintDirection.isZeroLength())
   {
      if (nullptr != this->upVector)
      {
         this->releaseConstraintDirection();
      }
   }

   this->constraintDirection->setValue(constraintDirection);
   // Only set pin, if there is no constraint axis, because constraint axis also uses pin
   if (nullptr != this->physicsBody && Ogre::Vector3::ZERO != constraintDirection && nullptr == this->upVector)
   {
      this->upVector = new OgreNewt::UpVector(this->physicsBody, constraintDirection);
   }
   else if (nullptr != this->upVector)
   {
      this->upVector->setPin(this->physicsBody, constraintDirection);
   }
}
Please support SecondEarthTechnicBase built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd17-5ff5-40a0-ac6f-44b97b79be62
Image
Lax
 
Posts: 182
Joined: Sat Jan 08, 2011 8:24 am

Re: dCustomUpVector Bug

Postby Julio Jerez » Tue Mar 25, 2025 10:30 pm

the two front vectors are identical
matrix0 m_front {m_x=-0.427665710 m_y=-0.287857831 m_z=-0.856878161}
matrix1 m_front {m_x=-0.427661270 m_y=-0.287850857 m_z=-0.856882572}

it is working exactly as it is supposed to.

your code is not calling SetPinDirection(vector newDir)

I see that it has this call, this->setConstraintDirection(this->gravityDirection);
just check that that call in in fact calling SetPinDirection in the joint class.

I also see that is has this

this->upVector->setPin(this->physicsBody, constraintDirection);
but I do not know if upVector is the joint, just make sure that either of those functions are calling
the joint function SetPinDirection and that it is in fact changing this direction.
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: dCustomUpVector Bug

Postby Lax » Wed Mar 26, 2025 8:30 am

Hi,

I always set the Pin, this the OgreNewt function:

void UpVector::setPin(const Body* body, const Ogre::Vector3& pin)
{
dCustomUpVector* supportJoint = static_cast<dCustomUpVector*>(m_joint);
dVector dPin(m_pin.x, m_pin.y, m_pin.z, 1.0f);

supportJoint->SetPinDir(dPin, body->getNewtonBody());
}

Maybe it does not work, because I work with forces. In the early past: I worked with velocities/omega for bodies. There the upvector had worked for alternating axis. But we discussed in the past, that using velocity/omega for body which is not a kinematic body is a bad Idea. So I refactored everything.


Best Regards
Lax
Please support SecondEarthTechnicBase built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd17-5ff5-40a0-ac6f-44b97b79be62
Image
Lax
 
Posts: 182
Joined: Sat Jan 08, 2011 8:24 am

Re: dCustomUpVector Bug

Postby Julio Jerez » Wed Mar 26, 2025 11:06 am

Not it does not work by forces, it just set the pin of the parent body in the joint
the function bellow, and the joint does the rest.
Code: Select all
// bu animating the orientation of the pin vector the application can change the orientation of the picked object
void dCustomUpVector::SetPinDir (const dVector& pin)
{
   m_localMatrix1 = dGrammSchmidt(pin);
}


you are showing the wrapper functions.
Lax wrote:void UpVector::setPin(const Body* body, const Ogre::Vector3& pin)
{
dCustomUpVector* supportJoint = static_cast<dCustomUpVector*>(m_joint);
dVector dPin(m_pin.x, m_pin.y, m_pin.z, 1.0f);

supportJoint->SetPinDir(dPin, body->getNewtonBody());
}
Lax


the log you showed before, showed that the pin is not changing
did you put the break point in this function and trace the values?
void dCustomUpVector::SetPinDir (const dVector& pin)

you can just add a hack like making the pin an arbitrary rotated vector, and check that the two front dir are different in this function.
void dCustomUpVector::SubmitConstraints (dFloat timestep, int threadIndex)

as long as the pins are colinear, it will never rotate the child body. that is the expected behavior.
Julio Jerez
Moderator
Moderator
 
Posts: 12425
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 1 guest