#include "lib_hair.h" #include "c4d_objectdata.h" #include "c4d_scenehookplugin.h" ////////////////////////////////////////////////////////////////////////// HairObjectLib *lib_hair = nullptr; HairColliderLib *lib_hair_collider = nullptr; static HairObjectLib *CheckHairObjectLib(Int32 offset) { return (HairObjectLib*)CheckLib(LIBRARY_HAIR,offset,(C4DLibrary**)&lib_hair); } static HairColliderLib *CheckHairColliderLib(Int32 offset) { return (HairColliderLib*)CheckLib(LIBRARY_HAIR_COLLIDER,offset,(C4DLibrary**)&lib_hair_collider); } #define HairObjectLibCall(b) HairObjectLib *lib = CheckHairObjectLib(LIBOFFSET(HairObjectLib, b)); \ if (!lib || !lib->b) return; \ (lib->b) #define HairObjectLibCallR(a,b) HairObjectLib *lib = CheckHairObjectLib(LIBOFFSET(HairObjectLib, b)); \ if (!lib || !lib->b) return a; \ return (lib->b) #define HairColliderLibCall(b) HairColliderLib *lib = CheckHairColliderLib(LIBOFFSET(HairColliderLib, b)); \ if (!lib || !lib->b) return; \ (((iHairCollider*)this)->*lib->b) #define HairColliderLibCallR(a,b) HairColliderLib *lib = CheckHairColliderLib(LIBOFFSET(HairColliderLib, b)); \ if (!lib || !lib->b) return a; \ return (((iHairCollider*)this)->*lib->b) ////////////////////////////////////////////////////////////////////////// #ifndef __API_INTERN__ Bool HairObject::Lock(BaseDocument *pDoc, BaseThread *pThread, Bool bValidate, Int32 flags) { HairObjectLibCallR(false,Lock)(this,pDoc,pThread,bValidate,flags); } void HairObject::Unlock() { HairObjectLibCall(Unlock)(this); } Bool HairObject::IsLocked() { HairObjectLibCallR(false,hairIsLocked)(this); } #endif HairGuides *HairObject::GetGuides() { HairObjectLibCallR(nullptr,GetGuides)(this); } HairGuides *HairObject::GetDynamicGuides() { HairObjectLibCallR(nullptr,GetDynamicGuides)(this); } Bool HairObject::GetRootObject(BaseObject **pObject, BaseTag **pTag, RootObjectData *pData) { HairObjectLibCallR(false,GetRootObject)(this,pObject,pTag,pData); } HairGuides *HairObject::GenerateHair(Int32 flags, Int32 count, Int32 segments, HairMaterialData **pMaterial, HairInterpolationMap *pMap) { HairObjectLibCallR(nullptr,GenerateHair)(this,flags,count,segments,pMaterial,pMap); } Bool HairObject::SetGuides(HairGuides *guides, Bool clone) { HairObjectLibCallR(false,SetGuides)(this,guides,clone); } void HairObject::RemoveGuides() { HairObjectLibCall(RemoveGuides)(this); } Bool HairObject::Update(BaseDocument *doc) { ObjectData *odata=(ObjectData*)GetNodeData(); if (!odata) return false; return odata->Execute(this,doc,nullptr,0,EXECUTIONFLAGS_EXPRESSION)==EXECUTIONRESULT_OK; } HairMaterialData *HairObject::InitMaterials(const InitRenderStruct &irs, BaseDocument *pDoc, HairGuides *guides, VolumeData *vd) { HairObjectLibCallR(nullptr,InitMaterials)(irs,this,pDoc,guides,vd); } void HairObject::FreeMaterials(HairMaterialData *&pMaterials) { HairObjectLibCall(FreeMaterials)(this,pMaterials); } ////////////////////////////////////////////////////////////////////////// HairGuides *HairGuides::Alloc(Int32 count, Int32 segments) { HairObjectLibCallR(nullptr,AllocGuides)(count,segments); } void HairGuides::Free(HairGuides *&guides) { HairObjectLibCall(FreeGuides)(guides); } Int32 HairGuides::GetCount() { HairObjectLibCallR(0,GetGuideCount)(this); } Int32 HairGuides::GetSegmentCount() { HairObjectLibCallR(0,GetGuideSegmentCount)(this); } Vector *HairGuides::GetPoints() { HairObjectLibCallR(nullptr,GetGuidePoints)(this); } HairGuideDynamics *HairGuides::GetDynamics() { HairObjectLibCallR(nullptr,GetGuideDynamics)(this); } Matrix HairGuides::GetMg() { HairObjectLibCallR(Matrix(),GetGuideMg)(this); } void HairGuides::SetMg(const Matrix &mg) { HairObjectLibCall(SetGuideMg)(this,mg); } HairRootData HairGuides::GetRoot(Int32 index) { HairObjectLibCallR(HairRootData(),GetGuideRoot)(this,index); } void HairGuides::SetRoot(Int32 index, const HairRootData &root, Bool update) { HairObjectLibCall(SetGuideRoot)(this,index,root,update); } HairObject *HairGuides::GetObject() { HairObjectLibCallR(nullptr,GetGuideObject)(this); } Bool HairGuides::GetSelected(Int32 mode, BaseSelect *select) { HairObjectLibCallR(false,GetGuideSelected)(this,mode,select); } Bool HairGuides::CopyFrom(const HairGuides *src) { HairObjectLibCallR(false,CopyGuidesFrom)(this,src); } Bool HairGuides::SetSelected(Int32 mode, BaseSelect *select) { HairObjectLibCallR(false,SetGuideSelected)(this,mode,select); } Bool HairGuides::ConvertSelection(Int32 from_mode, Int32 to_mode, BaseSelect *from_select, BaseSelect *to_select) { HairObjectLibCallR(false,ConvertGuideSelection)(this,from_mode,to_mode,from_select,to_select); } Vector HairGuides::GetTangent(Int32 guide, Int32 segment, Float t) { HairObjectLibCallR(Vector(0.0),GetGuideTangent)(this,guide,segment,t); } SplineObject *HairGuides::CreateSpline() { HairObjectLibCallR(nullptr,CreateGuideSpline)(this); } void HairGuides::ToLocal() { HairObjectLibCall(guideToLocal)(this); } void HairGuides::ToWorld() { HairObjectLibCall(guideToWorld)(this); } void HairGuides::ToInitial(Bool align) { HairObjectLibCall(guideToInitial)(this,align); } void HairGuides::UndisplaceRoots() { HairObjectLibCall(guideUndisplaceRoots)(this); } void HairGuides::DisplaceRoots() { HairObjectLibCall(guideDisplaceRoots)(this); } Bool HairGuides::GetRootAxis(Int32 index, Matrix &m, Bool bAlign, Bool bLocal, Bool bInitial, Bool bZAxis) { HairObjectLibCallR(false,guideGetRootAxis)(this,index,m,bAlign,bLocal,bInitial,bZAxis); } Vector HairGuides::GetRootUV(Int32 index) { HairObjectLibCallR(Vector(),guideGetRootUV)(this,index); } Bool HairGuides::GetRootData(Int32 index, Vector *p, Vector *n, Int32 *ply_id, Bool bLocal, Bool bDisplaced, Bool bInitial) { HairObjectLibCallR(false,guideGetRootData)(this,index,p,n,ply_id,bLocal,bDisplaced,bInitial); } Matrix *HairGuides::GetTransformMatrix() { HairObjectLibCallR(nullptr,guideGetTransformMatrix)(this); } void HairGuides::SetTransformMatrix(Matrix *tm) { HairObjectLibCall(guideSetTransformMatrix)(this,tm); } Bool HairGuides::Delete(BaseSelect *bs) { HairObjectLibCallR(false,guideDelete)(this,bs); } Bool HairGuides::AddRoot(Int32 ply_id, Float s, Float t, Float len) { HairObjectLibCallR(false,guideAddRoot)(this,ply_id,s,t,len); } Bool HairGuides::GetRootObject(RootObjectData *pData) { HairObjectLibCallR(false,guideGetRootObject)(this,pData); } Bool HairGuides::LinkToObject(HairObject *pHair) { HairObjectLibCallR(false,guideLinkToObject)(this,pHair); } Int32 HairGuides::GetFlags() { HairObjectLibCallR(false,guideGetFlags)(this); } Int32 HairGuides::SetFlags(Int32 flags) { HairObjectLibCallR(false,guideSetFlags)(this,flags); } ////////////////////////////////////////////////////////////////////////// HairGuides *HairGuideDynamics::GetGuides() { HairObjectLibCallR(nullptr,GetDynamicsGuides)(this); } Vector HairGuideDynamics::GetPosition(Int32 i) { HairObjectLibCallR(Vector(),GetDynamicsPosition)(this,i); } void HairGuideDynamics::SetPosition(Int32 i, const Vector &p) { HairObjectLibCall(SetDynamicsPosition)(this,i,p); } Vector HairGuideDynamics::GetLastPosition(Int32 i) { HairObjectLibCallR(Vector(),GetDynamicsLastPosition)(this,i); } void HairGuideDynamics::SetLastPosition(Int32 i, const Vector &p) { HairObjectLibCall(SetDynamicsLastPosition)(this,i,p); } Vector HairGuideDynamics::GetVelocity(Int32 i) { HairObjectLibCallR(Vector(),GetDynamicsVelocity)(this,i); } void HairGuideDynamics::SetVelocity(Int32 i, const Vector &v) { HairObjectLibCall(SetDynamicsVelocity)(this,i,v); } Float HairGuideDynamics::GetMass(Int32 i) { HairObjectLibCallR(0.0,GetDynamicsMass)(this,i); } void HairGuideDynamics::SetMass(Int32 i, Float m) { HairObjectLibCall(SetDynamicsMass)(this,i,m); } Vector HairGuideDynamics::GetForce(Int32 i) { HairObjectLibCallR(Vector(),GetDynamicsForce)(this,i); } void HairGuideDynamics::AddForce(Int32 i, const Vector &f) { HairObjectLibCall(AddDynamicsForce)(this,i,f); } Int32 HairGuideDynamics::GetPolygonIntersections(HairPolygonHit **hits) { HairObjectLibCallR(0,GetDynamicsPolygonIntersections)(this,hits); } ////////////////////////////////////////////////////////////////////////// Int32 HairLibrary::GetMode(BaseDocument *doc) { HairObjectLibCallR(0,hairGetMode)(doc); } void HairLibrary::SetMode(BaseDocument *doc, Int32 mode) { HairObjectLibCall(hairSetMode)(doc,mode); } Bool HairLibrary::GetHairGlobal(BaseDocument* doc) { HairObjectLibCallR(0,hairGetHairGlobal)(doc); } void HairLibrary::SetHairGlobal(BaseDocument* doc, Bool enable) { HairObjectLibCall(hairSetHairGlobal)(doc,enable); } Vector HairLibrary::BlendColors(Int32 mode, const Vector &colA, const Vector &colB) { HairObjectLibCallR(Vector(0.0),hairBlendColors)(mode,colA,colB); } Vector HairLibrary::MixST(Float s, Float t, const Vector &pa, const Vector &pb, const Vector &pc, const Vector &pd, Bool bQuad) { HairObjectLibCallR(Vector(0.0),hairMixST)(s,t,pa,pb,pc,pd,bQuad); } Float HairLibrary::MixST(Float s, Float t, Float va, Float vb, Float vc, Float vd, Bool bQuad) { HairObjectLibCallR(0,hairMixSTReal)(s,t,va,vb,vc,vd,bQuad); } void HairLibrary::GetPolyPointST(const Vector &p, Float &s, Float &t, const Vector &pa, const Vector &pb, const Vector &pc, const Vector &pd, Bool bQuad) { HairObjectLibCall(hairGetPolyPointST)(p,s,t,pa,pb,pc,pd,bQuad); } void *HairLibrary::GetHook(BaseDocument *doc, Int32 type) { HairObjectLibCallR(nullptr,hairGetHook)(doc,type); } void *HairLibrary::SetHook(BaseDocument *doc, Int32 type, void *fn) { HairObjectLibCallR(nullptr,hairSetHook)(doc,type,fn); } BaseContainer *HairLibrary::GetPrefsInstance() { HairObjectLibCallR(nullptr,hairGetPrefsInstance)(); } Int32 HairLibrary::GetHairVersion() { HairObjectLibCallR(0,hairGetHairVersion)(); } ////////////////////////////////////////////////////////////////////////// Bool HairSelectionTag::GetSelected(BaseSelect *bs) { HairObjectLibCallR(false,HairSelectionGetSelected)(this,bs); } Bool HairSelectionTag::SetSelected(BaseSelect *bs) { HairObjectLibCallR(false,HairSelectionSetSelected)(this,bs); } Int32 HairSelectionTag::GetSelectionType() { HairObjectLibCallR(0,HairSelectionGetType)(this); } void HairSelectionTag::SetSelectionType(Int32 mode) { HairObjectLibCall(HairSelectionSetType)(this,mode); } Int32 HairSelectionTag::GetCount() { HairObjectLibCallR(0,HairSelectionGetCount)(this); } Int32 HairSelectionTag::GetSegments() { HairObjectLibCallR(0,HairSelectionGetSegments)(this); } ////////////////////////////////////////////////////////////////////////// Int32 HairVertexMapTag::GetCount() { HairObjectLibCallR(0,HairVertexGetCount)(this); } Int32 HairVertexMapTag::GetSegments() { HairObjectLibCallR(0,HairVertexGetSegments)(this); } Int32 HairVertexMapTag::GetPointCount() { HairObjectLibCallR(0,HairVertexGetPointCount)(this); } UInt16 *HairVertexMapTag::GetMap() { HairObjectLibCallR(nullptr,HairVertexGetMap)(this); } ////////////////////////////////////////////////////////////////////////// Int32 HairTangentTag::GetPolygonsSegments() { HairObjectLibCallR(0,HairTangentGetPolygonsSegments)(this); } Int32 HairTangentTag::GetPointCount() { HairObjectLibCallR(0,HairTangentGetPointCount)(this); } Int32 HairTangentTag::GetCount() { HairObjectLibCallR(0,HairTangentGetCount)(this); } Int32 HairTangentTag::GetSegments() { HairObjectLibCallR(0,HairTangentGetSegments)(this); } Vector *HairTangentTag::GetTangent() { HairObjectLibCallR(nullptr,HairTangentGetTangent)(this); } ////////////////////////////////////////////////////////////////////////// Int32 HairMaterialData::GetCount() { HairObjectLibCallR(0,matGetCount)(this); } Int32 HairMaterialData::GetGuideMaterial(Int32 i, Int32 prev) { HairObjectLibCallR(NOTOK,matGetGuideMaterial)(this,i,prev); } BaseTag *HairMaterialData::GetMaterialTag(Int32 i) { HairObjectLibCallR(nullptr,matGetMaterialTag)(this,i); } Bool HairMaterialData::ApplyMaterial(Int32 i, HairGuides *guides, VolumeData *vd, Int32 vindex) { HairObjectLibCallR(false,matApplyMaterial)(this,i,guides,vd,vindex); } Bool HairMaterialData::ApplyMaterials(HairGuides *guides, VolumeData *vd, Int32 vindex) { HairObjectLibCallR(false,matApplyMaterials)(this,guides,vd,vindex); } Float HairMaterialData::GetThickness(Int32 guide, Float t, Int32 i) { HairObjectLibCallR(0.0,matGetThickness)(this,guide,t,i); } Vector HairMaterialData::GetColor(Int32 guide, Float t, const Vector &r, const Vector &wp, const Vector &p, const Vector &n, VolumeData *vd, const RayHitID &plyid, Int32 i) { HairObjectLibCallR(Vector(0.0),matGetColor)(this,guide,t,r,wp,p,n,vd,plyid,i); } Vector HairMaterialData::GetBackColor(Int32 guide, Float t, const Vector &col, const Vector &r, const Vector &wp, const Vector &p, const Vector &n, VolumeData *vd, const RayHitID &plyid, Int32 i) { HairObjectLibCallR(Vector(0.0),matGetBackColor)(this,guide,t,col,r,wp,p,n,vd,plyid,i); } Bool HairMaterialData::GetSpecularColor(Int32 guide, Float t, const Vector &wp, const Vector &p, const Vector &n, VolumeData *vd, const RayHitID &plyid, Vector &speccol, Vector &ispeccol) { HairObjectLibCallR(false, matGetSpecularColor)(this,guide,t,wp,p,n,vd,plyid,speccol,ispeccol); } Float HairMaterialData::GetTransparency(Int32 guide, Float t, const Vector &p, const Vector &n, VolumeData* vd, Int32 i) { HairObjectLibCallR(0.0,matGetTransparency)(this,guide,t,p,n,vd,i); } Bool HairMaterialData::GetTagSelection(Int32 i, BaseSelect *bs) { HairObjectLibCallR(false,matGetTagSelection)(this,i,bs); } Bool HairMaterialData::GetMaterialData(Int32 guide, Float &shadows, Float &selfshadows, Float &backshadows, Float &transparency, Float &diffuse, Float &reflect, Float &transmit, Bool &roughenable, Float &roughvar, Float &roughness, Bool &specularenable, Float &specular, Float &specularpower, Float &specularback, Bool &ispecularenable, Bool &ispecularshader, Float &ispecular, Float &ispecularpower, Float &ispecularmix, Float &ispecularblend) { HairObjectLibCallR(false,matGetMaterialData)(this, guide, shadows, selfshadows, backshadows, transparency, diffuse, reflect, transmit, roughenable, roughvar, roughness, specularenable, specular, specularpower, specularback, ispecularenable, ispecularshader, ispecular, ispecularpower, ispecularmix, ispecularblend); } Bool HairMaterialData::GetGIData(Int32 guide, Bool &receive, Float &strength) { HairObjectLibCallR(false, matGetGIData)(this,guide,receive,strength); } Bool HairMaterialData::AdjustHUV(Int32 guide, Vector &huv, Float tline) { HairObjectLibCallR(false,matAdjustHUV)(this,guide,huv,tline); } ////////////////////////////////////////////////////////////////////////// Int32 HairVideoPost::GetObjectCount() { HairObjectLibCallR(0,vpGetObjectCount)(this); } void HairVideoPost::GetObject(Int32 i, HairRenderObject *hro) { HairObjectLibCall(vpGetObject)(this,i,hro); } Int32 HairVideoPost::FindObject(BaseList2D *bl) { HairObjectLibCallR(NOTOK,vpFindObject)(this,bl); } Bool HairVideoPost::TracerEnabled() { HairObjectLibCallR(false,vpTracerEnabled)(this); } Int32 HairVideoPost::TraceRay(const Vector &p, const Vector &v, Vector &hit, Float &d, Int32 cpu, Float tf, Int32 flags) { HairObjectLibCallR(NOTOK,vpTraceRay)(this,p,v,hit,d,cpu,tf,flags); } void HairVideoPost::GetHitInfo(Int32 id, HairHitData *hdata) { HairObjectLibCall(vpGetHitInfo)(this,id,hdata); } Bool HairVideoPost::IsLightEnabled(Int32 oindex, RayLight *light, Bool *nodiff, Bool *nospec) { HairObjectLibCallR(false,vpIsLightEnabled)(this,oindex,light,nodiff,nospec); } Bool HairVideoPost::ShadowsEnabled() { HairObjectLibCallR(false,vpShadowsEnabled)(this); } UInt32 HairVideoPost::GetCompositeFlags(Int32 oindex) { HairObjectLibCallR(0, vpGetCompositeFlags)(this, oindex); } void HairVideoPost::Sample(Int32 oindex, VolumeData *vd, Int32 cpu, Int32 lid, Int32 seg, Int32 p, Float lined, const Vector &linep, const Vector &v, Vector &col, const Vector &n, const Vector &lp, const Vector &t, const Vector &r, Vector huv, Int32 flags) { HairObjectLibCall(vpSample)(this,oindex,vd,cpu,lid,seg,p,lined,linep,v,col,n,lp,t,r,huv,flags); } Float HairVideoPost::SampleTransparency(Int32 oindex, VolumeData *vd, Int32 lid, Int32 seg, Int32 p, Float lined, const Vector &n, const Vector &linep, const Vector &lp, Vector huv, Int32 cpu, Int32 flags, RayLight *light) { HairObjectLibCallR(1.0,vpSampleTransparency)(this,oindex,vd,lid,seg,p,lined,n,linep,lp,huv,cpu,flags,light); } Float HairVideoPost::SampleShadow(VolumeData *vd, RayLight *light, const Vector &p, Float delta, Int32 cpu, Int32 flags) { HairObjectLibCallR(1.0,vpSampleShadow)(this,vd,light,p,delta,cpu,flags); } Bool HairVideoPost::GetTopFragment(Int32 x, Int32 y, HairFragment *frag, Int32 cpu) { HairObjectLibCallR(false,vpGetTopFragment)(this,x,y,frag,cpu); } Bool HairVideoPost::GetFragmentLink(Int32 x, Int32 y, HairFragmentLink *frag, Int32 cpu, Bool first) { HairObjectLibCallR(false,vpGetFragmentLink)(this,x,y,frag,cpu,first); } HairFragment *HairVideoPost::GetFragments(Int32 x, Int32 y, Int32 &cnt, Int32 cpu) { HairObjectLibCallR(nullptr,vpGetFragments)(this,x,y,cnt,cpu); } Bool HairVideoPost::SetFragments(Int32 x, Int32 y, HairFragment *frag, Int32 cnt, Int32 cpu) { HairObjectLibCallR(false,vpSetFragments)(this,x,y,frag,cnt,cpu); } Bool HairVideoPost::InsertFragment(Int32 x, Int32 y, HairFragment *frag, Int32 cnt, Int32 cpu) { HairObjectLibCallR(false,vpInsertFragment)(this,x,y,frag,cnt,cpu); } Bool HairVideoPost::InsertFragmentLine(Int32 x, Int32 y, Int32 xcnt, HairFragment **frag, Int32 *cnt, Int32 cpu) { HairObjectLibCallR(false,vpInsertFragmentLine)(this,x,y,xcnt,frag,cnt,cpu); } ////////////////////////////////////////////////////////////////////////// HairCollider* HairCollider::Alloc() { HairColliderLib *lib = CheckHairColliderLib(LIBOFFSET(HairColliderLib,Alloc)); if (!lib) return nullptr; return (HairCollider*)lib->Alloc(); } void HairCollider::Free(HairCollider *&p) { if (!p) return; HairColliderLib *lib = CheckHairColliderLib(LIBOFFSET(HairColliderLib,Free)); if (!lib) return; iHairCollider* i = (iHairCollider*)p; lib->Free(i); p = nullptr; } Bool HairCollider::Init(HairGuides *hair) { HairColliderLibCallR(false,Init)(hair); } void HairCollider::Release() { HairColliderLibCall(Release)(); } Int32 HairCollider::GetClosestPoint(const Vector &p) { HairColliderLibCallR(NOTOK,GetClosestPoint)(p); } Bool HairCollider::GetParticleIntersection(const Vector &p, const Vector &v, Float r, Int32 *guide, Int32 *segment, Float *segt, Float *rayt) { HairColliderLibCallR(false,GetParticleIntersection)(p,v,r,guide,segment,segt,rayt); } Bool HairCollider::GetClosestSegment(const Vector &p, Int32 *guide, Int32* segment, Float* segt) { HairColliderLibCallR(false,GetClosestSegment)(p,guide,segment,segt); } ////////////////////////////////////////////////////////////////////////// Float64 HairInterpolationMap::GetTotalWeight(Int32 index) { if (!m_pMap) return 0.0; Float64 total=0.0; Int32 i,j=index*m_WeightCount; for (i=0;i