@@ -193,3 +193,83 @@ SELECT_NODE(MVector, SelectVector);
193193SELECT_NODE (MMatrix, SelectMatrix);
194194SELECT_NODE (MEulerRotation, SelectRotation);
195195SELECT_NODE (MQuaternion, SelectQuaternion);
196+
197+
198+ template <typename TType>
199+ inline bool logical_and (TType a, TType b)
200+ {
201+ return a && b;
202+ }
203+
204+ template <typename TType>
205+ inline bool logical_or (TType a, TType b)
206+ {
207+ return a || b;
208+ }
209+
210+ template <typename TType>
211+ inline bool logical_xor (TType a, TType b)
212+ {
213+ return !a != !b;
214+ }
215+
216+ template <typename TAttrType, typename TClass, const char * TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
217+ class LogicalNode : public BaseNode <TClass, TTypeName>
218+ {
219+ public:
220+ static MStatus initialize ()
221+ {
222+ createAttribute (input1Attr_, " input1" , DefaultValue<TAttrType>());
223+ createAttribute (input2Attr_, " input2" , DefaultValue<TAttrType>());
224+ createAttribute (outputAttr_, " output" , DefaultValue<bool >(), false );
225+
226+ MPxNode::addAttribute (input1Attr_);
227+ MPxNode::addAttribute (input2Attr_);
228+ MPxNode::addAttribute (outputAttr_);
229+
230+ MPxNode::attributeAffects (input1Attr_, outputAttr_);
231+ MPxNode::attributeAffects (input2Attr_, outputAttr_);
232+
233+ return MS::kSuccess ;
234+ }
235+
236+ MStatus compute (const MPlug& plug, MDataBlock& dataBlock) override
237+ {
238+ if (plug == outputAttr_ || (plug.isChild () && plug.parent () == outputAttr_))
239+ {
240+ const auto input1Value = getAttribute<TAttrType>(dataBlock, input1Attr_);
241+ const auto input2Value = getAttribute<TAttrType>(dataBlock, input2Attr_);
242+
243+ setAttribute (dataBlock, outputAttr_, TFuncPtr (input1Value, input2Value));
244+
245+ return MS::kSuccess ;
246+ }
247+
248+ return MS::kUnknownParameter ;
249+ }
250+
251+ private:
252+ static Attribute input1Attr_;
253+ static Attribute input2Attr_;
254+ static Attribute outputAttr_;
255+ };
256+
257+ template <typename TAttrType, typename TClass, const char * TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
258+ Attribute LogicalNode<TAttrType, TClass, TTypeName, TFuncPtr>::input1Attr_;
259+
260+ template <typename TAttrType, typename TClass, const char * TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
261+ Attribute LogicalNode<TAttrType, TClass, TTypeName, TFuncPtr>::input2Attr_;
262+
263+ template <typename TAttrType, typename TClass, const char * TTypeName, bool (*TFuncPtr)(TAttrType, TAttrType)>
264+ Attribute LogicalNode<TAttrType, TClass, TTypeName, TFuncPtr>::outputAttr_;
265+
266+ #define LOGICAL_NODE (AttrType, NodeName, FuncPtr ) \
267+ TEMPLATE_PARAMETER_LINKAGE char name##NodeName[] = #NodeName; \
268+ class NodeName : public LogicalNode <AttrType, NodeName, name##NodeName, FuncPtr> {};
269+
270+ LOGICAL_NODE (bool , AndBool, &logical_and);
271+ LOGICAL_NODE (bool , OrBool, &logical_or);
272+ LOGICAL_NODE (bool , XorBool, &logical_xor);
273+ LOGICAL_NODE (int , AndInt, &logical_and);
274+ LOGICAL_NODE (int , OrInt, &logical_or);
275+ LOGICAL_NODE (int , XorInt, &logical_xor);
0 commit comments