constraints/constraint3Dcurvedeformer/orconstraint3Dcurvedeformer_constraint.cxx

constraints/constraint3Dcurvedeformer/orconstraint3Dcurvedeformer_constraint.cxx
/***************************************************************************************
Autodesk(R) Open Reality(R) Samples
(C) 2009 Autodesk, Inc. and/or its licensors
All rights reserved.
AUTODESK SOFTWARE LICENSE AGREEMENT
Autodesk, Inc. licenses this Software to you only upon the condition that
you accept all of the terms contained in the Software License Agreement ("Agreement")
that is embedded in or that is delivered with this Software. By selecting
the "I ACCEPT" button at the end of the Agreement or by copying, installing,
uploading, accessing or using all or any portion of the Software you agree
to enter into the Agreement. A contract is then formed between Autodesk and
either you personally, if you acquire the Software for yourself, or the company
or other legal entity for which you are acquiring the software.
AUTODESK, INC., MAKES NO WARRANTY, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
PURPOSE REGARDING THESE MATERIALS, AND MAKES SUCH MATERIALS AVAILABLE SOLELY ON AN
"AS-IS" BASIS.
IN NO EVENT SHALL AUTODESK, INC., BE LIABLE TO ANYONE FOR SPECIAL, COLLATERAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING OUT OF PURCHASE
OR USE OF THESE MATERIALS. THE SOLE AND EXCLUSIVE LIABILITY TO AUTODESK, INC.,
REGARDLESS OF THE FORM OF ACTION, SHALL NOT EXCEED THE PURCHASE PRICE OF THE
MATERIALS DESCRIBED HEREIN.
Autodesk, Inc., reserves the right to revise and improve its products as it sees fit.
Autodesk and Open Reality are registered trademarks or trademarks of Autodesk, Inc.,
in the U.S.A. and/or other countries. All other brand names, product names, or
trademarks belong to their respective holders.
GOVERNMENT USE
Use, duplication, or disclosure by the U.S. Government is subject to restrictions as
set forth in FAR 12.212 (Commercial Computer Software-Restricted Rights) and
DFAR 227.7202 (Rights in Technical Data and Computer Software), as applicable.
Manufacturer is Autodesk, Inc., 10 Duke Street, Montreal, Quebec, Canada, H3C 2L7.
***************************************************************************************/
// Class declaration
#include "orconstraint3Dcurvedeformer_constraint.h"
#define ORCONSTRAINT3DCURVEDEFORMER__CLASS ORCONSTRAINT3DCURVEDEFORMER__CLASSNAME
#define ORCONSTRAINT3DCURVEDEFORMER__NAME "3DCurve Deformer"
#define ORCONSTRAINT3DCURVEDEFORMER__LABEL "OR - 3DCurve Deformer"
#define ORCONSTRAINT3DCURVEDEFORMER__DESC "OR - 3DCurve Deformation Constraint"
FBConstraintImplementation ( ORCONSTRAINT3DCURVEDEFORMER__CLASS );
FBRegisterConstraint ( ORCONSTRAINT3DCURVEDEFORMER__NAME,
ORCONSTRAINT3DCURVEDEFORMER__CLASS,
ORCONSTRAINT3DCURVEDEFORMER__LABEL,
ORCONSTRAINT3DCURVEDEFORMER__DESC,
// -------------------------------------------------------------------------
// FBCreate
//
// Constructor
bool ORConstraint3DCurveDeformer::FBCreate()
{
// Notify that this plug-in constraint is NOT "Deformer" constraint
//
// NOTE:
// "Deformer" constraints are evaluated after "Generic" constraints are evaluated.
// Since this plug-in constraint should be evaluated before built-in "path" constraint,
// this plug-in should not be "Deformer" plug-in while this plug-in constraint add deformations
// to 3d Curve.
//
Deformer = false;
// This plug-in constraint doesn't have any custom layout
HasLayout = false;
Description = "3D Curve Deformer Constraint";
// Add reference groups
mReferenceGroup_3DCurve = ReferenceGroupAdd( "Constrained Path", 1 );
mReferenceGroup_Point = ReferenceGroupAdd( "Point", MAX_POINT_NUMBER );
mReferenceGroup_Point_Tangent_In = ReferenceGroupAdd( "Tangent In", MAX_POINT_NUMBER );
mReferenceGroup_Point_Tangent_Out = ReferenceGroupAdd( "Tangent Out", MAX_POINT_NUMBER );
// Initialize member variables
mDummy_AnimationNode = NULL;
m3DCurve_Valid = false;
m3DCurve = NULL;
return true;
}
// -------------------------------------------------------------------------
// FBDestroy
void ORConstraint3DCurveDeformer::FBDestroy()
{
}
// -------------------------------------------------------------------------
// SetupAllAnimationNodes
//
// Set up a dummy input animation node.
void ORConstraint3DCurveDeformer::SetupAllAnimationNodes()
{
// NOTE:
// Depending on setup:
// - Parallel Pipeline (default) - we need to make sure that curve deformation (call to AnimationNodeNotify) is done during the rendering thread run,
// because if we do it during Evaluation we may override Curve data while it's being used for rendering - in best case we will see only jitering, worst case we will crash.
// That's why we use Curve Color to trigger the deformation. As long as it is not constrained by any TRS deformer will be working as expected.
// - Serial Pipeline - doesn't really matter when we will do it. We can link to T, R or S and rendering still will be good.
if(m3DCurve)
{
FBPropertyAnimatable* lLinkToRenderingProperty = (FBPropertyAnimatable*)m3DCurve->PropertyList.Find("Main Color",false);
if(lLinkToRenderingProperty)
{
lLinkToRenderingProperty->SetAnimated(true);
mDummy_AnimationNode = AnimationNodeInCreate ( 0/*Curve_UserId*/, lLinkToRenderingProperty );
}
}
}
// -------------------------------------------------------------------------
// ReferenceAddNotify
// + Bind referenced 3d curve.
bool ORConstraint3DCurveDeformer::ReferenceAddNotify( int pGroupIndex, FBModel* pModel )
{
if ( pGroupIndex == mReferenceGroup_3DCurve )
{
if ( pModel->Is( FBModelPath3D::TypeInfo) ){
m3DCurve_Valid = true;
m3DCurve = (FBModelPath3D*)pModel;
}
else {
// Group [Deformable 3D Curve] has a model other than 3d curve
// Mark m3DCurve_Valid invalid.
m3DCurve_Valid = false;
}
}
return true;
}
// -------------------------------------------------------------------------
// ReferenceRemoveNotify
// + Unbind referenced 3d curve.
bool ORConstraint3DCurveDeformer::ReferenceRemoveNotify( int pGroupIndex, FBModel* pModel )
{
if ( pGroupIndex == mReferenceGroup_3DCurve )
{
m3DCurve = NULL;
m3DCurve_Valid = false;
}
return true;
}
// -------------------------------------------------------------------------
// AnimationNodeNotify
// + Retrieve referencing model positions
// + Deform 3d curve and update it
bool ORConstraint3DCurveDeformer::AnimationNodeNotify(
FBAnimationNode* pConnector,
FBEvaluateInfo* pEvaluateInfo,
FBConstraintInfo* pConstraintInfo
)
{
if ( m3DCurve_Valid ) {
for ( int i = 0; i < m3DCurve->PathKeyGetCount(); i++ )
{
if ( ReferenceGet( mReferenceGroup_Point, i ) )
{
// A models to control point is specified
// Retrieve position of the model
FBVector3d posPoint(0,0,0);
ReferenceGet( mReferenceGroup_Point, i )->GetVector( posPoint, kModelTranslation, true );
if ( ReferenceGet( mReferenceGroup_Point_Tangent_Out, i ) && ReferenceGet( mReferenceGroup_Point_Tangent_In, i ) )
{
// A models to control tangent In/Out are specified.
// Retrieve positions of these models.
//
FBVector3d posPoint_TangentIn;
FBVector3d posPoint_TangentOut;
ReferenceGet( mReferenceGroup_Point_Tangent_In, i )->GetVector( posPoint_TangentIn, kModelTranslation, true );
ReferenceGet( mReferenceGroup_Point_Tangent_Out, i )->GetVector( posPoint_TangentOut, kModelTranslation, true );
// Set point and IN/Out tangent.
m3DCurve->PathKeySetLeftRightTangent( i , (FBVector4d)posPoint, (FBVector4d)posPoint_TangentIn, (FBVector4d)posPoint_TangentOut, false );
}
else
{
// Models for setting tangent In/Out are not specified.
// Set point only.
m3DCurve->PathKeySet( i , (FBVector4d)posPoint, false );
}
}
}
m3DCurve->UpdateGeometry();
}
return true;
}
// -------------------------------------------------------------------------
// SnapSuggested
// + Snap 3d curve to origin point.
void ORConstraint3DCurveDeformer::SnapSuggested()
{
// This is an optional feature.
// Since this constraint plug-in apply deformation in local space,
// 3d curve must be in origin point and have no scaling.
if ( m3DCurve_Valid ) {
m3DCurve -> SetVector( FBVector3d( 0, 0, 0 ), kModelTranslation, true);
m3DCurve -> SetVector( FBVector3d( 0, 0, 0 ), kModelRotation, true);
m3DCurve -> SetVector( FBVector3d( 1, 1, 1 ), kModelScaling, true);
}
}