deargui-vpl/ref/virtools/Samples/Behaviors/ParticlesSystem/behaviors src/ClothSystemBB.cpp

285 lines
6.1 KiB
C++

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//
// ClothSystem
//
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
#include "CKAll.h"
#include "ParticleManager.h"
#include "ClothSystem.h"
CKERROR CreateClothSystemProto(CKBehaviorPrototype **);
int ClothSystemFunction(const CKBehaviorContext& behcontext);
CKERROR ClothSystemCallback(const CKBehaviorContext& behcontext);
CKObjectDeclaration *FillBehaviorClothSystemDecl()
{
CKObjectDeclaration *od = CreateCKObjectDeclaration("Cloth System");
od->SetDescription("Creates a cloth system (spring & mass system).");
od->SetType( CKDLL_BEHAVIORPROTOTYPE);
od->SetGuid(CKGUID(0x67c59347,0x6710721e));
od->SetAuthorGuid(VIRTOOLS_GUID);
od->SetAuthorName("Virtools");
od->SetVersion(0x00010000);
od->SetCreationFunction(CreateClothSystemProto);
od->SetCompatibleClassId(CKCID_3DENTITY);
od->SetCategory("Particles/Cloth");
od->NeedManager(PARTICLE_MANAGER_GUID);
return od;
}
CKERROR CreateClothSystemProto(CKBehaviorPrototype **pproto)
{
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Cloth System");
if(!proto) return CKERR_OUTOFMEMORY;
proto->DeclareInput("On");
proto->DeclareInput("Off");
proto->DeclareOutput("Exit On");
proto->DeclareOutput("Exit Off");
proto->DeclareInParameter("Hang Array",CKPGUID_DATAARRAY);
proto->DeclareInParameter("Material",CKPGUID_MATERIAL);
proto->DeclareInParameter("Point Mass",CKPGUID_FLOAT, "1");
proto->DeclareInParameter("Damping",CKPGUID_FLOAT, "0.95");
proto->DeclareInParameter("Tightness",CKPGUID_FLOAT, "1");
proto->DeclareInParameter("Gravity",CKPGUID_VECTOR, "0,-9.8,0");
proto->DeclareInParameter("Iterations",CKPGUID_INT, "1");
proto->DeclareLocalParameter(NULL,CKPGUID_POINTER); // the system
// Settings
proto->DeclareSetting("Grid Resolution",CKPGUID_2DVECTOR,"30,30");
proto->DeclareSetting("Grid Size",CKPGUID_2DVECTOR,"10,10");
proto->DeclareSetting("Grid Mapping",CKPGUID_2DVECTOR,"10,10");
proto->DeclareSetting("Back Material",CKPGUID_MATERIAL);
proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
proto->SetFunction(ClothSystemFunction);
proto->SetBehaviorCallbackFct( ClothSystemCallback );
proto->SetBehaviorFlags(CKBEHAVIOR_TARGETABLE);
*pproto = proto;
return CK_OK;
}
enum IO {
On,
Off
};
enum Inputs {
Array,
Material,
PointMass,
Damping,
Tightness,
Gravity,
Iterations
};
int ClothSystemFunction(const CKBehaviorContext& behcontext)
{
CKBehavior* beh = behcontext.Behavior;
ClothSystem* cs = NULL;
beh->GetLocalParameterValue(0,&cs);
if (beh->IsInputActive(On)) { // On
beh->ActivateInput(On,FALSE);
beh->ActivateOutput(On);
} else
if (beh->IsInputActive(Off)) { // Off
beh->ActivateInput(Off,FALSE);
beh->ActivateOutput(Off);
return CKBR_OK;
}
// Set the referential
cs->SetReferential((CK3dEntity*)beh->GetTarget());
///
// Set hook points
{
cs->ClearHooks();
CKDataArray* array = (CKDataArray*)beh->GetInputParameterObject(Array);
if (array && (array->GetColumnCount() >= 2) && (array->GetColumnParameterGuid(1) == CKPGUID_2DVECTOR)) {
int count = array->GetRowCount();
for (int i=0; i<count; ++i) {
CK3dEntity* ent = (CK3dEntity*)array->GetElementObject(i,0);
Vx2DVector v2;
array->GetElementValue(i,1,&v2);
cs->SetHook(ent, v2);
}
}
}
// Set Materials
CKMaterial* mat = (CKMaterial*)beh->GetInputParameterObject(Material);
cs->SetMaterial(mat);
// Point Mass
float pointMass = 1.0f;
beh->GetInputParameterValue(PointMass,&pointMass);
cs->SetPointMass(pointMass);
// Damping
float damping = 1.0f;
beh->GetInputParameterValue(Damping,&damping);
cs->SetDamping(damping);
// Tightness
float tightness = 1.0f;
beh->GetInputParameterValue(Tightness,&tightness);
cs->SetTightness(tightness);
// Gravity
VxVector g(0,-9.8f,0);
beh->GetInputParameterValue(Gravity,&g);
cs->SetGravity(g);
// Iterations
int iterations = 1;
beh->GetInputParameterValue(Iterations,&iterations);
cs->SetIterations(iterations);
///
// The Updating
cs->Update(behcontext.DeltaTime);
return CKBR_ACTIVATENEXTFRAME;
}
CKERROR ClothSystemCallback(const CKBehaviorContext& behcontext)
{
CKBehavior* beh = behcontext.Behavior;
CKContext* ctx = behcontext.Context;
ClothSystem* cs = NULL;
beh->GetLocalParameterValue(0,&cs);
switch (behcontext.CallbackMessage) {
case CKM_BEHAVIORCREATE:
case CKM_BEHAVIORLOAD:
{
cs = new ClothSystem(ctx);
beh->SetLocalParameterValue(0, &cs);
if (behcontext.CallbackMessage == CKM_BEHAVIORLOAD) {
cs->SetReferential((CK3dEntity*)beh->GetTarget());
}
}
case CKM_BEHAVIORSETTINGSEDITED:
{
Vx2DVector res;
beh->GetLocalParameterValue(1,&res);
Vx2DVector size;
beh->GetLocalParameterValue(2,&size);
Vx2DVector msize;
beh->GetLocalParameterValue(3,&msize);
CKMaterial* mat = (CKMaterial*)beh->GetInputParameterObject(Material);
CKMaterial* backmat = (CKMaterial*)beh->GetLocalParameterObject(4);
cs->Tesselate(res, size, msize, mat, backmat);
}
break;
case CKM_BEHAVIORATTACH:
{
cs->SetReferential((CK3dEntity*)beh->GetTarget());
}
break;
case CKM_BEHAVIORDETACH:
{
cs->SetReferential(NULL);
}
break;
case CKM_BEHAVIORDELETE:
{
delete cs;
}
break;
case CKM_BEHAVIORPOSTSAVE:
{
}
break;
case CKM_BEHAVIORRESET:
{
// TODO : do not recreate everything, only reset the positions
cs->SetReferential((CK3dEntity*)beh->GetTarget());
Vx2DVector res;
beh->GetLocalParameterValue(1,&res);
Vx2DVector size;
beh->GetLocalParameterValue(2,&size);
Vx2DVector msize;
beh->GetLocalParameterValue(3,&msize);
CKMaterial* mat = (CKMaterial*)beh->GetInputParameterObject(Material);
CKMaterial* backmat = (CKMaterial*)beh->GetLocalParameterObject(4);
cs->Tesselate(res, size, msize, mat, backmat);
}
break;
case CKM_BEHAVIORPAUSE:
{
}
case CKM_BEHAVIORDEACTIVATESCRIPT:
{
}
break;
case CKM_BEHAVIORPRESAVE:
{
}
break;
case CKM_BEHAVIORRESUME:
{
}
case CKM_BEHAVIORACTIVATESCRIPT:
{
}
break;
}
return CKBR_OK;
}