Jump to content

[SOLVED] Question regarding intersections


photo

Recommended Posts

I've been looking for an engine to migrate to from unity and so far unigine seems to be a really good choice but i cant quite get my head around intersections and all their different types

I'm making a racing game and the tire/suspension script relies on a spherecast (used spherecast instead of a normal raycast for a smooth transition of the wheel on pointy terrain), here is a snippet of it

 if (Physics.SphereCast(
    new Vector3(transform.position.x, transform.position.y + radius, transform.position.z),
    radius, -transform.up, out wheelGroundHit, suspensionDistance + radius, roadLayer.value))
{
    /////////////
    ////////////
    ///////////


    Vector3 position = transform.position - transform.up * wheelGroundHit.distance;
    compression = 1f - (wheelGroundHit.distance - radius) / suspensionDistance;

    camber = Vector3.Angle(Vector3.ProjectOnPlane(wheelGroundHit.normal.normalized, dummyWheel.transform.forward), dummyWheel.transform.up);
    toe = Vector3.Angle(Vector3.ProjectOnPlane(wheelGroundHit.normal.normalized, dummyWheel.transform.right), dummyWheel.transform.up);

    //////////////
    //////////////
    //////////////

    visualWheel.transform.position = transform.position - transform.up * (wheelGroundHit.distance - radius);
}

What i cant quite recreate with intersections is setting a distance limit and reading the current ray length, basically anything that that uses wheelGroundHit in the script above

would really appreciate some guidance, thanks in advance

Link to comment

Alright so this is what i came up with so far:
 

vec3 force = vec3.ZERO;
WorldIntersectionNormal ray = new WorldIntersectionNormal();
wheelGroundHit = World.GetIntersection(node.WorldPosition, node.WorldPosition - node.GetWorldDirection(MathLib.AXIS.Z) * suspensionDistance, roadLayer, ray);
if(wheelGroundHit){
    float distance = (float)(node.WorldPosition - ray.Point).Length;
    isGrounded = true;
    wheelVelocity = (vec3)((node.WorldPosition - wheelPrevPosition) / Game.IFps);
    wheelPrevPosition = (vec3)node.WorldPosition;

    //wheelLongitudalVelocity = dummyWheel.transform.InverseTransformDirection(wheelVelocity).z;
    //wheelLateralVelocity = dummyWheel.transform.InverseTransformDirection(wheelVelocity).x;
    wheelLongitudalVelocity = (float)(dummyWheel.WorldPosition - wheelVelocity).Normalized.y;
    wheelLateralVelocity = (float)(dummyWheel.WorldPosition - wheelVelocity).Normalized.x;

    vec3 position = (vec3)(node.WorldPosition - node.GetWorldDirection(MathLib.AXIS.Z) * distance);
    compression = 1f - (distance - radius) / suspensionDistance;

    /////////////
    /////////////
    /////////////
    
    visualWheel.WorldPosition = node.WorldPosition - node.GetWorldDirection(MathLib.AXIS.Z) * (distance - radius);
}

but the car in classic gamedev fashion flies into space at speed of sound, so im probably doing something wrong

Link to comment

Hi igorciz777,

At first glance I don't see any issues. The code seems to be working.
Are your wheels Objects? The car is a BodyRigid? There may be a collision between "visualWheel" (ObjectMeshSkinned?) and the body of your car (Object + BodyRigid). Unlike Unity, our physics can collide with meshes "as is", without shapes (colliders).
Try to disable all Intersections, Collisions and Physics Intersections on all objects of your car:
image.png

Best regards,
Alexander

Link to comment

None of the objects had those options selected but an useful thing to remember. Im thinking my initial understanding of Unity's InverseTransformDirection() function might be wrong, wheelLongitudal(Lateral)Velocity contribute to calculating forces applied to the wheel and those forces are in incredibly high numbers which is probably the cause of the car being launched

