Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add invert option #22

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
3 changes: 2 additions & 1 deletion res/description/oProjector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ enum
PROJECTOR_OFFSET = 10003, // REAL
PROJECTOR_BLEND = 10004, // REAL
PROJECTOR_GEOMFALLOFF_ENABLE = 10005, // BOOL
PROJECTOR_GEOMFALLOFF_DIST = 10006 // REAL
PROJECTOR_GEOMFALLOFF_DIST = 10006, // REAL
PROJECTOR_INVERT = 10007 // BOOL
};

#endif
16 changes: 9 additions & 7 deletions res/description/oProjector.res
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@ CONTAINER oProjector
NAME oProjector;
INCLUDE Obase;

GROUP PROJECTOR_GROUP_PARAMS
GROUP PROJECTOR_GROUP_PARAMS
{
DEFAULT 1;

LINK PROJECTOR_LINK { ACCEPT { Obase; } }
LONG PROJECTOR_MODE
LINK PROJECTOR_LINK { ACCEPT { Obase; } }
LONG PROJECTOR_MODE
{
CYCLE
{
PROJECTOR_MODE_PARALLEL;
PROJECTOR_MODE_SPHERICAL;
}
}
REAL PROJECTOR_OFFSET { UNIT METER; MINSLIDER -50.0; MAXSLIDER 50.0; CUSTOMGUI REALSLIDER; }
REAL PROJECTOR_BLEND { UNIT PERCENT; MIN 0.0; MAX 100.0; CUSTOMGUI REALSLIDER; }
BOOL PROJECTOR_INVERT { }

BOOL PROJECTOR_GEOMFALLOFF_ENABLE { }
REAL PROJECTOR_GEOMFALLOFF_DIST { UNIT METER; MIN 0.0; STEP 1.0; }
REAL PROJECTOR_OFFSET { UNIT METER; MINSLIDER -50.0; MAXSLIDER 50.0; CUSTOMGUI REALSLIDER; }
REAL PROJECTOR_BLEND { UNIT PERCENT; MIN 0.0; MAX 100.0; CUSTOMGUI REALSLIDER; }

BOOL PROJECTOR_GEOMFALLOFF_ENABLE { }
REAL PROJECTOR_GEOMFALLOFF_DIST { UNIT METER; MIN 0.0; STEP 1.0; }
}
}
1 change: 1 addition & 0 deletions res/strings_de/description/oProjector.str
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ STRINGTABLE oProjector
PROJECTOR_MODE "Modus";
PROJECTOR_MODE_PARALLEL "Parallel";
PROJECTOR_MODE_SPHERICAL "Sph\u00E4risch";
PROJECTOR_INVERT "Invertieren";
PROJECTOR_OFFSET "Versatz";
PROJECTOR_BLEND "Blenden";
PROJECTOR_GEOMFALLOFF_ENABLE "Geometrie-Falloff";
Expand Down
1 change: 1 addition & 0 deletions res/strings_us/description/oProjector.str
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ STRINGTABLE oProjector
PROJECTOR_MODE "Mode";
PROJECTOR_MODE_PARALLEL "Parallel";
PROJECTOR_MODE_SPHERICAL "Spherical";
PROJECTOR_INVERT "Invert";
PROJECTOR_OFFSET "Offset";
PROJECTOR_BLEND "Blend";
PROJECTOR_GEOMFALLOFF_ENABLE "Geometry Falloff";
Expand Down
57 changes: 57 additions & 0 deletions source/lib/wsFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,60 @@ FieldLayer* IterateNextFieldLayer(FieldLayer* layer)

return layer->GetNext();
}


Bool IsValidFieldLayer(FieldLayer* fieldLayer, BaseDocument* doc)
{
// Check pointer
if (!fieldLayer)
return false;

// Flagged as no-to-be-used (doesn't seem to work, flags are never set)
const FIELDLAYER_FLAG layerFlags = fieldLayer->GetLayerFlags();
if (layerFlags&FIELDLAYER_FLAG::SKIP ||
layerFlags&FIELDLAYER_FLAG::ERRORSKIP ||
layerFlags&FIELDLAYER_FLAG::HIDE ||
layerFlags&FIELDLAYER_FLAG::TEMPORARY)
return false;

// Dead link but not a folder (once the flags actually work, the first line can be removed)
if (!fieldLayer->GetLinkedObject(doc)._object &&
fieldLayer->GetType() != FLfolder)
return false;

return true;
}


