/* * Copyright 2016 Nathan Howard * * This file is part of OpenGrave * * OpenGrave is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenGrave is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenGrave. If not, see <http://www.gnu.org/licenses/>. */ package com.opengrave.og.engine.gait; import com.opengrave.og.Util; import com.opengrave.og.engine.AnimatedObject; import com.opengrave.og.engine.Surface; import com.opengrave.og.util.Vector3f; import com.opengrave.og.util.Vector4f; public class BipedWalk extends Walk { private Bone leg1, leg2; private AnimatedObject obj; private Gait gait; private Bone legPlanted = null, otherLeg = null; private Vector3f p; private int coolDown = 0; private int fails = 0; public BipedWalk(AnimatedObject obj, Bone leg1, Bone leg2) { System.out.println(leg1.jointName + " " + leg2.jointName); this.leg2 = leg2.getEndBone(); this.leg1 = leg1.getEndBone(); this.obj = obj; Skeleton skele = obj.getSkeleton(); Bone boneHL1 = skele.getBone("Hip.left"); boneHL1.yC = new AngleConstraint(-15f, 15f); boneHL1.zC = new AngleConstraint(-5f, 5f); // boneHL1.xC = new AngleConstraint(-5f, 5f); // Upper Bone boneHL2 = skele.getBone("UpperLeg.left"); boneHL2.zC = new AngleConstraint(-80f, 80f); boneHL2.xC = new AngleConstraint(-20f, 40f); // Lower Bone boneHL3 = skele.getBone("LowerLeg.left"); boneHL3.xC = new AngleConstraint(0f, 150f); // Hip Bone boneHR1 = skele.getBone("Hip.right"); boneHR1.yC = new AngleConstraint(-15f, 15f); boneHR1.zC = new AngleConstraint(-5f, 5f); // boneHR1.xC = new AngleConstraint(-5f, 5f); // Upper Bone boneHR2 = skele.getBone("UpperLeg.right"); boneHR2.zC = new AngleConstraint(-80f, 80f); boneHR2.xC = new AngleConstraint(-20f, 40f); // Lower Bone boneHR3 = skele.getBone("LowerLeg.right"); boneHR3.xC = new AngleConstraint(0f, 150f); gait = new BipedGait(); } public void update(float delta) { if (leg1 == null || leg2 == null) { return; } obj.skele.root.setWorldMatrixRecurse(Util.createMatrixFor(obj.location, null, null, null)); if (legPlanted == null) { // No leg is planted. Assume no movement has happened yet plantLeg(leg1.getEndBone(), null); obj.skele.location.setZ(-0.3f); } else { // Get Model co-ordinate of pinned location // TODO Compare current location to bones default location, not center of obj Vector4f pin = Util.createMatrixFor(obj.location, null, null, null).inverse(null).mult4(new Vector4f(p.x, p.y, p.z, 1f), null); boolean pinSwap = false; if (Math.abs(pin.y) > gait.getStride(1f)) { pinSwap = true; } else if (Math.abs(pin.x) > gait.getSideStride(1f)) { pinSwap = true; } legPlanted.IK(2, obj, p); Vector3f otherLegLoc = obj.location.toVector3().sub(p, null); otherLegLoc = otherLegLoc.add(obj.location.toVector3(), null); Surface s = obj.getSurface(); if (s != null) { otherLegLoc.z = s.getHeight(otherLegLoc.x, otherLegLoc.y); } otherLeg.IK(2, obj, otherLegLoc); if (pinSwap) { if (coolDown > 0) { fails++; if (fails > 5) { System.out.println("Armature pinning failed - reseting"); removePlant(); fails = 0; coolDown = 0; } return; } coolDown = 10; if (legPlanted == leg1.getEndBone()) { plantLeg(leg2.getEndBone(), null); } else { plantLeg(leg1.getEndBone(), null); } } if (coolDown > 0) { coolDown--; } // gait.moveOther(otherLeg,pin); } } public void plantLeg(Bone leg, Vector3f newLoc) { legPlanted = leg.getEndBone(); if (legPlanted == leg1) { otherLeg = leg2; } else { otherLeg = leg1; } if (newLoc == null) { p = leg.getEndBone().getWorldPosition(); } else { p = newLoc; } // p = new Vector3f(0f,0f,1f); // System.out.println("Biped walk leg "+leg.jointName+" planted at "+p); } @Override public void removePlant() { p = null; legPlanted = null; otherLeg = null; } }