Skip to content

Commit

Permalink
fix bug where a constrained sub-base being unable to solve would affe…
Browse files Browse the repository at this point in the history
…ct later chain's ability to reach the target.
  • Loading branch information
Stermere committed Jan 13, 2024
1 parent 1b18c67 commit d56d3fd
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class IKChain(
// state variables
var children = mutableListOf<IKChain>()
var target = Vector3.NULL
private var distToTargetSqr = Float.POSITIVE_INFINITY
var distToTargetSqr = Float.POSITIVE_INFINITY
private var centroidWeight = 1f
private var positions = getPositionList()
private var tailConstrainPosOffset = Vector3.NULL
Expand Down Expand Up @@ -50,21 +50,22 @@ class IKChain(
positions[positions.size - 1] = target

for (i in positions.size - 2 downTo 0) {
val direction = (positions[i] - positions[i + 1]).unit()
val constrainedDirection = nodes[i].rotationConstraint
var direction = (positions[i] - positions[i + 1]).unit()
direction = nodes[i].rotationConstraint
.applyConstraintInverse(direction, nodes[i])

positions[i] = positions[i + 1] + (constrainedDirection * nodes[i].length)
positions[i] = positions[i + 1] + (direction * nodes[i].length)
}

if (parent != null) parent!!.target += positions[0] * centroidWeight
if (parent != null && parent!!.tailConstraint == null)
parent!!.target += positions[0] * centroidWeight
}

private fun forwards() {
if (baseConstraint != null) {
positions[0] = baseConstraint.position + baseConstraintPosOffset
} else if (parent != null) {
if (parent != null) {
positions[0] = parent!!.positions.last()
} else if (baseConstraint != null) {
positions[0] = baseConstraint.position + baseConstraintPosOffset
}

for (i in 1 until positions.size - 1) {
Expand Down Expand Up @@ -104,6 +105,8 @@ class IKChain(

fun resetChain() {
centroidWeight = 1f
distToTargetSqr = Float.POSITIVE_INFINITY
target = Vector3.NULL

for (child in children) {
child.resetChain()
Expand Down Expand Up @@ -139,17 +142,19 @@ class IKChain(
}

/**
* Updates the distance to target and centroid weight variables
* and returns the new distance to the target
* Updates the distance to target and other fields
* Call on the root chain only returns the sum of the
* distances
*/
fun computeTargetDistance(): Float {
fun computeTargetDistance() {
distToTargetSqr = if (tailConstraint != null) {
(positions.last() - (tailConstraint.position + tailConstrainPosOffset)).lenSq()
} else {
0.0f
}

return distToTargetSqr
for (chain in children)
chain.computeTargetDistance()
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,12 @@ class IKSolver(private val root: Bone) {
}
rootChain?.forwardsMulti()

rootChain?.computeTargetDistance()

// if all chains have reached their target the chain is solved
var solved = true
for (chain in chainList) {
if (chain.computeTargetDistance() > TOLERANCE_SQR) {
if (chain.distToTargetSqr > TOLERANCE_SQR) {
solved = false
break
}
Expand Down

0 comments on commit d56d3fd

Please sign in to comment.