Bool IsActiveFieldLayer(FieldLayer* fieldLayer)
{
// Check pointer
if (!fieldLayer)
return false;

// Inactive or not sampling the value (we only need the ones that sample value)
const FIELDLAYER_CHANNELFLAG channelFlags = fieldLayer->GetChannelFlags();
if (!(channelFlags&FIELDLAYER_CHANNELFLAG::ENABLE))
return false;

// We can consider the FieldLayer active
return true;
}


Int CountActiveAndValidFieldLayers(FieldList* fieldList, BaseDocument* doc)
{
if (!fieldList)
return NOTOK;

GeListHead *listHead = fieldList->GetLayersRoot();

Int count = 0;

for (FieldLayer *fieldLayer = static_cast<FieldLayer*>(listHead->GetFirst()); fieldLayer; fieldLayer = IterateNextFieldLayer(fieldLayer))
{
if (IsValidFieldLayer(fieldLayer, doc) && IsActiveFieldLayer(fieldLayer))
++count;
}
return count;
}
6 changes: 6 additions & 0 deletions source/lib/wsFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ UInt32 AddDirtySums(BaseObject *op, Bool goDown, DIRTYFLAGS flags);
/// @return The next layer
FieldLayer* IterateNextFieldLayer(FieldLayer* layer);

Bool IsValidFieldLayer(FieldLayer* fieldLayer, BaseDocument* doc);

Bool IsActiveFieldLayer(FieldLayer* fieldLayer);

Int CountActiveAndValidFieldLayers(FieldList* fieldList, BaseDocument* doc);

