Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Expressions/Operator2Expr.cpp')
-rw-r--r--source/gameengine/Expressions/Operator2Expr.cpp275
1 files changed, 275 insertions, 0 deletions
diff --git a/source/gameengine/Expressions/Operator2Expr.cpp b/source/gameengine/Expressions/Operator2Expr.cpp
new file mode 100644
index 00000000000..33223b2ae3d
--- /dev/null
+++ b/source/gameengine/Expressions/Operator2Expr.cpp
@@ -0,0 +1,275 @@
+// Operator2Expr.cpp: implementation of the COperator2Expr class.
+/*
+ * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Erwin Coumans makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+// 31 dec 1998 - big update: try to use the cached data for updating, instead of
+// rebuilding completely it from left and right node. Modified flags and bounding boxes
+// have to do the trick
+// when expression is cached, there will be a call to UpdateCalc() instead of Calc()
+
+
+
+#include "Operator2Expr.h"
+#include "StringValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+COperator2Expr::COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs)
+:
+m_cached_calculate(NULL),
+m_op(op),
+m_lhs(lhs),
+m_rhs(rhs)
+/*
+pre:
+effect: constucts a COperator2Expr with op, lhs and rhs in it
+*/
+{
+
+}
+
+COperator2Expr::COperator2Expr():
+m_cached_calculate(NULL),
+m_lhs(NULL),
+m_rhs(NULL)
+
+/*
+pre:
+effect: constucts an empty COperator2Expr
+*/
+{
+
+}
+
+COperator2Expr::~COperator2Expr()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_lhs)
+ m_lhs->Release();
+ if (m_rhs)
+ m_rhs->Release();
+ if (m_cached_calculate)
+ m_cached_calculate->Release();
+
+}
+CValue* COperator2Expr::Calculate()
+/*
+pre:
+ret: a new object containing the result of applying operator m_op to m_lhs
+and m_rhs
+*/
+{
+
+ bool leftmodified,rightmodified;
+ leftmodified = m_lhs->NeedsRecalculated();
+ rightmodified = m_rhs->NeedsRecalculated();
+
+ // if no modifications on both left and right subtree, and result is already calculated
+ // then just return cached result...
+ if (!leftmodified && !rightmodified && (m_cached_calculate))
+ {
+ // not modified, just return m_cached_calculate
+ } else {
+ // if not yet calculated, or modified...
+
+
+ if (m_cached_calculate) {
+ m_cached_calculate->Release();
+ m_cached_calculate=NULL;
+ }
+
+ CValue* ffleft = m_lhs->Calculate();
+ CValue* ffright = m_rhs->Calculate();
+
+ ffleft->SetOwnerExpression(this);//->m_pOwnerExpression=this;
+ ffright->SetOwnerExpression(this);//->m_pOwnerExpression=this;
+
+ m_cached_calculate = ffleft->Calc(m_op,ffright);
+
+ //if (m_cached_calculate)
+ // m_cached_calculate->Action(CValue::SETOWNEREXPR,&CVoidValue(this,false,CValue::STACKVALUE));
+
+ ffleft->Release();
+ ffright->Release();
+ }
+
+ return m_cached_calculate->AddRef();
+
+}
+
+/*
+bool COperator2Expr::IsInside(float x, float y, float z,bool bBorderInclude)
+{
+ bool inside;
+ inside = false;
+
+ switch (m_op)
+ {
+ case VALUE_ADD_OPERATOR: {
+ // inside = first || second; // optimized with early out if first is inside
+ // todo: calculate smallest leaf first ! is much faster...
+
+ bool second;//first ;//,second;
+
+ //first = m_lhs->IsInside(x,y,z) ;
+ second = m_rhs->IsInside(x,y,z,bBorderInclude) ;
+ if (second)
+ return true; //early out
+
+ // second = m_rhs->IsInside(x,y,z) ;
+
+ return m_lhs->IsInside(x,y,z,bBorderInclude) ;
+
+ break;
+ }
+
+ case VALUE_SUB_OPERATOR: {
+ //inside = first && !second; // optimized with early out
+ // todo: same as with add_operator: calc smallest leaf first
+
+ bool second;//first ;//,second;
+ //first = m_lhs->IsInside(x,y,z) ;
+ second = m_rhs->IsInside(x,y,z,bBorderInclude);
+ if (second)
+ return false;
+
+ // second space get subtracted -> negate!
+ //second = m_rhs->IsInside(x,y,z);
+
+ return (m_lhs->IsInside(x,y,z,bBorderInclude));
+
+
+ break;
+ }
+ default:{
+ assert(false);
+ // not yet implemented, only add or sub csg operations
+ }
+ }
+
+ return inside;
+}
+
+
+
+bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude) {
+
+ return m_rhs->IsInside(x,y,z,bBorderInclude) ;
+
+}
+
+bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude) {
+ return m_lhs->IsInside(x,y,z,bBorderInclude);
+}
+*/
+bool COperator2Expr::NeedsRecalculated() {
+ // added some lines, just for debugging purposes, it could be a one-liner :)
+ //bool modleft
+ //bool modright;
+ assertd(m_lhs);
+ assertd(m_rhs);
+
+ //modright = m_rhs->NeedsRecalculated();
+ if (m_rhs->NeedsRecalculated()) // early out
+ return true;
+ return m_lhs->NeedsRecalculated();
+ //modleft = m_lhs->NeedsRecalculated();
+ //return (modleft || modright);
+
+}
+
+
+
+CExpression* COperator2Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
+// if both children are 'dead', return NULL
+// if only one child is alive, return that child
+// if both childresn are alive, return this
+
+
+// bool leftalive = true,rightalive=true;
+ /* Does this mean the function will always bomb? */
+ assertd(false);
+ assert(m_lhs);
+ assert(m_rhs);
+/*
+ if (m_cached_calculate)
+ m_cached_calculate->Action(CValue::REFRESH_CACHE);
+
+ CExpression* newlhs = m_lhs->CheckLink(brokenlinks);
+ CExpression* newrhs = m_rhs->CheckLink(brokenlinks);
+
+ if (m_lhs != newlhs)
+ {
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));
+ }
+
+ if (m_rhs != newrhs)
+ {
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_rhs,m_rhs));
+ }
+
+
+
+ m_lhs = newlhs;
+ m_rhs = newrhs;
+
+ if (m_lhs && m_rhs) {
+ return this;
+ }
+
+ AddRef();
+ if (m_lhs)
+ return Release(m_lhs->AddRef());
+
+ if (m_rhs)
+ return Release(m_rhs->AddRef());
+/
+
+ */
+ return Release();
+
+
+
+}
+
+
+bool COperator2Expr::MergeExpression(CExpression *otherexpr)
+{
+ if (m_lhs)
+ {
+ if (m_lhs->GetExpressionID() == CExpression::CCONSTEXPRESSIONID)
+ {
+ // cross fingers ;) replace constexpr by new tree...
+ m_lhs->Release();
+ m_lhs = otherexpr->AddRef();
+ return true;
+ }
+ }
+
+ assertd(false);
+ return false;
+}
+
+
+void COperator2Expr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ if (m_lhs)
+ m_lhs->BroadcastOperators(m_op);
+ if (m_rhs)
+ m_rhs->BroadcastOperators(m_op);
+}