OfficerYoda / Fhysics

A Physics simulation
MIT License
0 stars 0 forks source link

Cursor is effecting objects #58

Closed OfficerYoda closed 4 months ago

OfficerYoda commented 4 months ago

When the cursor is hovering over an object is can act differently then normal (e.g. it starts shaking)

How to recreate

Create a triangle and let it settle on the bottom border, so it remains stationary under the influence of gravity (0, -10). When hovering over the triangle, as shown in the picture below, it begins to shake more and more and eventually starts drifting to one side.

image

OfficerYoda commented 4 months ago

The shaking etc. also starts when the mouse is entering inside the Border or drawing BoundingBoxes is enabled. for both of these the object doesnt need to be selected.

This leads me to suspect that it might have to do with something that is called in QuadTree.query() aswell as in DebugDrawer.drawBoundingBox().

OfficerYoda commented 4 months ago

If the object is only selected and the mouse is not inside the border nothing happens.

OfficerYoda commented 4 months ago

When modifying the QuadTree.query() function to always return null. The bug doesnt occur during hovering or when the mouse is inside the border.

Enabling bounding boxes still brings the bug up from hell

OfficerYoda commented 4 months ago

The bug with enabling boundingBox was caused by the boundingBox retrieval process. When replacing the boundingBox retrieval with instantiating a new bounding box, the bug didn't occur.

The following two similar methods for getting the transformed vertices of a polygon will or will not cause the bug when called during the boundingBox retrieval process of a FhysicsObject. These methods are called inside the setFromPolygon(Polygon) method, which in turn is called by the setFromFhysicsObject() method, which in turn is called by the boundingBox retrieval process.

BoundingBox field in FhysicsObject:

    val boundingBox: BoundingBox = BoundingBox()
        get() {
            // Only update the bounding box if it hasn't been updated this update cycle
            if (lastBBoxUpdate != FhysicsCore.updateCount) {
                lastBBoxUpdate = FhysicsCore.updateCount
                boundingBox.setFromFhysicsObject(this)
            }
            return field
        }

BoundingBox.setFromPolygon(Polygon):

    private fun setFromPolygon(poly: Polygon) {
//        val transformedVertices: Array<Vector2> = poly.getTransformedVertices() // Causes the bug
        val transformedVertices: Array<Vector2> = poly.getBoundingVertices() // Doesn't cause the bug

        // Getting the min and max values and setting the according fields...
    }

This causes the bug:

    open fun getTransformedVertices(): Array<Vector2> {
        return vertices.map { it.rotatedAround(Vector2.ZERO, angle) + super.position }.toTypedArray()
    }

This doesn't cause the bug:

    // For debug only
    fun getBoundingVertices(): Array<Vector2>  {
        return vertices.map { it + super.position }.toTypedArray()
    }

Note: They only differ in the .rotatedAround(Vector2, Float) part

Vector2.rotatedAround(Vector2, Float):

    fun rotatedAround(center: Vector2, angle: Float): Vector2 {
        val cosAngle: Float = cos(angle)
        val sinAngle: Float = sin(angle)

        val translatedX: Float = this.x - center.x
        val translatedY: Float = this.y - center.y

        val rotatedX: Float = translatedX * cosAngle - translatedY * sinAngle
        val rotatedY: Float = translatedX * sinAngle + translatedY * cosAngle

        return Vector2(rotatedX + center.x, rotatedY + center.y)
    }

Someone please help me before I go insane.

OfficerYoda commented 4 months ago

Bug Description

The bug was caused by updating the bounding box during rendering. The core issue was not the render thread itself, but rather the timing of the bounding box update. Specifically, the updateCounter, used to ensure the bounding box was calculated only once per update, was already incremented. This calculation issue occurred in the render thread when getting the bounding box for rendering and during the query step of the QuadTree.

Root Cause

This timing mismatch resulted in the bounding box being out of sync with the object. The bounding box was updated before the object's position and velocity were updated for the current frame. As a result, the object could move out of its expected bounds while the bounding box incorrectly considered it still within bounds. This discrepancy caused the object to become unstable, leading to shaking and erratic movement.

Solution

The bug was fixed by recalculating the bounding box after the object’s position and velocity updates, but before collision detection. This approach ensures that the bounding box is synchronized with the object's current state, resolving the instability and preventing issues during interactions like hovering and cursor detection.