Skip to content
This repository was archived by the owner on Oct 7, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/mgear_solvers.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,11 +533,22 @@ class mgear_springNode : public MPxNode
static MObject aGoalY;
static MObject aGoalZ;
static MObject aDamping;
static MObject aGravity;
static MObject aStiffness;
static MObject aTime;
static MObject aCollider;
static MObject aColliderX;
static MObject aColliderY;
static MObject aColliderZ;
static MObject aColliderRadius;
static MObject aColliderSoftness;
static MObject aColliderList;
//static MObject aParentInverse;
static MObject aSpringIntensity;
static MObject aSpringActive;

static MObject aUseGroundPlane;
static MObject aGroundPlaneHeight;
////variables

bool _initialized;
Expand Down Expand Up @@ -713,4 +724,4 @@ MTransformationMatrix mapObjectPoseToWorldSpace(MTransformationMatrix objectSpac
MTransformationMatrix interpolateTransform(MTransformationMatrix xf1, MTransformationMatrix xf2, double blend);


#endif
#endif
124 changes: 119 additions & 5 deletions src/springNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Date: 2016 / 10 / 10
// INCLUDE
/////////////////////////////////////////////////
#include "mgear_solvers.h"
#include <maya/MFnCompoundAttribute.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MArrayDataBuilder.h>

/////////////////////////////////////////////////
// GLOBAL
Expand All @@ -49,8 +52,22 @@ MObject mgear_springNode::aGoalZ;
MObject mgear_springNode::aDamping;
MObject mgear_springNode::aStiffness;
MObject mgear_springNode::aTime;

MObject mgear_springNode::aGravity;

MObject mgear_springNode::aCollider;
MObject mgear_springNode::aColliderX;
MObject mgear_springNode::aColliderY;
MObject mgear_springNode::aColliderZ;
MObject mgear_springNode::aColliderRadius;
MObject mgear_springNode::aColliderList;
MObject mgear_springNode::aColliderSoftness;
MObject mgear_springNode::aUseGroundPlane;
MObject mgear_springNode::aGroundPlaneHeight;

//MObject mgear_springNode::aParentInverse;
MObject mgear_springNode::aSpringIntensity;
MObject mgear_springNode::aSpringActive;


mgear_springNode::mgear_springNode(){}
Expand All @@ -75,6 +92,8 @@ MStatus mgear_springNode::initialize()
MFnNumericAttribute nAttr;
MFnUnitAttribute uAttr;
MFnMatrixAttribute mAttr;
MFnCompoundAttribute cmpAttr;


aOutput = nAttr.createPoint("output", "out"); // initializing attribute
nAttr.setWritable(false);
Expand Down Expand Up @@ -116,6 +135,68 @@ MStatus mgear_springNode::initialize()
addAttribute(aSpringIntensity);
attributeAffects(aSpringIntensity, aOutput);

aSpringActive = nAttr.create("active", "active", MFnNumericData::kFloat, 1.0f);
nAttr.setKeyable(true);
nAttr.setMin(0.0f);
nAttr.setMax(1.0f);
addAttribute(aSpringActive);
attributeAffects(aSpringActive, aOutput);

aGravity = nAttr.create("gravity", "gravity", MFnNumericData::kFloat, 0.0f);
nAttr.setKeyable(true);
nAttr.setMin(-1000.0f);
nAttr.setMax(1000.0f);
addAttribute(aGravity);
attributeAffects(aGravity, aOutput);

aColliderSoftness = nAttr.create("collide_softness", "collide_softness", MFnNumericData::kFloat, 0.5f);
nAttr.setKeyable(true);
nAttr.setMin(0.0f);
nAttr.setMax(1.0f);
addAttribute(aColliderSoftness);
attributeAffects(aColliderSoftness, aOutput);

aUseGroundPlane = nAttr.create("use_ground", "use_ground", MFnNumericData::kBoolean, 0);
nAttr.setKeyable(true);
addAttribute(aUseGroundPlane);
attributeAffects(aUseGroundPlane, aOutput);

aGroundPlaneHeight = nAttr.create("ground_height", "ground_height", MFnNumericData::kFloat, 0.0f);
nAttr.setKeyable(true);
addAttribute(aGroundPlaneHeight);
attributeAffects(aGroundPlaneHeight, aOutput);


aCollider = nAttr.createPoint("collider", "collider");
aColliderX = nAttr.child(0);
aColliderY = nAttr.child(1);
aColliderZ = nAttr.child(2);
nAttr.setKeyable(true);
McheckErr(nAttr.setDisconnectBehavior(MFnAttribute::kDelete), "setDisconnectBehavior");
addAttribute(aCollider);
attributeAffects(aCollider, aOutput);


aColliderRadius = nAttr.create("collide_radius", "collide_radius", MFnNumericData::kFloat, 0.0f);
nAttr.setKeyable(true);
nAttr.setMin(-1000.0f);
nAttr.setMax(1000.0f);
McheckErr(nAttr.setDisconnectBehavior(MFnAttribute::kDelete), "setDisconnectBehavior");
addAttribute(aColliderRadius);
attributeAffects(aColliderRadius, aOutput);


aColliderList = cmpAttr.create("colliders_list", "colliders_list", &status);
cmpAttr.setArray(true);
cmpAttr.setKeyable(true);
McheckErr(cmpAttr.addChild(aCollider), "compoundAttr.addChild");
McheckErr(cmpAttr.addChild(aColliderRadius), "compoundAttr.addChild");
McheckErr(cmpAttr.setDisconnectBehavior(MFnAttribute::kDelete), "setDisconnectBehavior");
McheckErr(addAttribute(aColliderList), "addAttribute");
McheckErr(attributeAffects(aColliderList, aOutput), "attributeAffects");



/*aParentInverse = mAttr.create("parentInverse", "parentInverse");
mAttr.setStorable(true);
mAttr.setKeyable(true);
Expand Down Expand Up @@ -144,21 +225,20 @@ MStatus mgear_springNode::compute(const MPlug& plug, MDataBlock& data)
// getting inputs attributes
float damping = data.inputValue(aDamping, &status).asFloat();
float stiffness = data.inputValue(aStiffness, &status).asFloat();
float gravity = data.inputValue(aGravity, &status).asFloat();

//MVector goal = data.inputValue(aGoal, &status).asVector();
MDataHandle h;
MVector goal;
h = data.inputValue(aGoal, &status);
McheckStatusAndReturnIt(status);
goal = h.asFloatVector();
// float aGoalX = goal.x;
// float aGoalY = goal.y;
// float aGoalZ = goal.z;


MTime currentTime = data.inputValue(aTime, &status).asTime();
//MMatrix parentInverse = data.inputValue(aParentInverse, &status).asMatrix();
float springIntensity = data.inputValue(aSpringIntensity, &status).asFloat();
float springActive = data.inputValue(aSpringActive, &status).asFloat();


if (_initialized == false) {
Expand All @@ -185,16 +265,50 @@ MStatus mgear_springNode::compute(const MPlug& plug, MDataBlock& data)
MFloatVector velocity = (_currentPosition - _previousPosition) * (1.0 - damping);
MVector newPosition = _currentPosition + velocity;
MFloatVector goalForce = (goal - newPosition) * stiffness;
goalForce.y += gravity;
newPosition += goalForce;



// Apply collision
float colliderStrength = 1.0 - data.inputValue(aColliderSoftness, &status).asFloat();
MVector colliderPos;
MVector distFromCollider;
float colliderRadius;
float collideAmount;
MArrayDataHandle arrayHandle = data.inputArrayValue(aColliderList, &status);
McheckErr(status, "arrayHandle construction for aColliderList failed\n");
unsigned count = arrayHandle.elementCount();
for( int i = 0; i < count; i++) {
arrayHandle.jumpToArrayElement(i);
h = arrayHandle.inputValue(&status);
McheckErr(status, "handle evaluation failed\n");
colliderPos = h.child(aCollider).asFloatVector();
colliderRadius = h.child(aColliderRadius).asFloat();
distFromCollider = newPosition - colliderPos;
collideAmount = (colliderRadius - distFromCollider.length()) / distFromCollider.length() * colliderStrength;
collideAmount = collideAmount > 0 ? collideAmount : 0; // Only push outward
newPosition += collideAmount * distFromCollider; // Move radially
}


bool useGroundPlane = data.inputValue(aUseGroundPlane, &status).asBool();
float groundPlaneHeight = data.inputValue(aGroundPlaneHeight, &status).asFloat();

float distFromGround = (newPosition[1] - groundPlaneHeight);
float collideAmount = -1.0f * distFromGround * colliderStrength;
collideAmount = collideAmount > 0 ? collideAmount : 0;
newPosition[1] += ((float)useGroundPlane) * collideAmount;


// store the states for the next calculation
_previousPosition = _currentPosition;
_currentPosition = newPosition;
_previousTime = currentTime;

//multipply the position by the spring intensity
//calculamos depues de los states, para no afectarlos
newPosition = goal + ((newPosition - goal) * springIntensity);
newPosition = goal + (((newPosition - goal) * springIntensity) * springActive);

//Setting the output in local space
// esto lo hacemos depues de hacer el store de los states
Expand All @@ -210,4 +324,4 @@ MStatus mgear_springNode::compute(const MPlug& plug, MDataBlock& data)

return MS::kSuccess;

}
}