Edit:
im having trouble with using visualizer to draw the intersection, instead i moved an object to ray.Point and it seems that the intersection point is weirdly positioned to the right and behind of the wheel, it looks like the intersection goes at an angle rather than straight down, which i thought would happen with the endpoint (node.WorldPosition - (node.GetWorldDirection(MathLib.AXIS.Z) * suspensionDistance)) i set
Edit2:

Got the visualizer to work, the fault is still at the intersection code it seems.

image.thumb.png.1017e6c726ddc7561aa18fec392bf06a.png

Edited by igorciz777
Link to comment

Hi!

The only option why you have an interaction and the visualizer looks sideways and not vertically is that your node is rotated in the world. Can you share a screenshot of node(and hierarhy) you added the component to? does this wheel spin?

if you need strictly vertical - you can try using vec3.UP instead of  node.GetWorldDirection(MathLib.AXIS.Z)

It's just guesswork anyway. We need more context to understand what exactly is going wrong

Link to comment

Multiplying node.GetWorldRotation() by vec3.UP did the job, the intersection now goes in the correct direction. The car still goes flying so i tried to port a simpler script that only does suspension without any tire forces but to no avail, car still launches up instantly
Here is the unity script i tried to port github
And here is the attempt 

public class Suspension : Component
{
	[ShowInEditor] private Node vehicleNode;
	[ShowInEditor] private float wheelRadius = 0.5f;
	[ShowInEditor] private float suspensionDistanceConstant = 1f;
	[ShowInEditor] private float springConstant = 30000f;
	[ShowInEditor] private float damperConstant = 4000f;

	private BodyRigid vehicleBody;
	private float previousSuspensionDistance;
	private float currentSuspensionDistance;
	private float springVelocity;
	private float springForce;
	private float damperForce;

	private void Init(){
		vehicleBody = vehicleNode.ObjectBodyRigid;
		Visualizer.Enabled = true;
        Unigine.Console.Run("show_visualizer 1");
	}

	private void UpdatePhysics()
	{
		WorldIntersectionNormal ray = new WorldIntersectionNormal();
        Unigine.Object hit = World.GetIntersection(node.WorldPosition, node.WorldPosition - (node.GetWorldRotation() * vec3.UP * (suspensionDistanceConstant + wheelRadius)), 1, ray);
		if(hit)
		{
			float distance = (float)(ray.Point - node.WorldPosition).Length;
			// Hooke's Law
			previousSuspensionDistance = currentSuspensionDistance;
			currentSuspensionDistance = suspensionDistanceConstant - (distance - wheelRadius);
			springVelocity = (currentSuspensionDistance - previousSuspensionDistance) / Game.IFps;
			springForce = springConstant * currentSuspensionDistance;
			damperForce = damperConstant * springVelocity;

			// Apply force to car body
			vehicleBody.AddWorldForce(node.GetWorldRotation() * vec3.UP * (springForce + damperForce), (vec3)node.WorldPosition);
		}

		 Visualizer.RenderLine3D(node.WorldPosition, node.WorldPosition - (node.GetWorldRotation() * vec3.UP * (suspensionDistanceConstant + wheelRadius)), vec4.GREEN);
	}
}

The only major differences are getting the rays distance and replacing Time.fixedDelta with Game.IFps

Edit: There is a stupid mistake in the code, AddWorldForce takes in position first, force second ofc, sadly that wasnt the fix either, its a little bit less insane now but still makes the rigidbody jump in all directions


Here is also my hierarchy if it still might help
image.png.5643a0209fd029836c3c07efb9cac210.png

Edited by igorciz777
Link to comment

Seems like an obvious fix now but i stabilized the suspension script by increasing the Physics FPS in the Settings tab. No luck with the TireModel script, it most likely needs a complete rewrite, maybe a XZY->XYZ related issue i overlooked. I think all my Intersection specific issues are solved for now, I appreciate the help!

  • Like 1
Link to comment
  • silent changed the title to [SOLVED] Question regarding intersections
×
×
  • Create New...