#endif // WS_FUNCTIONS_H__
17 changes: 13 additions & 4 deletions source/lib/wsPointProjector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Bool wsPointProjector::Project(PointObject *op, const wsPointProjectorParams &pa

// Calculate a ray length.
// The resulting length might be a bit too long, but with this we're on the safe side. No ray should ever be too short to reach the collision geometry.
Float rayLength = (collisionObjectMg.off - opMg.off).GetLength() + _collisionObject->GetRad().GetSum()+ op->GetRad().GetSum();
Float rayLength = (collisionObjectMg.off - opMg.off).GetLength() + _collisionObject->GetRad().GetSum() + op->GetRad().GetSum();

// Iterate points
for (Int32 i = 0; i < pointCount; i++)
Expand All @@ -120,10 +120,19 @@ Bool wsPointProjector::Project(PointObject *op, const wsPointProjectorParams &pa
// This needs to be done inside the loop, as the direction is different for each point
if (params._mode == PROJECTORMODE::SPHERICAL)
{
// Direction points from the modifier to the position of the point
rayDirection = rayPosition - params._modifierMg.off;

if (params._invert)
{
// Direction points from the position of the point to the modifier
rayDirection = params._modifierMg.off - rayPosition;
}
else
{
// Direction points from the modifier to the position of the point
rayDirection = rayPosition - params._modifierMg.off;
}
}

// Project point, cancel if critical error occurred
if (!ProjectPosition(rayPosition, rayDirection, rayLength, collisionObjectMg, collisionObjectMgI, params._offset, params._blend))
return false;
Expand Down
5 changes: 4 additions & 1 deletion source/lib/wsPointProjector.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct wsPointProjectorParams
Bool _geometryFalloffEnabled = true; ///< Geometry falloff enabled attribute
Float _geometryFalloffDist = 0.0_f; ///< Geometry falloff distance attribute
Float32* _weightMap = nullptr; ///< Ptr to weight map
Bool _invert = false;
C4D_Falloff *_falloff = nullptr; ///< Ptr to falloff

/// Default constructor
Expand All @@ -36,17 +37,19 @@ struct wsPointProjectorParams
_geometryFalloffEnabled(false),
_geometryFalloffDist(0.0),
_weightMap(nullptr),
_invert(false),
_falloff(nullptr)
{ }

/// Constructor with parameters
wsPointProjectorParams(const Matrix &modifierMg, PROJECTORMODE mode, Float offset, Float blend, Bool geometryFalloffEnabled, Float geometryFalloffDist, Float32 *weightMap = nullptr, C4D_Falloff *falloff = nullptr) :
wsPointProjectorParams(const Matrix &modifierMg, PROJECTORMODE mode, Float offset, Float blend, Bool geometryFalloffEnabled, Float geometryFalloffDist, Bool invert, Float32 *weightMap = nullptr, C4D_Falloff *falloff = nullptr) :
_modifierMg(modifierMg),
_mode(mode),
_offset(offset),
_blend(blend),
_geometryFalloffEnabled(geometryFalloffEnabled),
_geometryFalloffDist(geometryFalloffDist),
_invert(invert),
_weightMap(weightMap),
_falloff(falloff)
{ }
Expand Down
20 changes: 10 additions & 10 deletions source/object/oProjector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Bool oProjector::Init(GeListNode *node)
bc->SetInt32(PROJECTOR_MODE, PROJECTOR_MODE_PARALLEL);
bc->SetFloat(PROJECTOR_OFFSET, 0.0);
bc->SetFloat(PROJECTOR_BLEND, 1.0);
bc->SetBool(PROJECTOR_INVERT, false);
bc->SetBool(PROJECTOR_GEOMFALLOFF_ENABLE, false);
bc->SetFloat(PROJECTOR_GEOMFALLOFF_DIST, 150.0);

Expand Down Expand Up @@ -137,7 +138,7 @@ DRAWRESULT oProjector::Draw(BaseObject *op, DRAWPASS drawpass, BaseDraw *bd, Bas
bd->SetPen(bd->GetObjectColor(bh, op));

// Get projector mode
PROJECTORMODE mode = (PROJECTORMODE)bc->GetInt32(PROJECTOR_MODE, PROJECTOR_MODE_PARALLEL);
const PROJECTORMODE mode = (PROJECTORMODE)bc->GetInt32(PROJECTOR_MODE, PROJECTOR_MODE_PARALLEL);

// Draw arrows in parallel mode, or star in spherical mode
if (mode == PROJECTORMODE::PARALLEL)
Expand Down Expand Up @@ -198,11 +199,12 @@ Bool oProjector::ModifyObject(BaseObject *mod, BaseDocument *doc, BaseObject *op
}

// Get parameters
PROJECTORMODE mode = (PROJECTORMODE)bc->GetInt32(PROJECTOR_MODE, PROJECTOR_MODE_PARALLEL);
Float offset = bc->GetFloat(PROJECTOR_OFFSET, 0.0);
Float blend = bc->GetFloat(PROJECTOR_BLEND, 1.0);
Bool geometryFalloffEnabled = bc->GetBool(PROJECTOR_GEOMFALLOFF_ENABLE, false);
Float geometryFalloffDist = bc->GetFloat(PROJECTOR_GEOMFALLOFF_DIST, 100.0);
const PROJECTORMODE mode = (PROJECTORMODE)bc->GetInt32(PROJECTOR_MODE, PROJECTOR_MODE_PARALLEL);
const Float offset = bc->GetFloat(PROJECTOR_OFFSET, 0.0);
const Float blend = bc->GetFloat(PROJECTOR_BLEND, 1.0);
const Bool geometryFalloffEnabled = bc->GetBool(PROJECTOR_GEOMFALLOFF_ENABLE, false);
const Float geometryFalloffDist = bc->GetFloat(PROJECTOR_GEOMFALLOFF_DIST, 100.0);
const Bool invert = bc->GetBool(PROJECTOR_INVERT, false);

// Calculate weight map from vertex maps linked in restriction tag
Float32* weightMap = nullptr;
Expand All @@ -217,7 +219,7 @@ Bool oProjector::ModifyObject(BaseObject *mod, BaseDocument *doc, BaseObject *op
return false;

// Parameters for projection
wsPointProjectorParams projectorParams(mod->GetMg(), mode, offset, blend, geometryFalloffEnabled, geometryFalloffDist, weightMap, _falloff);
wsPointProjectorParams projectorParams(mod->GetMg(), mode, offset, blend, geometryFalloffEnabled, geometryFalloffDist, invert, weightMap, _falloff);

// Perform projection
if (!_projector.Project(static_cast<PointObject*>(op), projectorParams, thread))
Expand Down Expand Up @@ -269,8 +271,7 @@ void oProjector::CheckDirty(BaseObject *op, BaseDocument *doc)
// Iterate modifier and its parents and add their dirty checksums
dirtyness += AddDirtySums(op, false, dirtyFlags);

#if API_VERSION >= 23000
// Add falloff dirtiness
// Add falloff/Fields dirtiness
if (_falloff)
{
dirtyness += _falloff->GetDirty(doc);
Expand Down Expand Up @@ -311,7 +312,6 @@ void oProjector::CheckDirty(BaseObject *op, BaseDocument *doc)
}

}
#endif

// Compare dirty checksum to previous one, set modifier dirty if necessary
if (dirtyness != _lastDirtyness + 1)
Expand Down