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:
-rw-r--r--bin/.blender/.Blanguages1
-rw-r--r--intern/boolop/SConscript2
-rw-r--r--intern/boolop/intern/BOP_Edge.cpp43
-rw-r--r--intern/boolop/intern/BOP_Edge.h13
-rw-r--r--intern/boolop/intern/BOP_Face.cpp2
-rw-r--r--intern/boolop/intern/BOP_Face.h3
-rw-r--r--intern/boolop/intern/BOP_Interface.cpp30
-rw-r--r--intern/boolop/intern/BOP_Merge.cpp3
-rw-r--r--intern/boolop/intern/BOP_Merge.h5
-rw-r--r--intern/boolop/intern/BOP_Merge2.cpp944
-rw-r--r--intern/boolop/intern/BOP_Merge2.h99
-rw-r--r--intern/boolop/intern/BOP_Mesh.cpp11
-rw-r--r--intern/boolop/intern/BOP_Mesh.h7
-rw-r--r--intern/boolop/intern/BOP_Misc.h54
-rw-r--r--intern/boolop/intern/BOP_Tag.h2
-rw-r--r--intern/boolop/intern/BOP_Vertex.cpp19
-rw-r--r--intern/boolop/intern/BOP_Vertex.h5
-rw-r--r--intern/bsp/SConscript2
-rw-r--r--projectfiles_vc7/gameengine/blenderhook/KX_blenderhook.vcproj6
-rw-r--r--projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj1
-rw-r--r--projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Sumo/PHY_Sumo.vcproj1
-rw-r--r--source/blender/blenkernel/BKE_texture.h1
-rw-r--r--source/blender/blenkernel/intern/collision.c221
-rw-r--r--source/blender/blenkernel/intern/texture.c15
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c9
-rw-r--r--source/blender/blenlib/intern/boxpack2d.c10
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/include/BDR_gpencil.h9
-rw-r--r--source/blender/include/BIF_editview.h3
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h2
-rw-r--r--source/blender/src/buttons_logic.c89
-rw-r--r--source/blender/src/drawgpencil.c378
-rw-r--r--source/blender/src/editimasel.c6
-rw-r--r--source/blender/src/editipo.c11
-rw-r--r--source/blender/src/editobject.c13
-rw-r--r--source/blender/src/editview.c4
-rw-r--r--source/blender/src/gpencil.c378
-rw-r--r--source/blender/src/header_info.c51
-rw-r--r--source/blender/src/header_ipo.c2
-rw-r--r--source/blender/src/header_view3d.c24
-rw-r--r--source/blender/src/meshlaplacian.c2
-rw-r--r--source/blender/src/space.c5
-rw-r--r--source/blender/src/toolbox.c9
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp24
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp9
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp15
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp13
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.cpp13
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h6
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp27
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp9
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.cpp15
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.cpp14
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.h1
-rw-r--r--source/gameengine/GamePlayer/common/windows/GPW_Canvas.h2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp17
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h3
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.h1
-rw-r--r--source/gameengine/Ketsji/KX_RayEventManager.cpp9
-rw-r--r--source/gameengine/Ketsji/KX_RayEventManager.h1
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp9
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp31
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h2
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h1
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp10
-rw-r--r--source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h1
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp97
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h11
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h1
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp17
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp6
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h1
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_CameraData.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp4
93 files changed, 2320 insertions, 640 deletions
diff --git a/bin/.blender/.Blanguages b/bin/.blender/.Blanguages
index 0f98ce02247..de8d8c44550 100644
--- a/bin/.blender/.Blanguages
+++ b/bin/.blender/.Blanguages
@@ -20,3 +20,4 @@ Romanian:ro
Arabic:ar
Bulgarian:bg
Greek:el
+Korean:kr
diff --git a/intern/boolop/SConscript b/intern/boolop/SConscript
index a3f3c0b6433..bec263f251f 100644
--- a/intern/boolop/SConscript
+++ b/intern/boolop/SConscript
@@ -8,7 +8,7 @@ incs += ' ../../source/blender/makesdna ../../intern/guardedalloc'
incs += ' ../../source/blender/blenlib'
if (env['OURPLATFORM'] == 'win32-mingw'):
- env.BlenderLib ('blender_bop', sources, Split(incs) , [], libtype=['common','intern'], priority = [5,50] )
+ env.BlenderLib ('blender_bop', sources, Split(incs) , [], libtype=['common','intern'], priority = [30,85] )
else:
env.BlenderLib ('blender_bop', sources, Split(incs) , [], libtype='common', priority = 5 )
diff --git a/intern/boolop/intern/BOP_Edge.cpp b/intern/boolop/intern/BOP_Edge.cpp
index ac302b530df..44e7d5cb567 100644
--- a/intern/boolop/intern/BOP_Edge.cpp
+++ b/intern/boolop/intern/BOP_Edge.cpp
@@ -75,4 +75,47 @@ void BOP_Edge::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
else if (m_vertexs[1] == oldIndex) m_vertexs[1] = newIndex;
}
+#ifdef BOP_NEW_MERGE
+
+/**
+ * Returns if this edge contains the specified face index.
+ * @param i face index
+ * @return true if this edge contains the specified face index, false otherwise
+ */
+bool BOP_Edge::removeFace(BOP_Index i)
+{
+ int pos=0;
+ for(BOP_IT_Indexs it = m_faces.begin();it!=m_faces.end();pos++,it++) {
+ if ((*it) == i) {
+ m_faces.erase(it);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#endif
+
+#ifdef BOP_DEBUG
+
+#include <iostream>
+using namespace std;
+
+/**
+ * Implements operator <<.
+ */
+ostream &operator<<(ostream &stream, BOP_Edge *e)
+{
+ stream << "Edge[" << e->getVertex1() << "," << e->getVertex2();
+#ifdef BOP_NEW_MERGE
+ if(e->m_used)
+ stream << "] (used)";
+ else
+ stream << "] (unused)";
+#endif
+ return stream;
+}
+#endif
+
diff --git a/intern/boolop/intern/BOP_Edge.h b/intern/boolop/intern/BOP_Edge.h
index 13426f6e63c..a817b3d624f 100644
--- a/intern/boolop/intern/BOP_Edge.h
+++ b/intern/boolop/intern/BOP_Edge.h
@@ -29,12 +29,16 @@
#define BOP_EDGE_H
#include "BOP_Indexs.h"
+#include "BOP_Misc.h"
class BOP_Edge
{
private:
BOP_Index m_vertexs[2];
BOP_Indexs m_faces;
+#ifdef BOP_NEW_MERGE
+ bool m_used;
+#endif
bool containsFace(BOP_Index i);
@@ -47,6 +51,15 @@ public:
inline unsigned int getNumFaces(){return m_faces.size();};
inline BOP_Indexs &getFaces(){return m_faces;};
void addFace(BOP_Index face);
+#ifdef BOP_NEW_MERGE
+ bool removeFace(BOP_Index i);
+ bool getUsed() { return m_used;};
+ void setUsed(bool setting) { m_used=setting;};
+#endif
+#ifdef BOP_DEBUG
+ friend ostream &operator<<(ostream &stream, BOP_Edge *e);
+#endif
+
};
#endif
diff --git a/intern/boolop/intern/BOP_Face.cpp b/intern/boolop/intern/BOP_Face.cpp
index 12c94624517..01308de3e5d 100644
--- a/intern/boolop/intern/BOP_Face.cpp
+++ b/intern/boolop/intern/BOP_Face.cpp
@@ -402,6 +402,7 @@ bool BOP_Face4::getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e)
return true;
}
+#ifdef BOP_DEBUG
/**
* Implements operator <<.
*/
@@ -421,3 +422,4 @@ ostream &operator<<(ostream &stream, BOP_Face *f)
return stream;
}
+#endif
diff --git a/intern/boolop/intern/BOP_Face.h b/intern/boolop/intern/BOP_Face.h
index e16425f78b3..965882db732 100644
--- a/intern/boolop/intern/BOP_Face.h
+++ b/intern/boolop/intern/BOP_Face.h
@@ -32,6 +32,7 @@
#include "MT_Plane3.h"
#include "BOP_Indexs.h"
#include "BOP_BBox.h"
+#include "BOP_Misc.h"
#include <iostream>
#include <vector>
using namespace std;
@@ -80,7 +81,9 @@ public:
virtual void replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) = 0;
virtual bool containsVertex(BOP_Index v) = 0;
+#ifdef BOP_DEBUG
friend ostream &operator<<(ostream &stream, BOP_Face *f);
+#endif
};
class BOP_Face3: public BOP_Face
diff --git a/intern/boolop/intern/BOP_Interface.cpp b/intern/boolop/intern/BOP_Interface.cpp
index 2a198103931..c6bcb4a74ce 100644
--- a/intern/boolop/intern/BOP_Interface.cpp
+++ b/intern/boolop/intern/BOP_Interface.cpp
@@ -33,9 +33,12 @@
#include "BOP_Mesh.h"
#include "BOP_Face2Face.h"
#include "BOP_Merge.h"
+#include "BOP_Merge2.h"
#include "BOP_Chrono.h"
-//#define DEBUG
+#if defined(BOP_ORIG_MERGE) && defined(BOP_NEW_MERGE)
+#include "../../../source/blender/blenkernel/BKE_global.h"
+#endif
BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC,
BOP_Faces* facesA,
@@ -208,7 +211,32 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC,
#endif
// Merge faces
+#ifdef BOP_ORIG_MERGE
+#ifndef BOP_NEW_MERGE
BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
+#endif
+#endif
+
+#ifdef BOP_NEW_MERGE
+#ifndef BOP_ORIG_MERGE
+ BOP_Merge2::getInstance().mergeFaces(meshC,numVertices);
+#else
+ static int state = -1;
+ if (G.rt == 100) {
+ if( state != 1 ) {
+ cout << "Boolean code using old merge technique." << endl;
+ state = 1;
+ }
+ BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
+ } else {
+ if( state != 0 ) {
+ cout << "Boolean code using new merge technique." << endl;
+ state = 0;
+ }
+ BOP_Merge2::getInstance().mergeFaces(meshC,numVertices);
+ }
+#endif
+#endif
#ifdef DEBUG
c = chrono.stamp(); t += c;
diff --git a/intern/boolop/intern/BOP_Merge.cpp b/intern/boolop/intern/BOP_Merge.cpp
index 1e4139ab971..012d3409187 100644
--- a/intern/boolop/intern/BOP_Merge.cpp
+++ b/intern/boolop/intern/BOP_Merge.cpp
@@ -30,6 +30,7 @@
#include "BOP_Merge.h"
+#ifdef BOP_ORIG_MERGE
#ifdef _MSC_VER
#if _MSC_VER < 1300
@@ -802,3 +803,5 @@ void BOP_Merge::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, B
}
}
}
+
+#endif /* BOP_ORIG_MERGE */
diff --git a/intern/boolop/intern/BOP_Merge.h b/intern/boolop/intern/BOP_Merge.h
index 88999b2e734..ceb8ec10690 100644
--- a/intern/boolop/intern/BOP_Merge.h
+++ b/intern/boolop/intern/BOP_Merge.h
@@ -28,6 +28,9 @@
#ifndef BOP_MERGE_H
#define BOP_MERGE_H
+#include "BOP_Misc.h"
+
+#ifdef BOP_ORIG_MERGE
#include "BOP_Mesh.h"
#include "BOP_Tag.h"
#include "BOP_MathUtils.h"
@@ -68,4 +71,6 @@ class BOP_Merge {
void mergeFaces(BOP_Mesh *m, BOP_Index v);
};
+#endif /* BOP_ORIG_MERGE */
+
#endif
diff --git a/intern/boolop/intern/BOP_Merge2.cpp b/intern/boolop/intern/BOP_Merge2.cpp
new file mode 100644
index 00000000000..bbf3f8ba702
--- /dev/null
+++ b/intern/boolop/intern/BOP_Merge2.cpp
@@ -0,0 +1,944 @@
+/**
+ *
+ * $Id: BOP_Merge22.cpp 14444 2008-04-16 22:40:48Z hos $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Marc Freixas, Ken Hughes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BOP_Merge2.h"
+
+#ifdef BOP_NEW_MERGE
+
+static void deleteFace(BOP_Mesh *m, BOP_Face *face);
+
+/**
+ * SINGLETON (use method BOP_Merge2.getInstance).
+ */
+BOP_Merge2 BOP_Merge2::SINGLETON;
+
+#ifdef BOP_DEBUG
+void dumpmesh ( BOP_Mesh *m, bool force )
+{
+ unsigned int nonmanifold = 0;
+ {
+ BOP_Edges edges = m->getEdges();
+ int count = 0;
+ for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
+ ++count, ++edge) {
+ if (!(*edge)->getUsed() && (*edge)->getFaces().size() == 0 ) continue;
+ BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
+ BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
+
+ if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
+ int fcount = 0;
+ BOP_Indexs faces = (*edge)->getFaces();
+ for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
+ BOP_Face *f = m->getFace(*face);
+ if(f->getTAG()== UNCLASSIFIED) ++fcount;
+ }
+
+
+ if(fcount !=0 && fcount !=2 ) {
+ ++nonmanifold;
+ }
+ }
+ }
+ if (!force && nonmanifold == 0) return;
+ }
+ if( nonmanifold )
+ cout << nonmanifold << " edges detected" << endl;
+#ifdef DEBUG
+ cout << "---------------------------" << endl;
+
+ BOP_Edges edges = m->getEdges();
+ int count = 0;
+ for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
+ ++count, ++edge) {
+ BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
+ BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
+
+ if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
+ int fcount = 0;
+ BOP_Indexs faces = (*edge)->getFaces();
+ cout << count << ", " << (*edge) << ", " << faces.size() << endl;
+ for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
+ BOP_Face *f = m->getFace(*face);
+ if(f->getTAG()== UNCLASSIFIED) ++fcount;
+ cout << " face " << f << endl;
+ }
+
+
+ if(fcount !=0 && fcount !=2 )
+ cout << " NON-MANIFOLD" << endl;
+ }
+ }
+
+ BOP_Faces faces = m->getFaces();
+ count = 0;
+ for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) {
+ if( count < 12*2 || (*face)->getTAG() != BROKEN ) {
+ cout << count << ", " << *face << endl;
+ }
+ ++count;
+ }
+
+ BOP_Vertexs verts = m->getVertexs();
+ count = 0;
+ for (BOP_IT_Vertexs vert = verts.begin(); vert != verts.end(); vert++) {
+ cout << count++ << ", " << *vert << " " << (*vert)->getNumEdges() << endl;
+ BOP_Indexs edges = (*vert)->getEdges();
+ for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
+ BOP_Edge *edge = m->getEdge(*it);
+ cout << " " << edge << endl;
+ }
+ }
+ cout << "===========================" << endl;
+#endif
+}
+#endif
+
+/**
+ * Simplifies a mesh, merging its faces.
+ * @param m mesh
+ * @param v index of the first mergeable vertex (can be removed by merge)
+ */
+
+void BOP_Merge2::mergeFaces(BOP_Mesh *m, BOP_Index v)
+{
+ m_mesh = m;
+
+#ifdef DEBUG
+ cout << "##############################" << endl;
+#endif
+ cleanup( );
+
+ m_firstVertex = v;
+ bool cont = false;
+
+ // Merge faces
+ mergeFaces();
+
+ do {
+ // Add quads ...
+ cont = createQuads();
+ // ... and merge new faces
+ if( cont ) cont = mergeFaces();
+
+#ifdef DEBUG
+ cout << "called mergeFaces " << cont << endl;
+#endif
+ // ... until the merge is not succesful
+ } while(cont);
+}
+
+void clean_nonmanifold( BOP_Mesh *m )
+{
+ return;
+
+ BOP_Edges nme;
+ BOP_Edges e = m->getEdges();
+ for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) {
+ BOP_Indexs faces = (*it)->getFaces();
+ if( faces.size() & ~2 )
+ nme.push_back(*it);
+ }
+ if (nme.size() == 0) return;
+ for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) {
+ if( (*it)->getFaces().size() > 1 ) {
+ BOP_Indexs faces = (*it)->getFaces();
+ for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) {
+ MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint();
+ MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint();
+ MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint();
+ if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle
+ deleteFace(m,m->getFace(*face));
+ }
+ continue;
+ }
+ BOP_Face *oface1 = m->getFace((*it)->getFaces().front());
+ BOP_Face *oface2, *tmpface;
+ BOP_Index first =(*it)->getVertex1();
+ BOP_Index next =(*it)->getVertex2();
+ BOP_Index last = first;
+ unsigned short facecount = 0;
+ bool found = false;
+ BOP_Indexs vertList;
+#ifdef DEBUG
+ cout << " first edge is " << (*it) << endl;
+#endif
+ vertList.push_back(first);
+ BOP_Edge *edge;
+ while(true) {
+ BOP_Vertex *vert = m->getVertex(next);
+ BOP_Indexs edges = vert->getEdges();
+ edge = NULL;
+ for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) {
+ edge = m->getEdge(*eit);
+ if( edge->getFaces().size() > 1) {
+ edge = NULL;
+ continue;
+ }
+ if( edge->getVertex1() == next && edge->getVertex2() != last ) {
+ last = next;
+ next = edge->getVertex2();
+ break;
+ }
+ if( edge->getVertex2() == next && edge->getVertex1() != last ) {
+ last = next;
+ next = edge->getVertex1();
+ break;
+ }
+ edge = NULL;
+ }
+ if( !edge ) break;
+#ifdef DEBUG
+ cout << " next edge is " << edge << endl;
+#endif
+ tmpface = m->getFace(edge->getFaces().front());
+ if( oface1->getOriginalFace() != tmpface->getOriginalFace() )
+ oface2 = tmpface;
+ else
+ ++facecount;
+ vertList.push_back(last);
+ if( vertList.size() > 3 ) break;
+ if( next == first ) {
+ found = true;
+ break;
+ }
+ }
+ if(found) {
+ edge = *it;
+#ifdef DEBUG
+ cout << " --> found a loop" << endl;
+#endif
+ if( vertList.size() == 3 ) {
+ BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front());
+ face->getNeighbours(first,last,next);
+ } else if( vertList.size() == 4 ) {
+ BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front());
+ face->getNeighbours(first,last,next,last);
+ } else {
+#ifdef DEBUG
+ cout << "loop has " << vertList.size() << "verts";
+#endif
+ continue;
+ }
+ if(facecount == 1) oface1 = oface2;
+ next = vertList[1];
+ last = vertList[2];
+ if( edge->getVertex2() == next ) {
+ BOP_Face3 *f = new BOP_Face3(next,first,last,
+ oface1->getPlane(),oface1->getOriginalFace());
+ m->addFace( f );
+#ifdef DEBUG
+ cout << " face is backward: " << f << endl;
+#endif
+
+ } else {
+ BOP_Face3 *f = new BOP_Face3(last,first,next,
+ oface1->getPlane(),oface1->getOriginalFace());
+ m->addFace( f );
+#ifdef DEBUG
+ cout << " face is forward: " << f << endl;
+#endif
+ }
+ }
+ }
+}
+
+/**
+ * Runs through mesh and makes sure vert/face/edge data is consistent. Most
+ * importantly:
+ * (1) mark edges which are no longer used
+ * (2) remove broken faces from edges
+ * (3) remove faces from mesh which have a single edge belonging to no other
+ * face (non-manifold edges)
+ */
+
+void BOP_Merge2::cleanup( void )
+{
+ BOP_Edges edges = m_mesh->getEdges();
+ for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); ++edge) {
+ BOP_Indexs faces = (*edge)->getFaces();
+ for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face) {
+ BOP_Face *f = m_mesh->getFace(*face);
+ if(f->getTAG()== UNCLASSIFIED) ;
+ else (*edge)->removeFace(*face);
+ }
+ if( (*edge)->getFaces().size() == 0) (*edge)->setUsed(false);
+ }
+
+ BOP_Vertexs v = m_mesh->getVertexs();
+ for( BOP_IT_Vertexs it = v.begin(); it != v.end(); ++it ) {
+ if( (*it)->getTAG() != BROKEN) {
+ BOP_Indexs edges = (*it)->getEdges();
+ for(BOP_IT_Indexs i = edges.begin();i!=edges.end();i++)
+ if( m_mesh->getEdge((*i))->getUsed( ) == false) (*it)->removeEdge( *i );
+ if( (*it)->getEdges().size() == 0 ) (*it)->setTAG(BROKEN);
+ }
+ }
+ // clean_nonmanifold( m_mesh );
+}
+
+/**
+ * Simplifies a mesh, merging its faces.
+ */
+bool BOP_Merge2::mergeFaces()
+{
+ BOP_Indexs mergeVertices;
+ BOP_Vertexs vertices = m_mesh->getVertexs();
+ BOP_IT_Vertexs v = vertices.begin();
+ const BOP_IT_Vertexs verticesEnd = vertices.end();
+
+ // Advance to first mergeable vertex
+ advance(v,m_firstVertex);
+ BOP_Index pos = m_firstVertex;
+
+ // Add unbroken vertices to the list
+ while(v!=verticesEnd) {
+ if ((*v)->getTAG() != BROKEN) {
+ mergeVertices.push_back(pos);
+ }
+
+ v++;
+ pos++;
+ }
+
+ // Merge faces with that vertices
+ return mergeFaces(mergeVertices);
+}
+
+/**
+ * remove edges from vertices when the vertex is removed
+ */
+void BOP_Merge2::freeVerts(BOP_Index v, BOP_Vertex *vert)
+{
+ BOP_Indexs edges = vert->getEdges();
+ BOP_Vertex *other;
+
+ for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
+ BOP_Edge *edge = m_mesh->getEdge(*it);
+ BOP_Indexs edges2;
+ if( edge->getVertex1() != v )
+ other = m_mesh->getVertex( edge->getVertex1() );
+ else
+ other = m_mesh->getVertex( edge->getVertex2() );
+ other->removeEdge(*it);
+ vert->removeEdge(*it);
+ }
+}
+
+/**
+ * Simplifies a mesh, merging the faces with the specified vertices.
+ * @param mergeVertices vertices to test
+ * @return true if a face merge was performed
+ */
+bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices)
+{
+ // Check size > 0!
+ if (mergeVertices.size() == 0) return false;
+ bool didMerge = false;
+
+ for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) {
+ BOP_LFaces facesByOriginalFace;
+ BOP_Index v = mergeVertices[i];
+ BOP_Vertex *vert = m_mesh->getVertex(v);
+#ifdef DEBUG
+ cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl;
+ if (v==48)
+ cout << "found vert 48" << endl;
+#endif
+ if ( vert->getTAG() != BROKEN ) {
+ getFaces(facesByOriginalFace,v);
+
+ switch (facesByOriginalFace.size()) {
+ case 0:
+ // v has no unbroken faces (so it's a new BROKEN vertex)
+ freeVerts( v, vert );
+ vert->setTAG(BROKEN);
+ break;
+ case 2: {
+#ifdef DEBUG
+ cout << "size of fBOF = " << facesByOriginalFace.size() << endl;
+#endif
+ BOP_Faces ff = facesByOriginalFace.front();
+ BOP_Faces fb = facesByOriginalFace.back();
+ BOP_Index eindexs[2];
+ int ecount = 0;
+
+ // look for two edges adjacent to v which contain both ofaces
+ BOP_Indexs edges = vert->getEdges();
+#ifdef DEBUG
+ cout << " ff has " << ff.size() << " faces" << endl;
+ cout << " fb has " << fb.size() << " faces" << endl;
+ cout << " v has " << edges.size() << " edges" << endl;
+#endif
+ for(BOP_IT_Indexs it = edges.begin(); it != edges.end();
+ ++it ) {
+ BOP_Edge *edge = m_mesh->getEdge(*it);
+ BOP_Indexs faces = edge->getFaces();
+#ifdef DEBUG
+ cout << " " << edge << " has " << edge->getFaces().size() << " faces" << endl;
+#endif
+ if( faces.size() == 2 ) {
+ BOP_Face *f0 = m_mesh->getFace(faces[0]);
+ BOP_Face *f1 = m_mesh->getFace(faces[1]);
+ if( f0->getOriginalFace() != f1->getOriginalFace() ) {
+#ifdef DEBUG
+ cout << " " << f0 << endl;
+ cout << " " << f1 << endl;
+#endif
+ eindexs[ecount++] = (*it);
+ }
+ }
+ }
+ if(ecount == 2) {
+#ifdef DEBUG
+ cout << " edge indexes are " << eindexs[0];
+ cout << " and " << eindexs[1] << endl;
+#endif
+ BOP_Edge *edge = m_mesh->getEdge(eindexs[0]);
+ BOP_Index N = edge->getVertex1();
+ if(N == v) N = edge->getVertex2();
+#ifdef DEBUG
+ cout << " ## OK, replace "<<v<<" with "<<N << endl;
+#endif
+ mergeVertex(ff , v, N );
+ mergeVertex(fb , v, N );
+// now remove v and its edges
+ vert->setTAG(BROKEN);
+ for(BOP_IT_Indexs it = edges.begin(); it != edges.end();
+ ++it ) {
+ BOP_Edge *edge = m_mesh->getEdge(*it);
+ edge->setUsed(false);
+ }
+ didMerge = true;
+ }
+#ifdef DEBUG
+ else {
+ cout << " HUH: ecount was " << ecount << endl;
+ }
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return didMerge;
+}
+
+void BOP_Merge2::mergeVertex(BOP_Faces &faces, BOP_Index v1, BOP_Index v2)
+{
+ for(BOP_IT_Faces face=faces.begin();face!=faces.end();face++) {
+ if( (*face)->size() == 3)
+ mergeVertex((BOP_Face3 *) *face, v1, v2);
+ else
+ mergeVertex((BOP_Face4 *) *face, v1, v2);
+ (*face)->setTAG(BROKEN);
+#ifdef DEBUG
+ cout << " breaking " << (*face) << endl;
+#endif
+ }
+}
+
+/*
+ * Remove a face from the mesh and from each edges's face list
+ */
+
+static void deleteFace(BOP_Mesh *m, BOP_Face *face)
+{
+ BOP_Index l2 = face->getVertex(0);
+ BOP_Faces faces = m->getFaces();
+ for(int i = face->size(); i-- ; ) {
+ BOP_Indexs edges = m->getVertex(l2)->getEdges();
+ BOP_Index l1 = face->getVertex(i);
+ for(BOP_IT_Indexs it1 = edges.begin(); it1 != edges.end(); ++it1 ) {
+ BOP_Edge *edge = m->getEdge(*it1);
+ if( ( edge->getVertex1() == l1 && edge->getVertex2() == l2 ) ||
+ ( edge->getVertex1() == l2 && edge->getVertex2() == l1 ) ) {
+ BOP_Indexs ef = edge->getFaces();
+ for(BOP_IT_Indexs it = ef.begin(); it != ef.end(); ++it ) {
+ if( m->getFace(*it) == face) {
+ edge->removeFace(*it);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ l2 = l1;
+ }
+ face->setTAG(BROKEN);
+}
+
+void BOP_Merge2::mergeVertex(BOP_Face3 *face, BOP_Index v1, BOP_Index v2)
+{
+ BOP_Index next, prev;
+ face->getNeighbours(v1,prev,next);
+
+ // if new vertex is not already in the tri, make a new tri
+ if( prev != v2 && next != v2 ) {
+ m_mesh->addFace( new BOP_Face3(prev,v2,next,
+ face->getPlane(),face->getOriginalFace()) );
+#ifdef DEBUG
+ cout << "mv3: add " << prev << "," << v2 << "," << next << endl;
+ } else {
+ cout << "mv3: vertex already in tri: doing nothing" << endl;
+#endif
+ }
+ deleteFace(m_mesh, face);
+}
+
+void BOP_Merge2::mergeVertex(BOP_Face4 *face, BOP_Index v1, BOP_Index v2)
+{
+ BOP_Index next, prev, opp;
+ face->getNeighbours(v1,prev,next,opp);
+
+ // if new vertex is already in the quad, replace quad with new tri
+ if( prev == v2 || next == v2 ) {
+ m_mesh->addFace( new BOP_Face3(prev,next,opp,
+ face->getPlane(),face->getOriginalFace()) );
+#ifdef DEBUG
+ cout << "mv4a: add " << prev << "," << next << "," << opp << endl;
+#endif
+ }
+ // otherwise make a new quad
+ else {
+ m_mesh->addFace( new BOP_Face4(prev,v2,next,opp,
+ face->getPlane(),face->getOriginalFace()) );
+#ifdef DEBUG
+ cout << "mv4b: add "<<prev<<","<<v2<<","<<next<<","<<opp<<endl;
+#endif
+ }
+ deleteFace(m_mesh, face);
+}
+
+// #define OLD_QUAD
+
+/**
+ * Simplifies the mesh, merging the pairs of triangles that come frome the
+ * same original face and define a quad.
+ * @return true if a quad was added, false otherwise
+ */
+bool BOP_Merge2::createQuads()
+{
+
+ BOP_Faces quads;
+
+ // Get mesh faces
+ BOP_Faces faces = m_mesh->getFaces();
+
+ // Merge mesh triangles
+ const BOP_IT_Faces facesIEnd = (faces.end()-1);
+ const BOP_IT_Faces facesJEnd = faces.end();
+ for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) {
+#ifdef OLD_QUAD
+ if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue;
+ for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
+ if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 ||
+ (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;
+
+
+ BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
+ if (faceK != NULL) {
+ // Set triangles to BROKEN
+ deleteFace(m_mesh, *faceI);
+ deleteFace(m_mesh, *faceJ);
+#ifdef DEBUG
+ cout << "createQuad: del " << *faceI << endl;
+ cout << "createQuad: del " << *faceJ << endl;
+ cout << "createQuad: add " << faceK << endl;
+#endif
+ quads.push_back(faceK);
+ break;
+ }
+ }
+#else
+ if ((*faceI)->getTAG() == BROKEN ) continue;
+ for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
+ if ((*faceJ)->getTAG() == BROKEN ||
+ (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;
+
+ BOP_Face *faceK = NULL;
+ if((*faceI)->size() == 3) {
+ if((*faceJ)->size() == 3)
+ faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
+ else
+ faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face4*)*faceJ);
+ } else {
+ if((*faceJ)->size() == 3)
+ faceK = createQuad((BOP_Face3*)*faceJ,(BOP_Face4*)*faceI);
+ else
+ faceK = createQuad((BOP_Face4*)*faceI,(BOP_Face4*)*faceJ);
+ }
+
+ if (faceK != NULL) {
+ // Set triangles to BROKEN
+ deleteFace(m_mesh, *faceI);
+ deleteFace(m_mesh, *faceJ);
+#ifdef DEBUG
+ cout << "createQuad: del " << *faceI << endl;
+ cout << "createQuad: del " << *faceJ << endl;
+ cout << "createQuad: add " << faceK << endl;
+#endif
+ quads.push_back(faceK);
+ break;
+ }
+ }
+#endif
+ }
+
+ // Add quads to mesh
+ const BOP_IT_Faces quadsEnd = quads.end();
+ for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad);
+ return (quads.size() > 0);
+}
+
+/**
+ * Returns a new quad (convex) from the merge of two triangles that share the
+ * vertex index v.
+ * @param faceI mesh triangle
+ * @param faceJ mesh triangle
+ * @param v vertex index shared by both triangles
+ * @return a new convex quad if the merge is possible
+ */
+BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ)
+{
+ // Test if both triangles share a vertex index
+ BOP_Index v;
+ unsigned int i;
+ for(i=0;i<3 ;i++) {
+ v = faceI->getVertex(i);
+ if( faceJ->containsVertex(v) ) break;
+ }
+ if (i == 3) return NULL;
+
+ BOP_Face *faceK = NULL;
+
+ // Get faces data
+ BOP_Index prevI, nextI, prevJ, nextJ;
+ faceI->getNeighbours(v,prevI,nextI);
+ faceJ->getNeighbours(v,prevJ,nextJ);
+ MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
+ MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
+ MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
+ MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
+ MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
+
+ // Quad test
+ if (prevI == nextJ) {
+ if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) &&
+ BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) {
+ faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ BOP_Index edge;
+ m_mesh->getIndexEdge(v,prevI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ }
+ }
+ else if (nextI == prevJ) {
+ if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) &&
+ BOP_convex(vertex,vNextJ,vNextI,vPrevI)) {
+ faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ BOP_Index edge;
+ m_mesh->getIndexEdge(v,nextI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ }
+ }
+ return faceK;
+}
+
+/**
+ * Returns a new quad (convex) from the merge of two triangles that share the
+ * vertex index v.
+ * @param faceI mesh triangle
+ * @param faceJ mesh triangle
+ * @param v vertex index shared by both triangles
+ * @return a new convex quad if the merge is possible
+ */
+BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ)
+{
+ // Test if triangle and quad share a vertex index
+ BOP_Index v;
+ unsigned int i;
+ for(i=0;i<3 ;i++) {
+ v = faceI->getVertex(i);
+ if( faceJ->containsVertex(v) ) break;
+ }
+ if (i == 3) return NULL;
+
+ BOP_Face *faceK = NULL;
+
+ // Get faces data
+ BOP_Index prevI, nextI, prevJ, nextJ, oppJ;
+ faceI->getNeighbours(v,prevI,nextI);
+ faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
+
+ // Quad test
+ BOP_Index edge;
+ if (nextI == prevJ) {
+ if (prevI == nextJ) { // v is in center
+ faceK = new BOP_Face3(nextJ,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ m_mesh->getIndexEdge(v,prevI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ m_mesh->getIndexEdge(v,nextI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ freeVerts(v, m_mesh->getVertex(v));
+ } else if (prevI == oppJ) { // nextI is in center
+ faceK = new BOP_Face3(v,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ m_mesh->getIndexEdge(v,nextI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ m_mesh->getIndexEdge(prevI,nextI,edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ freeVerts(nextI, m_mesh->getVertex(nextI));
+ }
+ } else if (nextI == oppJ && prevI == nextJ ) { // prevI is in center
+ faceK = new BOP_Face3(prevJ,v,oppJ,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ m_mesh->getIndexEdge(v,prevI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ m_mesh->getIndexEdge(nextI,prevI,edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ freeVerts(prevI, m_mesh->getVertex(prevI));
+ }
+ return faceK;
+}
+
+/**
+ * Returns a new quad (convex) from the merge of two triangles that share the
+ * vertex index v.
+ * @param faceI mesh triangle
+ * @param faceJ mesh triangle
+ * @param v vertex index shared by both triangles
+ * @return a new convex quad if the merge is possible
+ */
+BOP_Face* BOP_Merge2::createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ)
+{
+ BOP_Face *faceK = NULL;
+ //
+ // Test if both quads share a vertex index
+ //
+ BOP_Index v;
+ unsigned int i;
+ for(i=0;i<4 ;i++) {
+ v = faceI->getVertex(i);
+ if( faceJ->containsVertex(v) ) break;
+ }
+ if (i == 3) return NULL;
+
+
+ // Get faces data
+ BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
+ faceI->getNeighbours(v,prevI,nextI,oppI);
+ faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
+
+ // Quad test
+ BOP_Index edge;
+ if (nextI == prevJ) {
+ if (prevI == nextJ) { // v is in center
+ faceK = new BOP_Face4(nextI,oppI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ m_mesh->getIndexEdge(v,prevI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ m_mesh->getIndexEdge(v,nextI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ freeVerts(v, m_mesh->getVertex(v));
+ } else if (oppI == oppJ) { // nextI is in center
+ faceK = new BOP_Face4(v,nextJ,oppJ,prevI,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ m_mesh->getIndexEdge(v,nextI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ m_mesh->getIndexEdge(prevI,nextI,edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ freeVerts(nextI, m_mesh->getVertex(nextI));
+ }
+ } else if (prevI == nextJ && oppI == oppJ) { // prevI is in center
+ faceK = new BOP_Face4(v,nextI,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
+ faceK->setTAG(faceI->getTAG());
+ m_mesh->getIndexEdge(v,prevI,edge);
+ m_mesh->getVertex(v)->removeEdge(edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ m_mesh->getIndexEdge(nextI,prevI,edge);
+ m_mesh->getVertex(nextI)->removeEdge(edge);
+ m_mesh->getVertex(prevI)->removeEdge(edge);
+ freeVerts(prevI, m_mesh->getVertex(prevI));
+ }
+ return faceK;
+}
+
+/**
+ * Returns if a index is inside a set of indexs.
+ * @param indexs set of indexs
+ * @param i index
+ * @return true if the index is inside the set, false otherwise
+ */
+bool BOP_Merge2::containsIndex(BOP_Indexs indexs, BOP_Index i)
+{
+ const BOP_IT_Indexs indexsEnd = indexs.end();
+ for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) {
+ if (*it == i) return true;
+ }
+ return false;
+}
+
+/**
+ * Creates a list of lists L1, L2, ... LN where
+ * LX = mesh faces with vertex v that come from the same original face
+ * @param facesByOriginalFace list of faces lists
+ * @param v vertex index
+ */
+void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v)
+{
+ // Get edges with vertex v
+
+ BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
+ const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
+ for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {
+ // For each edge, add its no broken faces to the output list
+ BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
+ BOP_Indexs faceIndexs = edge->getFaces();
+ const BOP_IT_Indexs faceEnd = faceIndexs.end();
+ for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
+ BOP_Face* face = m_mesh->getFace(*faceIndex);
+ if (face->getTAG() != BROKEN) {
+ bool found = false;
+ // Search if we already have created a list for the
+ // faces that come from the same original face
+ const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
+ for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
+ facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
+ if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
+ // Search that the face has not been added to the list before
+ for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
+ if ((*facesByOriginalFaceX)[i] == face) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // Add the face to the list
+ if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
+ else facesByOriginalFaceX->push_back(face);
+ found = true;
+ }
+ break;
+ }
+ }
+ if (!found) {
+ // Create a new list and add the current face
+ BOP_Faces facesByOriginalFaceX;
+ facesByOriginalFaceX.push_back(face);
+ facesByOriginalFace.push_back(facesByOriginalFaceX);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Creates a list of lists L1, L2, ... LN where
+ * LX = mesh faces with vertex v that come from the same original face
+ * and without any of the vertices that appear before v in vertices
+ * @param facesByOriginalFace list of faces lists
+ * @param vertices vector with vertices indexs that contains v
+ * @param v vertex index
+ */
+void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v)
+{
+ // Get edges with vertex v
+ BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
+ const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
+ for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {
+ // Foreach edge, add its no broken faces to the output list
+ BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
+ BOP_Indexs faceIndexs = edge->getFaces();
+ const BOP_IT_Indexs faceEnd = faceIndexs.end();
+ for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
+ BOP_Face* face = m_mesh->getFace(*faceIndex);
+ if (face->getTAG() != BROKEN) {
+ // Search if the face contains any of the forbidden vertices
+ bool found = false;
+ for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) {
+ if (face->containsVertex(*vertex)) {
+ // face contains a forbidden vertex!
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // Search if we already have created a list with the
+ // faces that come from the same original face
+ const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
+ for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
+ facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
+ if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
+ // Search that the face has not been added to the list before
+ for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
+ if ((*facesByOriginalFaceX)[i] == face) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // Add face to the list
+ if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
+ else facesByOriginalFaceX->push_back(face);
+ found = true;
+ }
+ break;
+ }
+ }
+ if (!found) {
+ // Create a new list and add the current face
+ BOP_Faces facesByOriginalFaceX;
+ facesByOriginalFaceX.push_back(face);
+ facesByOriginalFace.push_back(facesByOriginalFaceX);
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif /* BOP_NEW_MERGE */
diff --git a/intern/boolop/intern/BOP_Merge2.h b/intern/boolop/intern/BOP_Merge2.h
new file mode 100644
index 00000000000..1e5945a889f
--- /dev/null
+++ b/intern/boolop/intern/BOP_Merge2.h
@@ -0,0 +1,99 @@
+/**
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BOP_MERGE2_H
+#define BOP_MERGE2_H
+
+#include "BOP_Misc.h"
+
+#ifdef BOP_NEW_MERGE
+
+#include "BOP_Mesh.h"
+#include "BOP_Tag.h"
+#include "BOP_MathUtils.h"
+#include "MEM_SmartPtr.h"
+
+typedef vector< BOP_Faces > BOP_LFaces;
+typedef vector< BOP_Faces >::iterator BOP_IT_LFaces;
+
+class BOP_Merge2 {
+ private:
+ BOP_Mesh* m_mesh;
+ BOP_Index m_firstVertex;
+ static BOP_Merge2 SINGLETON;
+
+ BOP_Merge2() {};
+ bool mergeFaces();
+ bool mergeFaces(BOP_Indexs &mergeVertices);
+ bool mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v);
+ bool mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v);
+ BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v);
+ BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Indexs &pending, BOP_Index v);
+ BOP_Face *mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v);
+ BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Index v);
+ BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v);
+ BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v);
+ bool createQuads();
+ bool containsIndex(BOP_Indexs indexs, BOP_Index index);
+ void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v);
+ void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v);
+ BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ);
+ BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ);
+ BOP_Face *createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ);
+
+ bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v,
+ BOP_Indexs &mergeVertices);
+ bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v,
+ BOP_Indexs &pending, BOP_Faces &oldFaces, BOP_Faces &newFaces );
+ BOP_Face *find3Neighbor(BOP_Face *faceI, BOP_Face *faceJ,
+ BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N );
+ BOP_Face *find4Neighbor(BOP_Face *faceI, BOP_Face *faceJ,
+ BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N,
+ BOP_Face **faceL, BOP_Index &O);
+ BOP_Face3 *collapse(BOP_Face4 *faceC, BOP_Index X);
+ void mergeFaces(BOP_Face *A, BOP_Face *B, BOP_Index X,
+ BOP_Index I, BOP_Index N, BOP_Index P, BOP_Faces &newFaces );
+ void freeVerts(BOP_Index v, BOP_Vertex *vert);
+
+ void mergeVertex(BOP_Faces&, BOP_Index, BOP_Index);
+ void mergeVertex(BOP_Face3 *, BOP_Index, BOP_Index);
+ void mergeVertex(BOP_Face4 *, BOP_Index, BOP_Index);
+ void cleanup( void );
+
+ public:
+
+ static BOP_Merge2 &getInstance() {
+ return SINGLETON;
+ }
+
+ void mergeFaces(BOP_Mesh *m, BOP_Index v);
+};
+
+void dumpmesh(BOP_Mesh *, bool);
+
+#endif /* BOP_NEW_MERGE2 */
+#endif
diff --git a/intern/boolop/intern/BOP_Mesh.cpp b/intern/boolop/intern/BOP_Mesh.cpp
index 5659cd62a3f..075884a1920 100644
--- a/intern/boolop/intern/BOP_Mesh.cpp
+++ b/intern/boolop/intern/BOP_Mesh.cpp
@@ -449,6 +449,13 @@ bool BOP_Mesh::getIndexEdge(BOP_Index v1, BOP_Index v2, BOP_Index &e)
printf ("found edge (%d %d)\n",v1,v2);
#endif
e = edge->index;
+#ifdef BOP_NEW_MERGE
+ if( m_edges[e]->getUsed() == false ) {
+ m_edges[e]->setUsed(true);
+ m_vertexs[v1]->addEdge(e);
+ m_vertexs[v2]->addEdge(e);
+ }
+#endif
return true;
}
#ifdef HASH_PRINTF_DEBUG
@@ -794,7 +801,8 @@ bool BOP_Mesh::isClosedMesh()
}
-/** ***************************************************************************
+#ifdef BOP_DEBUG
+/******************************************************************************
* DEBUG METHODS *
* This functions are used to test the mesh state and debug program errors. *
******************************************************************************/
@@ -1075,3 +1083,4 @@ void BOP_Mesh::updatePlanes()
}
}
+#endif
diff --git a/intern/boolop/intern/BOP_Mesh.h b/intern/boolop/intern/BOP_Mesh.h
index 9abff52545f..46c8fa53d20 100644
--- a/intern/boolop/intern/BOP_Mesh.h
+++ b/intern/boolop/intern/BOP_Mesh.h
@@ -1,10 +1,3 @@
-/*
- * TEMPORARY defines to enable hashing support
- */
-
-#define HASH(x) ((x) >> 5) /* each "hash" covers 32 indices */
-// #define HASH_PRINTF_DEBUG /* uncomment to enable debug output */
-
/**
*
* $Id$
diff --git a/intern/boolop/intern/BOP_Misc.h b/intern/boolop/intern/BOP_Misc.h
new file mode 100644
index 00000000000..d021579d161
--- /dev/null
+++ b/intern/boolop/intern/BOP_Misc.h
@@ -0,0 +1,54 @@
+/**
+ *
+ * $Id: BOP_Misc.h 14444 2008-04-16 22:40:48Z khughes $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Ken Hughes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/*
+ * This file contains various definitions used across the modules
+ */
+
+/*
+ * define operator>> for faces, edges and vertices, and also add some
+ * debugging functions for displaying various internal data structures
+ */
+
+// #define BOP_DEBUG
+
+#define HASH(x) ((x) >> 5) /* each "hash" covers 32 indices */
+// #define HASH_PRINTF_DEBUG /* uncomment to enable debug output */
+
+/*
+ * temporary: control which method is used to merge final triangles and
+ * quads back together after an operation. If both methods are included,
+ * the "rt" debugging button on the Scene panel (F10) is used to control
+ * which is active. Setting it to 100 enables the original method, any
+ * other value enables the new method.
+ */
+
+#define BOP_ORIG_MERGE /* include original merge code */
+#define BOP_NEW_MERGE /* include new merge code */
diff --git a/intern/boolop/intern/BOP_Tag.h b/intern/boolop/intern/BOP_Tag.h
index 705f4885866..ead10fa6040 100644
--- a/intern/boolop/intern/BOP_Tag.h
+++ b/intern/boolop/intern/BOP_Tag.h
@@ -39,7 +39,7 @@
#define OUTON_TAG 0x11 // Above and on the plane
#define UNCLASSIFIED_TAG 0x0F // Expecting to be classified
-#define PHANTOM_TAG 0x0C // Phantom face
+#define PHANTOM_TAG 0x0C // Phantom face: verts form collinear triangle
#define OVERLAPPED_TAG 0x0D // Overlapped face
#define BROKEN_TAG 0x0B // Splitted and unused ...
diff --git a/intern/boolop/intern/BOP_Vertex.cpp b/intern/boolop/intern/BOP_Vertex.cpp
index a429c26d204..edb53ea6a59 100644
--- a/intern/boolop/intern/BOP_Vertex.cpp
+++ b/intern/boolop/intern/BOP_Vertex.cpp
@@ -89,3 +89,22 @@ bool BOP_Vertex::containsEdge(BOP_Index i)
return false;
}
+
+#ifdef BOP_DEBUG
+/**
+ * Implements operator <<.
+ */
+#include <iomanip>
+
+ostream &operator<<(ostream &stream, BOP_Vertex *v)
+{
+ char aux[20];
+ BOP_stringTAG(v->m_tag,aux);
+ MT_Point3 point = v->getPoint();
+ stream << setprecision(6) << showpoint << fixed;
+ stream << "Vertex[" << point[0] << "," << point[1] << ",";
+ stream << point[2] << "] (" << aux << ")";
+ return stream;
+}
+#endif
+
diff --git a/intern/boolop/intern/BOP_Vertex.h b/intern/boolop/intern/BOP_Vertex.h
index 3a9895df6d3..18b2f168f8c 100644
--- a/intern/boolop/intern/BOP_Vertex.h
+++ b/intern/boolop/intern/BOP_Vertex.h
@@ -31,6 +31,7 @@
#include "BOP_Tag.h"
#include "BOP_Indexs.h"
#include "MT_Point3.h"
+#include "BOP_Misc.h"
class BOP_Vertex
{
@@ -52,6 +53,10 @@ public:
inline MT_Point3 getPoint() const { return m_point;};
inline BOP_TAG getTAG() { return m_tag;};
inline void setTAG(BOP_TAG t) { m_tag = t;};
+#ifdef BOP_DEBUG
+ friend ostream &operator<<(ostream &stream, BOP_Vertex *v);
+#endif
+
};
#endif
diff --git a/intern/bsp/SConscript b/intern/bsp/SConscript
index 88d2529ae59..39f278625a9 100644
--- a/intern/bsp/SConscript
+++ b/intern/bsp/SConscript
@@ -6,7 +6,7 @@ sources = env.Glob('intern/*.cpp')
incs = 'intern ../container ../moto/include ../memutil'
if (env['OURPLATFORM'] == 'win32-mingw'):
- env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype=['common','intern'], priority=[26,26] )
+ env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype=['common','intern'], priority=[26,69] )
else:
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=26 )
diff --git a/projectfiles_vc7/gameengine/blenderhook/KX_blenderhook.vcproj b/projectfiles_vc7/gameengine/blenderhook/KX_blenderhook.vcproj
index b020d88b2b3..edf0faf4ab7 100644
--- a/projectfiles_vc7/gameengine/blenderhook/KX_blenderhook.vcproj
+++ b/projectfiles_vc7/gameengine/blenderhook/KX_blenderhook.vcproj
@@ -143,9 +143,6 @@
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderMouseDevice.cpp">
</File>
<File
- RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderPolyMaterial.cpp">
- </File>
- <File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderRenderTools.cpp">
</File>
<File
@@ -171,9 +168,6 @@
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderMouseDevice.h">
</File>
<File
- RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderPolyMaterial.h">
- </File>
- <File
RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderRenderTools.h">
</File>
<File
diff --git a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
index 9d5a9f55074..323d2cc9b04 100644
--- a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
+++ b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
@@ -237,6 +237,7 @@
BasicRuntimeChecks="3"
RuntimeLibrary="1"
DefaultCharIsUnsigned="TRUE"
+ RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="..\..\..\..\build\msvc_7\source\gameengine\ketsji\debug\KX_ketsji.pch"
AssemblerListingLocation="..\..\..\..\build\msvc_7\source\gameengine\ketsji\debug\"
diff --git a/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Sumo/PHY_Sumo.vcproj b/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Sumo/PHY_Sumo.vcproj
index a8d6e77cd58..33806e32d65 100644
--- a/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Sumo/PHY_Sumo.vcproj
+++ b/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Sumo/PHY_Sumo.vcproj
@@ -171,6 +171,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
+ RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\source\gameengine\physics\sumo\debug\PHY_Sumo.pch"
AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\source\gameengine\physics\sumo\debug\"
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 96e61a8afdd..ad7810578d8 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -63,6 +63,7 @@ struct Tex *copy_texture(struct Tex *tex);
void make_local_texture(struct Tex *tex);
void autotexname(struct Tex *tex);
struct Tex *give_current_texture(struct Object *ob, int act);
+struct Tex *give_current_world_texture(void);
struct TexMapping *add_mapping(void);
void init_mapping(struct TexMapping *texmap);
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 6dfb77504fb..cfcab54058d 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -1291,116 +1291,6 @@ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *col
return 1;
}
-int cloth_do_selfcollisions(ClothModifierData * clmd)
-{
- int ret2 = 0, l;
- Cloth *cloth = clmd->clothObject;
-
- if ( clmd->clothObject->bvhselftree )
- {
- for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
- {
- BVHTreeOverlap *overlap = NULL;
- ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
- int k;
- int ret = 0, result = 0;
-
- // search for overlapping collision pairs
- overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
-
-// #pragma omp parallel for private(k, i, j) schedule(static)
- for ( k = 0; k < result; k++ )
- {
- float temp[3];
- float length = 0;
- float mindistance;
- int i, j;
-
- i = overlap[k].indexA;
- j = overlap[k].indexB;
-
- mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
-
- if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
- {
- if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
- && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
- {
- continue;
- }
- }
-
- VECSUB ( temp, verts[i].tx, verts[j].tx );
-
- if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
-
- // check for adjacent points (i must be smaller j)
- if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
- {
- continue;
- }
-
- length = Normalize ( temp );
-
- if ( length < mindistance )
- {
- float correction = mindistance - length;
-
- if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
- {
- VecMulf ( temp, -correction );
- VECADD ( verts[j].tx, verts[j].tx, temp );
- }
- else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
- {
- VecMulf ( temp, correction );
- VECADD ( verts[i].tx, verts[i].tx, temp );
- }
- else
- {
- VecMulf ( temp, -correction*0.5 );
- VECADD ( verts[j].tx, verts[j].tx, temp );
-
- VECSUB ( verts[i].tx, verts[i].tx, temp );
- }
- ret = 1;
- ret2 += ret;
- }
- else
- {
- // check for approximated time collisions
- }
- }
-
- if ( overlap )
- MEM_freeN ( overlap );
-
- if(!ret)
- break;
-
- }
- ////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////
- // SELFCOLLISIONS: update velocities
- ////////////////////////////////////////////////////////////
- if ( ret2 )
- {
- int i;
- ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
-
- for ( i = 0; i < cloth->numverts; i++ )
- {
- if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
- {
- VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
- }
- }
- }
- ////////////////////////////////////////////////////////////
- }
- return ret2;
-}
// return all collision objects in scene
// collision object will exclude self
@@ -1547,7 +1437,7 @@ int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, f
{
Cloth *cloth=NULL;
BVHTree *cloth_bvh=NULL;
- long i=0, numfaces = 0, numverts = 0;
+ int i=0, numfaces = 0, numverts = 0, k, l, j;
int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
int ret = 0, ret2 = 0;
@@ -1647,21 +1537,122 @@ int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, f
VECADD ( verts[i].tx, verts[i].txold, verts[i].tv );
}
////////////////////////////////////////////////////////////
-
+
////////////////////////////////////////////////////////////
// Test on *simple* selfcollisions
////////////////////////////////////////////////////////////
if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF )
{
- ret2 += cloth_do_selfcollisions(clmd);
+ for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
+ {
+ // TODO: add coll quality rounds again
+ BVHTreeOverlap *overlap = NULL;
+ int result = 0;
+
+ // collisions = 1;
+ verts = cloth->verts; // needed for openMP
+
+ numfaces = clmd->clothObject->numfaces;
+ numverts = clmd->clothObject->numverts;
+
+ verts = cloth->verts;
+
+ if ( cloth->bvhselftree )
+ {
+ // search for overlapping collision pairs
+ overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
+
+ // #pragma omp parallel for private(k, i, j) schedule(static)
+ for ( k = 0; k < result; k++ )
+ {
+ float temp[3];
+ float length = 0;
+ float mindistance;
+
+ i = overlap[k].indexA;
+ j = overlap[k].indexB;
+
+ mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
+
+ if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
+ {
+ if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ continue;
+ }
+ }
+
+ VECSUB ( temp, verts[i].tx, verts[j].tx );
+
+ if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
+
+ // check for adjacent points (i must be smaller j)
+ if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
+ {
+ continue;
+ }
+
+ length = Normalize ( temp );
+
+ if ( length < mindistance )
+ {
+ float correction = mindistance - length;
+
+ if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, -correction );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+ }
+ else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, correction );
+ VECADD ( verts[i].tx, verts[i].tx, temp );
+ }
+ else
+ {
+ VecMulf ( temp, -correction*0.5 );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+
+ VECSUB ( verts[i].tx, verts[i].tx, temp );
+ }
+ ret = 1;
+ ret2 += ret;
+ }
+ else
+ {
+ // check for approximated time collisions
+ }
+ }
+
+ if ( overlap )
+ MEM_freeN ( overlap );
+
+ }
+ }
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // SELFCOLLISIONS: update velocities
+ ////////////////////////////////////////////////////////////
+ if ( ret2 )
+ {
+ for ( i = 0; i < cloth->numverts; i++ )
+ {
+ if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
+ }
+ }
+ }
+ ////////////////////////////////////////////////////////////
}
- ////////////////////////////////////////////////////////////
}
while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) );
if(collobjs)
- + MEM_freeN(collobjs);
+ MEM_freeN(collobjs);
return MIN2 ( ret, 1 );
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index af5824f97a5..31a68587898 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -54,6 +54,7 @@
#include "DNA_brush_types.h"
#include "DNA_node_types.h"
#include "DNA_color_types.h"
+#include "DNA_scene_types.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -743,7 +744,7 @@ Tex *give_current_texture(Object *ob, int act)
bNode *node;
if(ob==0) return 0;
- if(ob->totcol==0) return 0;
+ if(ob->totcol==0 && !(ob->type==OB_LAMP)) return 0;
if(ob->type==OB_LAMP) {
la=(Lamp *)ob->data;
@@ -787,6 +788,18 @@ Tex *give_current_texture(Object *ob, int act)
return tex;
}
+Tex *give_current_world_texture(void)
+{
+ MTex *mtex = 0;
+ Tex *tex = 0;
+
+ if(!(G.scene->world)) return 0;
+
+ mtex= G.scene->world->mtex[(int)(G.scene->world->texact)];
+ if(mtex) tex= mtex->tex;
+
+ return tex;
+}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index a97b9ca6672..4ceb9762a7b 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -484,15 +484,14 @@ static char get_largest_axis(float *bv)
}
}
-static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char lastaxis)
+static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end)
{
- char laxis;
int i, tend;
BVHNode *tnode;
int slice = (end-start+tree->tree_type-1)/tree->tree_type; //division rounded up
// Determine which axis to split along
- laxis = get_largest_axis(node->bv);
+ char laxis = get_largest_axis(node->bv);
// split nodes along longest axis
for (i=0; start < end; start += slice, i++) //i counts the current child
@@ -515,7 +514,7 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char
if(tend != end)
partition_nth_element(tree->nodes, start, end, tend, laxis);
refit_kdop_hull(tree, tnode, start, tend);
- bvh_div_nodes(tree, tnode, start, tend, laxis);
+ bvh_div_nodes(tree, tnode, start, tend);
}
node->totnode++;
}
@@ -586,7 +585,7 @@ void BLI_bvhtree_balance(BVHTree *tree)
// refit root bvh node
refit_kdop_hull(tree, tree->nodes[tree->totleaf], 0, tree->totleaf);
// create + balance tree
- bvh_div_nodes(tree, tree->nodes[tree->totleaf], 0, tree->totleaf, 0);
+ bvh_div_nodes(tree, tree->nodes[tree->totleaf], 0, tree->totleaf);
// verify_tree(tree);
}
diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack2d.c
index acd53e5d516..db7bae8a91d 100644
--- a/source/blender/blenlib/intern/boxpack2d.c
+++ b/source/blender/blenlib/intern/boxpack2d.c
@@ -42,6 +42,8 @@
#define TRF 2
#define TLF 4
#define BRF 8
+#define CORNERFLAGS (BLF|TRF|TLF|BRF)
+
#define BL 0
#define TR 1
#define TL 2
@@ -159,7 +161,7 @@ void boxPack2D(boxPack *boxarray, int len, float *tot_width, float *tot_height)
vert->blb = vert->brb = vert->tlb =\
vert->isect_cache[0] = vert->isect_cache[1] =\
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = 15 &~ TRF;
+ vert->free = CORNERFLAGS &~ TRF;
vert->trb = box;
vert->index = i; i++;
box->v[BL] = vert; vert++;
@@ -167,7 +169,7 @@ void boxPack2D(boxPack *boxarray, int len, float *tot_width, float *tot_height)
vert->trb= vert->brb = vert->tlb =\
vert->isect_cache[0] = vert->isect_cache[1] =\
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = 15 &~ BLF;
+ vert->free = CORNERFLAGS &~ BLF;
vert->blb = box;
vert->index = i; i++;
box->v[TR] = vert; vert++;
@@ -175,7 +177,7 @@ void boxPack2D(boxPack *boxarray, int len, float *tot_width, float *tot_height)
vert->trb = vert->blb = vert->tlb =\
vert->isect_cache[0] = vert->isect_cache[1] =\
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = 15 &~ BRF;
+ vert->free = CORNERFLAGS &~ BRF;
vert->brb = box;
vert->index = i; i++;
box->v[TL] = vert; vert++;
@@ -183,7 +185,7 @@ void boxPack2D(boxPack *boxarray, int len, float *tot_width, float *tot_height)
vert->trb = vert->blb = vert->brb =\
vert->isect_cache[0] = vert->isect_cache[1] =\
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = 15 &~ TLF;
+ vert->free = CORNERFLAGS &~ TLF;
vert->tlb = box;
vert->index = i; i++;
box->v[BR] = vert; vert++;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 02cc5cab6d5..0cc87c7bdef 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2283,7 +2283,7 @@ static int handle_append_runtime(int handle, char *exename, char **cause_r) {
unsigned char buf[1024];
int count, progfd= -1;
- if (!runtime) {
+ if (!BLI_exists(runtime)) {
cause= "Unable to find runtime";
goto cleanup;
}
diff --git a/source/blender/include/BDR_gpencil.h b/source/blender/include/BDR_gpencil.h
index d2fc7be29ea..eb749cf28ec 100644
--- a/source/blender/include/BDR_gpencil.h
+++ b/source/blender/include/BDR_gpencil.h
@@ -38,6 +38,15 @@ struct bGPdata;
struct bGPDlayer;
struct bGPDframe;
+/* ------------- Grease-Pencil Helpers -------------- */
+
+/* Temporary 'Stroke Point' data */
+typedef struct tGPspoint {
+ short x, y; /* x and y coordinates of cursor (in relative to area) */
+ float xf, yf; /* same as x and y, but as floats */
+ float pressure; /* pressure of tablet at this point */
+} tGPspoint;
+
/* ------------ Grease-Pencil API ------------------ */
void free_gpencil_strokes(struct bGPDframe *gpf);
diff --git a/source/blender/include/BIF_editview.h b/source/blender/include/BIF_editview.h
index 4ed3d0df367..d2c6c56d01a 100644
--- a/source/blender/include/BIF_editview.h
+++ b/source/blender/include/BIF_editview.h
@@ -34,9 +34,12 @@ struct Base;
struct Object;
struct Camera;
struct View3D;
+struct rcti;
void arrows_move_cursor(unsigned short event);
+void lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves);
int lasso_inside(short mcords[][2], short moves, short sx, short sy);
+int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1);
void borderselect(void);
void circle_select(void);
void deselectall(void);
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index b88dd698c3f..dca4e28688d 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -125,7 +125,7 @@ typedef struct bGPdata {
*/
short sbuffer_size; /* number of elements currently in cache */
short sbuffer_sflag; /* flags for stroke that cache represents */
- bGPDspoint *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
+ void *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
} bGPdata;
/* bGPdata->flag */
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 498edc0dfed..5cf1958678e 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -1654,53 +1654,66 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
wval = (width-100)/3;
if (oa->type == ACT_OBJECT_NORMAL)
{
- ysize= 175;
-
+ if ( ob->gameflag & OB_DYNAMIC )
+ {
+ ysize= 175;
+ }
+ else
+ {
+ ysize= 72;
+ }
+
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
- uiDefBut(block, LABEL, 0, "Force", xco, yco-45, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
- uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "Torque", xco, yco-64, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
- uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
+ uiDefBut(block, LABEL, 0, "Loc", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the location");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
- uiDefBut(block, LABEL, 0, "dLoc", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
- uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "dRot", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
- uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
+ uiDefBut(block, LABEL, 0, "Rot", xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the rotation");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
+
+ uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+
+ if ( ob->gameflag & OB_DYNAMIC )
+ {
+ uiDefBut(block, LABEL, 0, "Force", xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
- uiDefBut(block, LABEL, 0, "linV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
- uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
+ uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-6106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
+ }
- uiDefBut(block, LABEL, 0, "angV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
- uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
+ if ( ob->gameflag & OB_DYNAMIC )
+ {
+ uiDefBut(block, LABEL, 0, "LinV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
- uiDefBut(block, LABEL, 0, "damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
- uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
-
- uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefBut(block, LABEL, 0, "AngV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
- uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
+ uiDefBut(block, LABEL, 0, "Damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
+ uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
+
+ uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
+ }
} else if (oa->type == ACT_OBJECT_SERVO)
{
ysize= 172;
diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c
index e07dec90629..ee28049e2c0 100644
--- a/source/blender/src/drawgpencil.c
+++ b/source/blender/src/drawgpencil.c
@@ -280,11 +280,15 @@ short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa)
/* show override lmb-clicks button + painting lock */
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret LMB-click as new strokes (same as holding Shift-Key per stroke)");
-
- uiBlockSetCol(block, TH_BUT_SETTING);
- uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
- uiBlockSetCol(block, TH_AUTO);
+ if ((gpd->flag & GP_DATA_EDITPAINT)==0) {
+ uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
+
+ uiBlockSetCol(block, TH_BUT_SETTING);
+ uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
+ uiBlockSetCol(block, TH_AUTO);
+ }
+ else
+ uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
uiBlockEndAlign(block);
/* 'view align' button (naming depends on context) */
@@ -306,6 +310,8 @@ short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa)
/* ************************************************** */
/* GREASE PENCIL DRAWING */
+/* ----- General Defines ------ */
+
/* flags for sflag */
enum {
GP_DRAWDATA_NOSTATUS = (1<<0), /* don't draw status info */
@@ -313,115 +319,294 @@ enum {
GP_DRAWDATA_ONLYV2D = (1<<2), /* only draw 'canvas' strokes */
};
-/* draw a given stroke */
-static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
+/* ----- Tool Buffer Drawing ------ */
+
+/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
+static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thickness, short dflag, short sflag)
{
- bGPDspoint *pt;
+ tGPspoint *pt;
int i;
/* error checking */
if ((points == NULL) || (totpoints <= 0))
return;
- /* check if stroke can be drawn */
- if ((dflag & GP_DRAWDATA_ONLY3D) && !(sflag & GP_STROKE_3DSPACE))
- return;
- if (!(dflag & GP_DRAWDATA_ONLY3D) && (sflag & GP_STROKE_3DSPACE))
- return;
- if ((dflag & GP_DRAWDATA_ONLYV2D) && !(sflag & GP_STROKE_2DSPACE))
- return;
- if (!(dflag & GP_DRAWDATA_ONLYV2D) && (sflag & GP_STROKE_2DSPACE))
+ /* check if buffer can be drawn */
+ if (dflag & (GP_DRAWDATA_ONLY3D|GP_DRAWDATA_ONLYV2D))
return;
- /* if drawing a single point, draw it larger */
+ /* if drawing a single point, draw it larger */
if (totpoints == 1) {
/* draw point */
- if (sflag & GP_STROKE_3DSPACE) {
- glBegin(GL_POINTS);
- glVertex3f(points->x, points->y, points->z);
- glEnd();
- }
- else if (sflag & GP_STROKE_2DSPACE) {
- glBegin(GL_POINTS);
- glVertex2f(points->x, points->y);
- glEnd();
- }
- else {
- const float x= (points->x / 1000 * winx);
- const float y= (points->y / 1000 * winy);
-
- glBegin(GL_POINTS);
- glVertex2f(x, y);
- glEnd();
+ glBegin(GL_POINTS);
+ glVertex2f(points->x, points->y);
+ glEnd();
+ }
+ else if (sflag & GP_STROKE_ERASER) {
+ /* draw stroke curve - just standard thickness */
+ setlinestyle(4);
+ glLineWidth(1.0f);
+
+ glBegin(GL_LINE_STRIP);
+ for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+ glVertex2f(pt->x, pt->y);
}
+ glEnd();
+
+ setlinestyle(0);
}
else {
float oldpressure = 0.0f;
/* draw stroke curve */
+ setlinestyle(2);
+
glBegin(GL_LINE_STRIP);
for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
- float x, y, z;
-
- if (sflag & GP_STROKE_3DSPACE) {
- x= pt->x;
- y= pt->y;
- z= pt->z;
- }
- else if (sflag & GP_STROKE_2DSPACE) {
- x= pt->x;
- y= pt->y;
- z= 0;
- }
- else {
- x= (pt->x / 1000 * winx);
- y= (pt->y / 1000 * winy);
- z= 0;
- }
-
if (fabs(pt->pressure - oldpressure) > 0.2f) {
glEnd();
glLineWidth(pt->pressure * thickness);
glBegin(GL_LINE_STRIP);
- if (sflag & GP_STROKE_3DSPACE)
- glVertex3f(x, y, z);
- else
- glVertex2f(x, y);
+ glVertex2f(pt->x, pt->y);
oldpressure = pt->pressure;
}
+ else
+ glVertex2f(pt->x, pt->y);
+ }
+ glEnd();
+
+ setlinestyle(0);
+ }
+}
+
+/* ----- Existing Strokes Drawing (3D and Point) ------ */
+
+/* draw a given stroke - just a single dot (only one point) */
+static void gp_draw_stroke_point (bGPDspoint *points, short sflag, int winx, int winy)
+{
+ /* draw point */
+ if (sflag & GP_STROKE_3DSPACE) {
+ glBegin(GL_POINTS);
+ glVertex3f(points->x, points->y, points->z);
+ glEnd();
+ }
+ else if (sflag & GP_STROKE_2DSPACE) {
+ glBegin(GL_POINTS);
+ glVertex2f(points->x, points->y);
+ glEnd();
+ }
+ else {
+ const float x= (points->x / 1000 * winx);
+ const float y= (points->y / 1000 * winy);
+
+ glBegin(GL_POINTS);
+ glVertex2f(x, y);
+ glEnd();
+ }
+}
+
+/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
+static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
+{
+ bGPDspoint *pt;
+ float oldpressure = 0.0f;
+ int i;
+
+ /* draw stroke curve */
+ glBegin(GL_LINE_STRIP);
+ for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+ if (fabs(pt->pressure - oldpressure) > 0.2f) {
+ glEnd();
+ glLineWidth(pt->pressure * thickness);
+ glBegin(GL_LINE_STRIP);
+
+ glVertex3f(pt->x, pt->y, pt->z);
+
+ oldpressure = pt->pressure;
+ }
+ else
+ glVertex3f(pt->x, pt->y, pt->z);
+ }
+ glEnd();
+
+ /* draw debug points of curve on top? */
+ if (debug) {
+ glBegin(GL_POINTS);
+ for (i=0, pt=points; i < totpoints && pt; i++, pt++)
+ glVertex3f(pt->x, pt->y, pt->z);
+ glEnd();
+ }
+}
+
+/* ----- Fancy 2D-Stroke Drawing ------ */
+
+/* draw a given stroke in 2d */
+static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
+{
+ /* if thickness is less than 3, 'smooth' opengl lines look better */
+ if ((thickness < 3) || (G.rt==0)) {
+ bGPDspoint *pt;
+ int i;
+
+ glBegin(GL_LINE_STRIP);
+ for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+ if (sflag & GP_STROKE_2DSPACE) {
+ glVertex2f(pt->x, pt->y);
+ }
else {
- if (sflag & GP_STROKE_3DSPACE)
- glVertex3f(x, y, z);
- else
- glVertex2f(x, y);
+ const float x= (pt->x / 1000 * winx);
+ const float y= (pt->y / 1000 * winy);
+
+ glVertex2f(x, y);
}
}
glEnd();
+ }
+ else { /* tesselation code: currently only enabled with rt != 0 */
+ bGPDspoint *pt1, *pt2;
+ float p0[2], p1[2], pm[2];
+ int i;
- /* draw debug points of curve on top? */
- if (debug) {
- glBegin(GL_POINTS);
- for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
- if (sflag & GP_STROKE_3DSPACE) {
- glVertex3f(pt->x, pt->y, pt->z);
- }
- else if (sflag & GP_STROKE_2DSPACE) {
- glVertex2f(pt->x, pt->y);
- }
- else {
- const float x= (pt->x / 1000 * winx);
- const float y= (pt->y / 1000 * winy);
+ glShadeModel(GL_FLAT);
+ glBegin(GL_QUAD_STRIP);
+
+ for (i=0, pt1=points, pt2=points+1; i < (totpoints-1); i++, pt1++, pt2++) {
+ float s0[2], s1[2]; /* segment 'center' points */
+ float t0[2], t1[2]; /* tesselated coordinates */
+ float m1[2], m2[2]; /* gradient and normal */
+ float pthick, dist; /* thickness at segment point, and length of segment */
+ float sminorang; /* minor angle between strokes */
+
+ /* get x and y coordinates from points */
+ if (sflag & GP_STROKE_2DSPACE) {
+ s0[0]= pt1->x; s0[1]= pt1->y;
+ s1[0]= pt2->x; s1[1]= pt2->y;
+ }
+ else {
+ s0[0]= (pt1->x / 1000 * winx);
+ s0[1]= (pt1->y / 1000 * winy);
+ s1[0]= (pt2->x / 1000 * winx);
+ s1[1]= (pt2->y / 1000 * winy);
+ }
+
+ /* calculate gradient and normal - 'angle'=(ny/nx) */
+ m1[1]= s1[1] - s0[1];
+ m1[0]= s1[0] - s0[0];
+ dist = Vec2Lenf(s0, s1);
+ m2[1]= -(m1[0]) / dist;
+ m2[0]= m1[1] / dist;
+
+ /* if the first segment, initialise the first segment using segment's normal */
+ if (i == 0) {
+ pthick= (pt1->pressure * thickness);
+
+ // TODO: also draw/do a round end-cap first
+
+ p0[0]= s0[0] - (pthick * m2[0]);
+ p0[1]= s0[1] - (pthick * m2[1]);
+ p1[0]= s1[0] + (pthick * m2[0]);
+ p1[1]= s1[1] + (pthick * m2[1]);
+
+ Vec2Copyf(pm, m1);
+ }
+
+ /* if the minor angle between the current segment and the previous one is less than 90 degrees */
+ if (i)
+ sminorang= NormalizedVecAngle2_2D(pm, m1);
+ else
+ sminorang= 0.0f;
+
+ if ((IS_EQ(sminorang, 0)==0) && (abs(sminorang) < M_PI_2) )
+ {
+ float closep[2];
+
+ /* recalculate startpoint of segment, where the new start-line:
+ * - starts a new gl-quad-strip
+ * - uses the vert of old startpoint closer to our endpoint
+ * - distance between new startpoints = distance between old startpoints
+ * - new startpoints occur on same gradient as old segment does (has potential for some 'minor' overlap, but ok)
+ */
+
+ /* find the closer vertex, and distance between startpoints */
+ if (Vec2Lenf(p0, s1) > Vec2Lenf(p1, s1))
+ Vec2Copyf(closep, p1);
+ else
+ Vec2Copyf(closep, p0);
- glVertex2f(x, y);
+ /* determine which side this closer vertex should be on */
+ pthick= (pt1->pressure * thickness * 2);
+ if ( ((closep[0] - s0[0]) > 0) || ((closep[1] - s0[1]) > 0) ) {
+ /* assumes this is the 'second' point, (i.e. the 'plus' one), so the other is subtracting */
+ p0[0]= closep[0] - (pthick * pm[0]);
+ p0[1]= closep[1] - (pthick * pm[1]);
+ p1[0]= closep[0];
+ p1[1]= closep[1];
+ }
+ else if ( ((closep[0] - s0[0]) < 0) || ((closep[1] - s0[1]) < 0) ) {
+ /* assumes this is the 'first' point, (i.e. the 'minus' one), so the other is adding */
+ p0[0]= closep[0];
+ p0[1]= closep[1];
+ p1[0]= closep[0] + (pthick * pm[0]);
+ p1[1]= closep[1] + (pthick * pm[1]);
}
+
+ /* reset gl-states! */
+ glEnd();
+ glBegin(GL_QUAD_STRIP);
}
- glEnd();
+
+ /* do the end of this segment */
+ pthick= (pt2->pressure * thickness);
+ t0[0] = s1[0] - (pthick * m2[0]);
+ t0[1] = s1[1] - (pthick * m2[1]);
+ t1[0] = s1[0] + (pthick * m2[0]);
+ t1[1] = s1[1] + (pthick * m2[1]);
+
+ /* draw this segment */
+ glVertex2f(p0[0], p0[1]);
+ glVertex2f(p1[0], p1[1]);
+ glVertex2f(t0[0], t0[1]);
+ glVertex2f(t1[0], t1[1]);
+
+ // TODO: draw end cap if last segment
+ if (i == totpoints-2) {
+
+ }
+
+ /* store current points for next segment to use */
+ Vec2Copyf(p0, t0);
+ Vec2Copyf(p1, t1);
+ Vec2Copyf(pm, m1);
}
+
+ glEnd();
+ }
+
+ /* draw debug points of curve on top? (original stroke points) */
+ if (debug) {
+ bGPDspoint *pt;
+ int i;
+
+ glBegin(GL_POINTS);
+ for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+ if (sflag & GP_STROKE_2DSPACE) {
+ glVertex2f(pt->x, pt->y);
+ }
+ else {
+ const float x= (pt->x / 1000 * winx);
+ const float y= (pt->y / 1000 * winy);
+
+ glVertex2f(x, y);
+ }
+ }
+ glEnd();
}
}
+/* ----- General Drawing ------ */
+
/* draw a set of strokes */
static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, short debug,
short lthick, float color[4])
@@ -431,9 +616,26 @@ static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, shor
/* set color first (may need to reset it again later too) */
glColor4f(color[0], color[1], color[2], color[3]);
- for (gps= gpf->strokes.first; gps; gps= gps->next) {
- /* just draw the stroke once */
- gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
+ for (gps= gpf->strokes.first; gps; gps= gps->next) {
+ /* check if stroke can be drawn */
+ if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE))
+ continue;
+ if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE))
+ continue;
+ if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE))
+ continue;
+ if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE))
+ continue;
+ if ((gps->points == 0) || (gps->totpoints < 1))
+ continue;
+
+ /* check which stroke-drawer to use */
+ if (gps->totpoints == 1)
+ gp_draw_stroke_point(gps->points, gps->flag, winx, winy);
+ else if (dflag & GP_DRAWDATA_ONLY3D)
+ gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
+ else if (gps->totpoints > 1)
+ gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
}
}
@@ -489,8 +691,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* check if frame is drawable */
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
- tcolor[3] = color[3] - (i * 0.7);
- gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+ tcolor[3] = color[3] - (i/gpl->gstep);
+ gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@@ -501,8 +703,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* check if frame is drawable */
if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
- tcolor[3] = color[3] - (i * 0.7);
- gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+ tcolor[3] = color[3] - (i/gpl->gstep);
+ gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@@ -515,12 +717,12 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* draw the strokes for the ghost frames (at half of the alpha set by user) */
if (gpf->prev) {
tcolor[3] = (color[3] / 7);
- gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+ gp_draw_strokes(gpf->prev, winx, winy, dflag, debug, lthick, tcolor);
}
if (gpf->next) {
tcolor[3] = (color[3] / 4);
- gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+ gp_draw_strokes(gpf->next, winx, winy, dflag, debug, lthick, tcolor);
}
/* restore alpha */
@@ -533,15 +735,13 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
- * that is being edited. (Stroke cache is currently stored in gp-data)
+ * that is being edited. (Stroke buffer is currently stored in gp-data)
*/
if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) &&
(gpf->flag & GP_FRAME_PAINT))
{
/* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */
- setlinestyle(2);
- gp_draw_stroke(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, debug, winx, winy);
- setlinestyle(0);
+ gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
}
}
@@ -594,7 +794,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
glColor4f(0, 0, 0, 1);
}
-/* ----------- */
+/* ----- Grease Pencil Sketches Drawing API ------ */
/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
* Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes
diff --git a/source/blender/src/editimasel.c b/source/blender/src/editimasel.c
index 67e10d771e0..97ddc2e0f1d 100644
--- a/source/blender/src/editimasel.c
+++ b/source/blender/src/editimasel.c
@@ -1076,6 +1076,12 @@ void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
toggle_blockhandler(sa, IMASEL_HANDLER_IMAGE, UI_PNL_UNSTOW);
scrarea_queue_winredraw(sa);
break;
+ case HKEY:
+ simasel->flag ^= FILE_HIDE_DOT;
+ BIF_filelist_free(simasel->files);
+ do_draw= 1;
+ do_headdraw= 1;
+ break;
case PKEY:
if(G.qual & LR_SHIFTKEY) {
extern char bprogname[]; /* usiblender.c */
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 672e3d3efd1..59952c7d568 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -82,6 +82,7 @@
#include "BKE_group.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
+#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_particle.h"
#include "BKE_texture.h"
@@ -999,6 +1000,9 @@ static void make_editipo(void)
ob->ipowin= ID_TE;
make_texture_editipo(G.sipo);
}
+ else if(G.scene->world && give_current_world_texture()) {
+ make_texture_editipo(G.sipo);
+ }
}
else if(G.sipo->blocktype==ID_CA) {
if (ob) {
@@ -1186,6 +1190,11 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
*from= (ID *)tex;
if(tex) *ipo= tex->ipo;
}
+ else if(G.scene->world) {
+ Tex *tex= give_current_world_texture();
+ *from= (ID *)tex;
+ if(tex) *ipo= tex->ipo;
+ }
}
else if(blocktype==ID_MA) {
if(ob) {
@@ -6073,4 +6082,4 @@ void move_to_frame(void)
}
}
BIF_undo_push("Set frame to selected Ipo vertex");
-}
+} \ No newline at end of file
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 2f9addb106e..cbf7691754d 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -3506,6 +3506,17 @@ void copy_attr(short event)
base->object->damping= ob->damping;
base->object->rdamping= ob->rdamping;
}
+ else if(event==11) { /* all physical attributes */
+ base->object->gameflag = ob->gameflag;
+ base->object->inertia = ob->inertia;
+ base->object->formfactor = ob->formfactor;
+ base->object->damping= ob->damping;
+ base->object->rdamping= ob->rdamping;
+ base->object->mass= ob->mass;
+ if (ob->gameflag & OB_BOUNDS) {
+ base->object->boundtype = ob->boundtype;
+ }
+ }
else if(event==17) { /* tex space */
copy_texture_space(base->object, ob);
}
@@ -3692,7 +3703,7 @@ void copy_attr_menu()
* view3d_edit_object_copyattrmenu() and in toolbox.c
*/
- strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l");
+ strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l");
strcat (str, "|Object Constraints%x22");
strcat (str, "|NLA Strips%x26");
diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c
index 7473fd32f2b..8110714e327 100644
--- a/source/blender/src/editview.c
+++ b/source/blender/src/editview.c
@@ -298,7 +298,7 @@ int lasso_inside(short mcords[][2], short moves, short sx, short sy)
}
/* edge version for lasso select. we assume boundbox check was done */
-static int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1)
+int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1)
{
short v1[2], v2[2];
int a;
@@ -371,7 +371,7 @@ static void do_lasso_select_objects(short mcords[][2], short moves, short select
}
}
-static void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
+void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
{
short a;
diff --git a/source/blender/src/gpencil.c b/source/blender/src/gpencil.c
index 24ed6a7b0ba..eef21323a44 100644
--- a/source/blender/src/gpencil.c
+++ b/source/blender/src/gpencil.c
@@ -48,6 +48,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_vec_types.h"
#include "DNA_view3d_types.h"
#include "BKE_global.h"
@@ -57,6 +58,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_butspace.h"
+#include "BIF_editview.h"
#include "BIF_graphics.h"
#include "BIF_interface.h"
#include "BIF_mywindow.h"
@@ -683,7 +685,7 @@ typedef struct tGPsdata {
bGPDframe *gpf; /* frame we're working on */
short status; /* current status of painting */
- short paintmode; /* mode for painting (L_MOUSE or R_MOUSE for now) */
+ short paintmode; /* mode for painting */
} tGPsdata;
/* values for tGPsdata->status */
@@ -693,6 +695,12 @@ enum {
GP_STATUS_DONE /* painting done */
};
+/* values for tGPsdata->paintmode */
+enum {
+ GP_PAINTMODE_DRAW = 0,
+ GP_PAINTMODE_ERASER
+};
+
/* Return flags for adding points to stroke buffer */
enum {
GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */
@@ -710,9 +718,9 @@ static void gp_session_validatebuffer (tGPsdata *p)
/* clear memory of buffer (or allocate it if starting a new session) */
if (gpd->sbuffer)
- memset(gpd->sbuffer, 0, sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX);
+ memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX);
else
- gpd->sbuffer= MEM_callocN(sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
+ gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
/* reset indices */
gpd->sbuffer_size = 0;
@@ -850,6 +858,25 @@ static void gp_session_cleanup (tGPsdata *p)
gpd->sbuffer_sflag= 0;
}
+/* check if the current mouse position is suitable for adding a new point */
+static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2])
+{
+ short dx= abs(mval[0] - pmval[0]);
+ short dy= abs(mval[1] - pmval[1]);
+
+ /* check if mouse moved at least certain distance on both axes (best case) */
+ if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX))
+ return 1;
+
+ /* check if the distance since the last point is significant enough */
+ else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX)
+ return 1;
+
+ /* mouse 'didn't move' */
+ else
+ return 0;
+}
+
/* convert screen-coordinates to buffer-coordinates */
static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
{
@@ -884,43 +911,24 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
}
}
-/* check if the current mouse position is suitable for adding a new point */
-static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2])
-{
- short dx= abs(mval[0] - pmval[0]);
- short dy= abs(mval[1] - pmval[1]);
-
- /* check if mouse moved at least certain distance on both axes (best case) */
- if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX))
- return 1;
-
- /* check if the distance since the last point is significant enough */
- else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX)
- return 1;
-
- /* mouse 'didn't move' */
- else
- return 0;
-}
-
/* add current stroke-point to buffer (returns whether point was successfully added) */
static short gp_stroke_addpoint (tGPsdata *p, short mval[2], float pressure)
{
bGPdata *gpd= p->gpd;
- bGPDspoint *pt;
+ tGPspoint *pt;
/* check if still room in buffer */
if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX)
return GP_STROKEADD_OVERFLOW;
-
/* get pointer to destination point */
- pt= gpd->sbuffer + gpd->sbuffer_size;
+ pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size);
- /* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, mval, &pt->x);
-
- /* store other settings */
+ /* store settings */
+ pt->x= mval[0];
+ pt->y= mval[1];
+ pt->xf= (float)mval[0];
+ pt->yf= (float)mval[0];
pt->pressure= pressure;
/* increment counters */
@@ -933,38 +941,13 @@ static short gp_stroke_addpoint (tGPsdata *p, short mval[2], float pressure)
return GP_STROKEADD_NORMAL;
}
-/* smooth a stroke (in buffer) before storing it */
-static void gp_stroke_smooth (tGPsdata *p)
-{
- bGPdata *gpd= p->gpd;
- int i=0, cmx=gpd->sbuffer_size;
-
- // fixme: currently disabled as it damages too much sometimes
- return;
-
- /* don't try if less than 2 points in buffer */
- if ((cmx <= 2) || (gpd->sbuffer == NULL))
- return;
-
- /* apply weighting-average (note doing this along path sequentially does introduce slight error) */
- for (i=0; i < gpd->sbuffer_size; i++) {
- bGPDspoint *pc= (gpd->sbuffer + i);
- bGPDspoint *pb= (i-1 > 0)?(pc-1):(pc);
- bGPDspoint *pa= (i-2 > 0)?(pc-2):(pb);
- bGPDspoint *pd= (i+1 < cmx)?(pc+1):(pc);
- bGPDspoint *pe= (i+2 < cmx)?(pc+2):(pd);
-
- pc->x= (0.1*pa->x + 0.2*pb->x + 0.4*pc->x + 0.2*pd->x + 0.1*pe->x);
- pc->y= (0.1*pa->y + 0.2*pb->y + 0.4*pc->y + 0.2*pd->y + 0.1*pe->y);
- }
-}
-
/* make a new stroke from the buffer data */
static void gp_stroke_newfrombuffer (tGPsdata *p)
{
bGPdata *gpd= p->gpd;
bGPDstroke *gps;
- bGPDspoint *pt, *ptc;
+ bGPDspoint *pt;
+ tGPspoint *ptc;
int i, totelem;
/* get total number of points to allocate space for */
@@ -990,7 +973,12 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
/* copy points from the buffer to the stroke */
for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) {
- memcpy(pt, ptc, sizeof(bGPDspoint));
+ /* convert screen-coordinates to appropriate coordinates (and store them) */
+ gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+
+ /* copy pressure */
+ pt->pressure= ptc->pressure;
+
pt++;
}
@@ -998,10 +986,220 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
BLI_addtail(&p->gpf->strokes, gps);
}
+/* --- 'Eraser' for 'Paint' Tool ------ */
+/* User should draw 'circles' around the parts of the sketches they wish to
+ * delete instead of drawing squiggles over existing lines. This should be
+ * easier to manage than if it was done otherwise.
+ */
+
+/* convert gp-buffer stroke into mouse-coordinates array */
+static short (*gp_stroke_eraser_2mco (bGPdata *gpd))[2]
+{
+ tGPspoint *pt;
+ short (*mcoords)[2];
+ int i;
+
+ /* allocate memory for coordinates array */
+ mcoords= MEM_mallocN(sizeof(*mcoords)*gpd->sbuffer_size,"gp_buf_mcords");
+
+ /* copy coordinates */
+ for (pt=gpd->sbuffer, i=0; i < gpd->sbuffer_size; i++, pt++) {
+ mcoords[i][0]= pt->x;
+ mcoords[i][1]= pt->y;
+ }
+
+ /* return */
+ return mcoords;
+}
+
+/* eraser tool - remove segment from stroke/split stroke (after lasso inside) */
+static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
+{
+ bGPDspoint *pt_tmp= gps->points;
+ bGPDstroke *gsn = NULL;
+
+ /* if stroke only had two points, get rid of stroke */
+ if (gps->totpoints == 2) {
+ /* free stroke points, then stroke */
+ MEM_freeN(pt_tmp);
+ BLI_freelinkN(&gpf->strokes, gps);
+
+ /* nothing left in stroke, so stop */
+ return 1;
+ }
+
+ /* if last segment, just remove segment from the stroke */
+ else if (i == gps->totpoints - 2) {
+ /* allocate new points array, and assign most of the old stroke there */
+ gps->totpoints--;
+ gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
+ memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*gps->totpoints);
+
+ /* free temp buffer */
+ MEM_freeN(pt_tmp);
+
+ /* nothing left in stroke, so stop */
+ return 1;
+ }
+
+ /* if first segment, just remove segment from the stroke */
+ else if (i == 0) {
+ /* allocate new points array, and assign most of the old stroke there */
+ gps->totpoints--;
+ gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
+ memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint)*gps->totpoints);
+
+ /* free temp buffer */
+ MEM_freeN(pt_tmp);
+
+ /* no break here, as there might still be stuff to remove in this stroke */
+ return 0;
+ }
+
+ /* segment occurs in 'middle' of stroke, so split */
+ else {
+ /* duplicate stroke, and assign 'later' data to that stroke */
+ gsn= MEM_dupallocN(gps);
+ gsn->prev= gsn->next= NULL;
+ BLI_insertlinkafter(&gpf->strokes, gps, gsn);
+
+ gsn->totpoints= gps->totpoints - i;
+ gsn->points= MEM_callocN(sizeof(bGPDspoint)*gsn->totpoints, "gp_stroke_points");
+ memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint)*gsn->totpoints);
+
+ /* adjust existing stroke */
+ gps->totpoints= i;
+ gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
+ memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*i);
+
+ /* free temp buffer */
+ MEM_freeN(pt_tmp);
+
+ /* nothing left in stroke, so stop */
+ return 1;
+ }
+}
+
+/* eraser tool - evaluation per stroke */
+static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
+{
+ bGPDspoint *pt1, *pt2;
+ short x0=0, y0=0, x1=0, y1=0;
+ short xyval[2];
+ int i;
+
+ if (gps->totpoints == 0) {
+ /* just free stroke */
+ if (gps->points)
+ MEM_freeN(gps->points);
+ BLI_freelinkN(&gpf->strokes, gps);
+ }
+ else if (gps->totpoints == 1) {
+ /* get coordinates */
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ // FIXME: this may not be the correct correction
+ project_short(&gps->points->x, xyval);
+ x0= xyval[0];
+ x1= xyval[1];
+ }
+ else if (gps->flag & GP_STROKE_2DSPACE) {
+ ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval);
+ x0= xyval[0];
+ y0= xyval[1];
+ }
+ else {
+ x0= (gps->points->x / 1000 * p->sa->winx);
+ y0= (gps->points->y / 1000 * p->sa->winy);
+ }
+
+ /* do boundbox check first */
+ if (BLI_in_rcti(rect, x0, y0)) {
+ /* only check if point is inside */
+ if (lasso_inside(mcoords, moves, x0, y0)) {
+ /* free stroke */
+ MEM_freeN(gps->points);
+ BLI_freelinkN(&gpf->strokes, gps);
+ }
+ }
+ }
+ else {
+ /* loop over the points in the stroke, checking for intersections
+ * - an intersection will require the stroke to be split
+ */
+ for (i=0; (i+1) < gps->totpoints; i++) {
+ /* get points to work with */
+ pt1= gps->points + i;
+ pt2= gps->points + i + 1;
+
+ /* get coordinates */
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ // FIXME: may not be correct correction
+ project_short(&gps->points->x, xyval);
+ x0= xyval[0];
+ x1= xyval[1];
+ }
+ else if (gps->flag & GP_STROKE_2DSPACE) {
+ ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval);
+ x0= xyval[0];
+ y0= xyval[1];
+
+ ipoco_to_areaco_noclip(p->v2d, &pt2->x, xyval);
+ x1= xyval[0];
+ y1= xyval[1];
+ }
+ else {
+ x0= (pt1->x / 1000 * p->sa->winx);
+ y0= (pt1->y / 1000 * p->sa->winy);
+ x1= (pt2->x / 1000 * p->sa->winx);
+ y1= (pt2->y / 1000 * p->sa->winy);
+ }
+
+ /* check that point segment of the boundbox of the eraser stroke */
+ if (BLI_in_rcti(rect, x0, y0) || BLI_in_rcti(rect, x1, y1)) {
+ /* check if point segment of stroke had anything to do with
+ * eraser region (either within stroke painted, or on its lines)
+ * - this assumes that linewidth is irrelevant
+ * - handled using the lasso-select checking code
+ */
+ if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) {
+ /* if function returns true, break this loop (as no more point to check) */
+ if (gp_stroke_eraser_splitdel(gpf, gps, i))
+ break;
+ }
+ }
+ }
+ }
+}
+
+/* -------- */
+
+/* erase strokes which fall under the eraser strokes */
+static void gp_stroke_doeraser (tGPsdata *p)
+{
+ bGPdata *gpd= p->gpd;
+ bGPDframe *gpf= p->gpf;
+ bGPDstroke *gps, *gpn;
+ short (*mcoords)[2];
+ rcti rect;
+
+ /* get buffer-stroke coordinates as shorts array, and then get bounding box */
+ mcoords= gp_stroke_eraser_2mco(gpd);
+ lasso_select_boundbox(&rect, mcoords, gpd->sbuffer_size);
+
+ /* loop over strokes, checking segments for intersections */
+ for (gps= gpf->strokes.first; gps; gps= gpn) {
+ gpn= gps->next;
+ gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, &rect, gpf, gps);
+ }
+
+ /* free mcoords array */
+ MEM_freeN(mcoords);
+}
+
/* ---------- 'Paint' Tool ------------ */
/* init new stroke */
-static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
+static void gp_paint_initstroke (tGPsdata *p, short paintmode)
{
/* get active layer (or add a new one if non-existent) */
p->gpl= gpencil_layer_getactive(p->gpd);
@@ -1025,14 +1223,10 @@ static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
else
p->gpf->flag |= GP_FRAME_PAINT;
- /* set 'eraser' for this stroke if using eraser or right-mouse in action */
- if ( get_activedevice() == 2 || (mousebutton & R_MOUSE) ) {
+ /* set 'eraser' for this stroke if using eraser */
+ p->paintmode= paintmode;
+ if (p->paintmode == GP_PAINTMODE_ERASER)
p->gpd->sbuffer_sflag |= GP_STROKE_ERASER;
-
- // for now: eraser isn't ready for prime-time yet, so no painting available here yet
- p->status= GP_STATUS_ERROR;
- return;
- }
/* check if points will need to be made in view-aligned space */
if (p->gpd->flag & GP_DATA_VIEWALIGN) {
@@ -1062,12 +1256,10 @@ static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
static void gp_paint_strokeend (tGPsdata *p)
{
- /* sanitize stroke-points in buffer (remove jitter) */
- gp_stroke_smooth(p);
-
/* check if doing eraser or not */
if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) {
/* get rid of relevant sections of strokes */
+ gp_stroke_doeraser(p);
}
else {
/* transfer stroke to frame */
@@ -1100,7 +1292,7 @@ static void gp_paint_cleanup (tGPsdata *p)
/* -------- */
/* main call to paint a new stroke */
-short gpencil_paint (short mousebutton)
+short gpencil_paint (short mousebutton, short paintmode)
{
tGPsdata p;
short prevmval[2], mval[2];
@@ -1113,7 +1305,7 @@ short gpencil_paint (short mousebutton)
gp_session_cleanup(&p);
return 0;
}
- gp_paint_initstroke(&p, mousebutton);
+ gp_paint_initstroke(&p, paintmode);
if (p.status == GP_STATUS_ERROR) {
gp_session_cleanup(&p);
return 0;
@@ -1188,7 +1380,10 @@ short gpencil_paint (short mousebutton)
setcursor_space(p.sa->spacetype, CURSOR_STD);
/* check size of buffer before cleanup, to determine if anything happened here */
- ok= p.gpd->sbuffer_size;
+ if (paintmode == GP_PAINTMODE_ERASER)
+ ok= (p.gpd->sbuffer_size > 1);
+ else
+ ok= p.gpd->sbuffer_size;
/* cleanup */
gp_paint_cleanup(&p);
@@ -1202,7 +1397,7 @@ short gpencil_paint (short mousebutton)
/* All event (loops) handling checking if stroke drawing should be initiated
* should call this function.
*/
-short gpencil_do_paint (ScrArea *sa, short mousebutton)
+short gpencil_do_paint (ScrArea *sa, short mbut)
{
bGPdata *gpd = gpencil_data_getactive(sa);
short retval= 0;
@@ -1211,18 +1406,43 @@ short gpencil_do_paint (ScrArea *sa, short mousebutton)
if (gpd == NULL)
return 0;
- /* currently, we will only paint if:
+ /* currently, we will only 'paint' if:
* 1. draw-mode on gpd is set (for accessibility reasons)
* (single 'dots' are only available via this method)
* 2. if shift-modifier is held + lmb -> 'quick paint'
+ *
+ * OR
+ *
+ * draw eraser stroke if:
+ * 1. using the eraser on a tablet
+ * 2. draw-mode on gpd is set (for accessiblity reasons)
+ * (eraser is mapped to right-mouse)
+ * 3. Alt + 'select' mouse-button
+ * i.e. if LMB = select: Alt-LMB
+ * if RMB = select: Alt-RMB
*/
- if (gpd->flag & GP_DATA_EDITPAINT) {
- /* try to paint */
- retval = gpencil_paint(mousebutton);
+ if (get_activedevice() == 2) {
+ /* eraser on a tablet - always try to erase strokes */
+ retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
+ }
+ else if (gpd->flag & GP_DATA_EDITPAINT) {
+ /* try to paint/erase */
+ if (mbut == L_MOUSE)
+ retval = gpencil_paint(mbut, GP_PAINTMODE_DRAW);
+ else if (mbut == R_MOUSE)
+ retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
}
- else if (!(gpd->flag & GP_DATA_LMBPLOCK) && (G.qual == LR_SHIFTKEY)) {
- /* try to paint */
- retval = gpencil_paint(mousebutton);
+ else if (!(gpd->flag & GP_DATA_LMBPLOCK)) {
+ /* try to paint/erase as not locked */
+ if ((G.qual == LR_SHIFTKEY) && (mbut == L_MOUSE)) {
+ retval = gpencil_paint(mbut, GP_PAINTMODE_DRAW);
+ }
+ else if (G.qual == LR_ALTKEY) {
+ if ((U.flag & USER_LMOUSESELECT) && (mbut == L_MOUSE))
+ retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
+ else if (!(U.flag & USER_LMOUSESELECT) && (mbut == R_MOUSE))
+ retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER);
+ }
}
/* return result of trying to paint */
diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c
index 8f460b85245..17a1604892d 100644
--- a/source/blender/src/header_info.c
+++ b/source/blender/src/header_info.c
@@ -543,6 +543,40 @@ static void check_packAll()
}
}
+static void copy_game_dll(char *dll_filename, char *source_dir, char *dest_dir)
+{
+ char source_filename[FILE_MAX];
+ char dest_filename[FILE_MAX];
+
+ strcpy( source_filename, source_dir );
+ strcat( source_filename, dll_filename );
+
+ strcpy( dest_filename, dest_dir );
+ strcat( dest_filename, dll_filename );
+
+ if(!BLI_exists(dest_filename)) {
+ BLI_copy_fileops( source_filename, dest_filename );
+ }
+}
+
+static void copy_all_game_dlls(char *str)
+{
+#define GAME_DLL_COUNT 7
+ char *game_dll_list[GAME_DLL_COUNT]={"gnu_gettext.dll", "libpng.dll", "libtiff.dll", "pthreadVC2.dll", "python25.dll", "SDL.dll", "zlib.dll"};
+
+ char dest_dir[FILE_MAX];
+ char source_dir[FILE_MAX];
+ int i;
+
+ strcpy(source_dir, get_install_dir());
+ strcat(source_dir, "\\");
+ BLI_split_dirfile_basic(str, dest_dir, NULL);
+
+ for (i= 0; i< GAME_DLL_COUNT; i++) {
+ copy_game_dll(game_dll_list[i], source_dir, dest_dir );
+ };
+}
+
static int write_runtime(char *str, char *exename)
{
char *freestr= NULL;
@@ -590,7 +624,14 @@ static void write_runtime_check(char *str)
#endif
write_runtime(str, player);
+
+#ifdef _WIN32
+ // get a list of the .DLLs in the Blender folder and copy all of these to the destination folder if they don't exist
+ copy_all_game_dlls(str);
+#endif
}
+
+
/* end keyed functions */
/************************** MAIN MENU *****************************/
@@ -1029,7 +1070,7 @@ static uiBlock *info_externalfiles(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "info_externalfiles", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_info_externalfiles, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack into Blend", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack into .blend file", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
#if 0
uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Removes all packed files from the project and saves them to the current directory");
#endif
@@ -1039,8 +1080,8 @@ static uiBlock *info_externalfiles(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Relative", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Absolute", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 13, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@@ -1081,9 +1122,9 @@ static uiBlock *info_filemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
#if GAMEBLENDER == 1
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Game As Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
#ifdef _WIN32
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Dynamic Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, "");
+// uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Dynamic Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, "");
#endif
#endif
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c
index 8dd2d590adf..9c51ac65b11 100644
--- a/source/blender/src/header_ipo.c
+++ b/source/blender/src/header_ipo.c
@@ -981,7 +981,7 @@ static char *ipo_modeselect_pup(void)
if(ob && ob->type==OB_LAMP)
str += sprintf(str,formatstring, "Lamp",ID_LA, ICON_LAMP);
- if(ob && give_current_texture(ob, ob->actcol))
+ if((ob && give_current_texture(ob, ob->actcol))||(give_current_world_texture()))
str += sprintf(str,formatstring, "Texture",ID_TE, ICON_TEXTURE);
if(ob){
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index 58a2a4c6ab3..81e8a010371 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -166,9 +166,9 @@ void do_layer_buttons(short event)
if(event==-1 && (G.qual & LR_CTRLKEY)) {
G.vd->scenelock= !G.vd->scenelock;
do_view3d_buttons(B_SCENELOCK);
- } else if (event==-1) {
+ } else if (event<0) {
if(G.vd->lay== (1<<20)-1) {
- if(G.qual & LR_SHIFTKEY) G.vd->lay= oldlay;
+ if(event==-2 || G.qual & LR_SHIFTKEY) G.vd->lay= oldlay;
}
else {
oldlay= G.vd->lay;
@@ -605,6 +605,9 @@ static void do_view3d_viewmenu(void *arg, int event)
case 21: /* Grease Pencil */
add_blockhandler(curarea, VIEW3D_HANDLER_GREASEPENCIL, UI_PNL_UNSTOW);
break;
+ case 22: /* View all layers */
+ do_layer_buttons(-2);
+ break;
}
allqueue(REDRAWVIEW3D, 1);
}
@@ -648,6 +651,11 @@ static uiBlock *view3d_viewmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ if(G.vd->lay== (1<<20)-1) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Previous Layers|Shift ~", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 22, "");
+ else uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show All Layers| ~", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 22, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
if(G.vd->localview) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Local View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Local View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
if(!G.vd->localview) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Global View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
@@ -726,6 +734,9 @@ void do_view3d_select_object_typemenu(void *arg, int event)
case 10: /* Lamp */
selectall_type(OB_LAMP);
break;
+ case 20:
+ do_layer_buttons(-2);
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -2196,6 +2207,7 @@ static uiBlock *view3d_edit_object_copyattrmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mass|Ctrl C, 7", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Damping|Ctrl C, 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "All Physical Attributes|Ctrl C, 11", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Properties|Ctrl C, 9", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Logic Bricks|Ctrl C, 10", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Protected Transform |Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 29, "");
@@ -2466,8 +2478,11 @@ static void do_view3d_edit_objectmenu(void *arg, int event)
case 15: /* Object Panel */
add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
break;
+ case 16: /* make proxy object*/
+ make_proxy();
+ break;
#ifdef WITH_VERSE
- case 16: /* Share Object at Verse server */
+ case 17: /* Share Object at Verse server */
if(session_list.first != session_list.last) session = session_menu();
else session = session_list.first;
if(session) b_verse_push_object(session, ob);
@@ -2492,7 +2507,7 @@ static uiBlock *view3d_edit_objectmenu(void *arg_unused)
if (base) ob= base->object;
if(ob && (ob->type == OB_MESH) && (!ob->vnode)) {
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Share at Verse Server", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Share at Verse Server", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
}
}
@@ -2518,6 +2533,7 @@ static uiBlock *view3d_edit_objectmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Proxy|Ctrl Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
uiDefIconTextBlockBut(block, view3d_edit_object_makelinksmenu, NULL, ICON_RIGHTARROW_THIN, "Make Links", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_object_singleusermenu, NULL, ICON_RIGHTARROW_THIN, "Make Single User", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_object_makelocalmenu, NULL, ICON_RIGHTARROW_THIN, "Make Local", 0, yco-=20, 120, 19, "");
diff --git a/source/blender/src/meshlaplacian.c b/source/blender/src/meshlaplacian.c
index 4d84672185a..60f569ecf0e 100644
--- a/source/blender/src/meshlaplacian.c
+++ b/source/blender/src/meshlaplacian.c
@@ -1281,9 +1281,9 @@ static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co)
outside[1] = co[1] + (mdb->max[1] - mdb->min[1] + 1.0f)*MESHDEFORM_OFFSET[i][1];
outside[2] = co[2] + (mdb->max[2] - mdb->min[2] + 1.0f)*MESHDEFORM_OFFSET[i][2];
+ VECCOPY(start, co);
VECSUB(dir, outside, start);
Normalize(dir);
- VECCOPY(start, co);
isect = meshdeform_ray_tree_intersect(mdb, start, outside);
if(isect && !isect->facing)
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index f4cfaba0fda..449c4db13de 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -5137,7 +5137,10 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
- if(doredraw) scrarea_queue_winredraw(curarea);
+ if(doredraw) {
+ scrarea_queue_winredraw(curarea);
+ scrarea_queue_headredraw(curarea);
+ }
}
diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c
index 94d38ee1635..8a8d7c8cec7 100644
--- a/source/blender/src/toolbox.c
+++ b/source/blender/src/toolbox.c
@@ -125,8 +125,6 @@
void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
{
- if( isalpha(ch)==0 ) return;
-
if( isupper(ch) ) {
*qual= LEFTSHIFTKEY;
ch= tolower(ch);
@@ -804,7 +802,10 @@ static void tb_do_hotkey(void *arg, int event)
case 'd': key= PAGEDOWNKEY; break;
}
}
- else asciitoraw(event, &key, &qual[3]);
+ else if (isalpha(event))
+ asciitoraw(event, &key, &qual[3]);
+ else if (event == '~')
+ key = ACCENTGRAVEKEY;
for (i=0;i<4;i++)
{
@@ -1213,6 +1214,8 @@ static TBitem tb_view[]= {
{ 0, "Ortho/Perspective|NumPad 5", TB_PAD|'5', NULL},
{ 0, "Local/Global View|NumPad /", TB_PAD|'/', NULL},
{ 0, "SEPR", 0, NULL},
+{ 0, "Show All Layers|Shift ~", TB_SHIFT|'~', NULL},
+{ 0, "SEPR", 0, NULL},
{ 0, "Align View", 0, tb_view_alignview},
{ 0, "SEPR", 0, NULL},
{ 0, "View Selected|NumPad .", TB_PAD|'.', NULL},
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 5d6dd694765..2ee8b54a014 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -57,24 +57,12 @@
BL_ActionActuator::~BL_ActionActuator()
{
-
- if (m_pose) {
- free_pose_channels(m_pose);
- MEM_freeN(m_pose);
- m_pose = NULL;
- };
-
- if (m_userpose){
- free_pose_channels(m_userpose);
- MEM_freeN(m_userpose);
- m_userpose=NULL;
- }
- if (m_blendpose) {
- free_pose_channels(m_blendpose);
- MEM_freeN(m_blendpose);
- m_blendpose = NULL;
- };
-
+ if (m_pose)
+ free_pose(m_pose);
+ if (m_userpose)
+ free_pose(m_userpose);
+ if (m_blendpose)
+ free_pose(m_blendpose);
}
void BL_ActionActuator::ProcessReplica(){
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index f73d5b42a01..09f1d9d4d87 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -82,10 +82,8 @@ void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica)
BL_ArmatureObject::~BL_ArmatureObject()
{
- if (m_mrdPose){
- free_pose_channels(m_mrdPose);
- MEM_freeN(m_mrdPose);
- }
+ if (m_mrdPose)
+ free_pose(m_mrdPose);
}
/* note, you can only call this for exisiting Armature objects, and not mix it with other Armatures */
@@ -172,12 +170,13 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose)
// copy_pose (&m_mrdPose, m_pose, 0);
//}
- if (!*pose)
+ if (!*pose) {
// must duplicate the constraints too otherwise we have corruption in free_pose_channels()
// because it will free the blender constraints.
// Ideally, blender should rememeber that the constraints were not copied so that
// free_pose_channels() would not free them.
copy_pose(pose, m_objArma->pose, 1);
+ }
else
extract_pose_from_pose(*pose, m_objArma->pose);
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index fce41ba8bd1..54e6884be20 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -628,7 +628,8 @@ BL_Material* ConvertMaterial(
material->transp = TF_ALPHA;
// always zsort alpha + add
- if(material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) {
+ if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha)
+ && (material->transp != TF_CLIP)) {
material->ras_mode |= ALPHA;
material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
}
@@ -1853,7 +1854,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (converter->addInitFromFrame)
if (!isInActiveLayer)
addobj=false;
-
+
if (gameobj&&addobj)
{
MT_Point3 posPrev;
@@ -2437,13 +2438,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter);
+ // set the init state to all objects
+ gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
}
- // apply the initial state to controllers
- for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
+ // apply the initial state to controllers, only on the active objects as this registers the sensors
+ for ( i=0;i<objectlist->GetCount();i++)
{
- KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
- struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
gameobj->ResetState();
}
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 7c9df688d45..5e433bb821b 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -733,9 +733,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
gameobj->AddSensor(gamesensor);
// only register to manager if it's in an active layer
-
- if (isInActiveLayer)
- gamesensor->RegisterToManager();
+ // Make registration dynamic: only when sensor is activated
+ //if (isInActiveLayer)
+ // gamesensor->RegisterToManager();
for (int i=0;i<sens->totlinks;i++)
diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
index 2c8aa854c8c..d2198f4d281 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
@@ -48,19 +48,10 @@ SCA_ActuatorEventManager::~SCA_ActuatorEventManager()
}
-
-
-void SCA_ActuatorEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-}
-
-
-
void SCA_ActuatorEventManager::NextFrame()
{
// check for changed actuator
- for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
(*it)->Activate(m_logicmgr,NULL);
}
@@ -69,7 +60,7 @@ void SCA_ActuatorEventManager::NextFrame()
void SCA_ActuatorEventManager::UpdateFrame()
{
// update the state of actuator before executing them
- for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
((SCA_ActuatorSensor*)(*it))->Update();
}
diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
index e1a9ed71a36..207c9723115 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
+++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
@@ -44,7 +44,6 @@ public:
virtual ~SCA_ActuatorEventManager();
virtual void NextFrame();
virtual void UpdateFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
//SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
};
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
index ab3bc2cc4ee..4cd2dfba994 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
@@ -51,16 +51,9 @@ SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
void SCA_AlwaysEventManager::NextFrame()
{
- for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
- SCA_ISensor* sensor = *i;
- sensor->Activate(m_logicmgr, NULL);
+ (*i)->Activate(m_logicmgr, NULL);
}
}
-
-
-void SCA_AlwaysEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-}
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
index 28c71512875..a619eecddd4 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
@@ -39,7 +39,6 @@ class SCA_AlwaysEventManager : public SCA_EventManager
public:
SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
};
diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp
index 0169864a133..e4fd0379597 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_EventManager.cpp
@@ -45,17 +45,14 @@ SCA_EventManager::~SCA_EventManager()
{
}
-
+void SCA_EventManager::RegisterSensor(class SCA_ISensor* sensor)
+{
+ m_sensors.insert(sensor);
+}
void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor)
{
- std::vector<SCA_ISensor*>::iterator i =
- std::find(m_sensors.begin(), m_sensors.end(), sensor);
- if (!(i == m_sensors.end()))
- {
- std::swap(*i, m_sensors.back());
- m_sensors.pop_back();
- }
+ m_sensors.erase(sensor);
}
void SCA_EventManager::NextFrame(double curtime, double fixedtime)
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
index 9cc1718cd1e..9dbb5a6d24f 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.h
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -30,12 +30,14 @@
#define __KX_EVENTMANAGER
#include <vector>
+#include <set>
#include <algorithm>
class SCA_EventManager
{
protected:
- std::vector <class SCA_ISensor*> m_sensors;
+ // use a set to speed-up insertion/removal
+ std::set <class SCA_ISensor*> m_sensors;
public:
enum EVENT_MANAGER_TYPE {
@@ -61,7 +63,7 @@ public:
virtual void NextFrame();
virtual void UpdateFrame();
virtual void EndFrame();
- virtual void RegisterSensor(class SCA_ISensor* sensor)=0;
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
int GetType();
protected:
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 25b4af696ea..b0f8decee26 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -337,12 +337,31 @@ void SCA_IObject::Resume(void)
void SCA_IObject::SetState(unsigned int state)
{
- m_state = state;
- // update the status of the controllers
+ unsigned int tmpstate;
SCA_ControllerList::iterator contit;
- for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+
+ // we will update the state in two steps:
+ // 1) set the new state bits that are 1
+ // 2) clr the new state bits that are 0
+ // This to ensure continuity if a sensor is attached to two states
+ // that are switching state: no need to deactive and reactive the sensor
+
+ tmpstate = m_state | state;
+ if (tmpstate != m_state)
+ {
+ // update the status of the controllers
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ {
+ (*contit)->ApplyState(tmpstate);
+ }
+ }
+ m_state = state;
+ if (m_state != tmpstate)
{
- (*contit)->ApplyState(m_state);
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ {
+ (*contit)->ApplyState(m_state);
+ }
}
}
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index f11c8047fac..2dc49924062 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -41,7 +41,8 @@
void SCA_ISensor::ReParent(SCA_IObject* parent)
{
SCA_ILogicBrick::ReParent(parent);
- m_eventmgr->RegisterSensor(this);
+ // will be done when the sensor is activated
+ //m_eventmgr->RegisterSensor(this);
this->SetActive(false);
}
@@ -133,6 +134,7 @@ void SCA_ISensor::DecLink() {
{
// sensor is detached from all controllers, initialize it so that it
// is fresh as at startup when it is reattached again.
+ UnregisterToManager();
Init();
}
}
@@ -203,6 +205,11 @@ void SCA_ISensor::RegisterToManager()
m_eventmgr->RegisterSensor(this);
}
+void SCA_ISensor::UnregisterToManager()
+{
+ m_eventmgr->RemoveSensor(this);
+}
+
void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
{
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 51837755ba4..d5dabbce3ee 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -115,6 +115,8 @@ public:
void SetLevel(bool lvl);
void RegisterToManager();
+ void UnregisterToManager();
+
virtual float GetNumber();
/** Stop sensing for a while. */
@@ -129,7 +131,7 @@ public:
void ClrLink()
{ m_links = 0; }
void IncLink()
- { m_links++; }
+ { if (!m_links++) RegisterToManager(); }
void DecLink();
bool IsNoLink() const
{ return !m_links; }
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
index 7bf2049e56e..8ff28ba0b51 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
@@ -52,9 +52,10 @@ SCA_JoystickManager::~SCA_JoystickManager()
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
- for (unsigned int i = 0; i < m_sensors.size(); i++)
+ set<SCA_ISensor*>::iterator it;
+ for (it = m_sensors.begin(); it != m_sensors.end(); it++)
{
- SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*) m_sensors[i];
+ SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it);
if(!joysensor->IsSuspended())
{
m_joystick->HandleEvents();
@@ -64,12 +65,6 @@ void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
}
-void SCA_JoystickManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-}
-
-
SCA_Joystick *SCA_JoystickManager::GetJoystickDevice()
{
/*
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.h b/source/gameengine/GameLogic/SCA_JoystickManager.h
index 3c4df64677e..f2bb27965fa 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.h
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.h
@@ -45,7 +45,6 @@ public:
SCA_JoystickManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_JoystickManager();
virtual void NextFrame(double curtime,double deltatime);
- virtual void RegisterSensor(SCA_ISensor* sensor);
SCA_Joystick* GetJoystickDevice(void);
};
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
index 259b06134d7..6a96442b124 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
@@ -62,23 +62,14 @@ void SCA_KeyboardManager::NextFrame()
{
//const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
// cerr << "SCA_KeyboardManager::NextFrame"<< endl;
- for (unsigned int i=0;i<m_sensors.size();i++)
+ set<SCA_ISensor*>::iterator it;
+ for (it=m_sensors.begin(); it != m_sensors.end(); it++)
{
- SCA_KeyboardSensor* keysensor = (SCA_KeyboardSensor*)m_sensors[i];
- keysensor->Activate(m_logicmanager,NULL);
+ (*it)->Activate(m_logicmanager,NULL);
}
}
-
-
-void SCA_KeyboardManager::RegisterSensor(SCA_ISensor* keysensor)
-{
- m_sensors.push_back(keysensor);
-}
-
-
-
bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
return false;
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h
index b4a50f56025..8f3cc0ab715 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardManager.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h
@@ -55,7 +55,6 @@ public:
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
- virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index d1c5917f0ce..91e66aea359 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -176,12 +176,7 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
(*c)->UnlinkSensor(sensor);
}
m_sensorcontrollermapje.erase(sensor);
-
- for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
- !(ie==m_eventmanagers.end());ie++)
- {
- (*ie)->RemoveSensor(sensor);
- }
+ sensor->UnregisterToManager();
}
void SCA_LogicManager::RemoveController(SCA_IController* controller)
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp
index b4251d8ab53..ca875dad07c 100644
--- a/source/gameengine/GameLogic/SCA_MouseManager.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp
@@ -75,9 +75,10 @@ void SCA_MouseManager::NextFrame()
{
if (m_mousedevice)
{
- for (unsigned int i = 0; i < m_sensors.size(); i++)
+ set<SCA_ISensor*>::iterator it;
+ for (it=m_sensors.begin(); it!=m_sensors.end(); it++)
{
- SCA_MouseSensor* mousesensor = (SCA_MouseSensor*) m_sensors[i];
+ SCA_MouseSensor* mousesensor = (SCA_MouseSensor*)(*it);
// (0,0) is the Upper Left corner in our local window
// coordinates
if (!mousesensor->IsSuspended())
@@ -98,15 +99,6 @@ void SCA_MouseManager::NextFrame()
}
}
-
-
-void SCA_MouseManager::RegisterSensor(SCA_ISensor* keysensor)
-{
- m_sensors.push_back(keysensor);
-}
-
-
-
bool SCA_MouseManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
/* We should guard for non-mouse events maybe? A rather silly side */
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h
index bc8254486ad..efa4c639ce7 100644
--- a/source/gameengine/GameLogic/SCA_MouseManager.h
+++ b/source/gameengine/GameLogic/SCA_MouseManager.h
@@ -62,7 +62,6 @@ public:
*/
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
- virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
index fc56d101728..e5e3f9cced5 100644
--- a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
@@ -47,19 +47,10 @@ SCA_PropertyEventManager::~SCA_PropertyEventManager()
}
-
-
-void SCA_PropertyEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-}
-
-
-
void SCA_PropertyEventManager::NextFrame()
{
// check for changed properties
- for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
(*it)->Activate(m_logicmgr,NULL);
}
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
index aaa303a52c8..f166065b198 100644
--- a/source/gameengine/GameLogic/SCA_PropertyEventManager.h
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
@@ -43,7 +43,6 @@ public:
SCA_PropertyEventManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_PropertyEventManager();
virtual void NextFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
//SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
};
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
index 02020a52a17..156478d866d 100644
--- a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
@@ -50,16 +50,9 @@ SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
void SCA_RandomEventManager::NextFrame()
{
- for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
- SCA_ISensor *sensor = *i;
- sensor->Activate(m_logicmgr, NULL);
+ (*i)->Activate(m_logicmgr, NULL);
}
}
-
-
-void SCA_RandomEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-};
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h
index 8c75ef665fa..79138c23c62 100644
--- a/source/gameengine/GameLogic/SCA_RandomEventManager.h
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h
@@ -45,7 +45,6 @@ public:
SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
};
#endif //__KX_RANDOMEVENTMGR
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
index 643f1247a52..b7fadd3d62c 100644
--- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
@@ -65,6 +65,11 @@ void SCA_TimeEventManager::RegisterSensor(SCA_ISensor* sensor)
// not yet
}
+void SCA_TimeEventManager::RemoveSensor(SCA_ISensor* sensor)
+{
+ // empty
+}
+
void SCA_TimeEventManager::NextFrame(double curtime, double fixedtime)
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.h b/source/gameengine/GameLogic/SCA_TimeEventManager.h
index 2fd39661a2d..bd57e12eb44 100644
--- a/source/gameengine/GameLogic/SCA_TimeEventManager.h
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.h
@@ -45,6 +45,7 @@ public:
virtual void NextFrame(double curtime, double fixedtime);
virtual void RegisterSensor(class SCA_ISensor* sensor);
+ virtual void RemoveSensor(class SCA_ISensor* sensor);
void AddTimeProperty(CValue* timeval);
void RemoveTimeProperty(CValue* timeval);
};
diff --git a/source/gameengine/GamePlayer/common/windows/GPW_Canvas.h b/source/gameengine/GamePlayer/common/windows/GPW_Canvas.h
index bb1abd71505..bf8cb720811 100644
--- a/source/gameengine/GamePlayer/common/windows/GPW_Canvas.h
+++ b/source/gameengine/GamePlayer/common/windows/GPW_Canvas.h
@@ -36,7 +36,7 @@
#include <iostream>
#include <windows.h>
-#include <gl/gl.h>
+//#include <gl/gl.h>
#include "GPC_Canvas.h"
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
index 7b5b7fdf78c..eee8e9f6827 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
@@ -55,28 +55,13 @@ KX_NetworkEventManager::~KX_NetworkEventManager()
//printf("KX_NetworkEventManager destructor\n");
}
-void KX_NetworkEventManager::RegisterSensor(class SCA_ISensor* sensor)
-{
- //printf("KX_NetworkEventManager RegisterSensor\n");
- m_sensors.push_back(sensor);
-}
-
-void KX_NetworkEventManager::RemoveSensor(class SCA_ISensor* sensor)
-{
- //printf("KX_NetworkEventManager RemoveSensor\n");
- // Network specific RemoveSensor stuff goes here
-
- // parent
- SCA_EventManager::RemoveSensor(sensor);
-}
-
void KX_NetworkEventManager::NextFrame()
{
// printf("KX_NetworkEventManager::proceed %.2f - %.2f\n", curtime, deltatime);
// each frame, the logicmanager will call the network
// eventmanager to look for network events, and process it's
// 'network' sensors
- vector<class SCA_ISensor*>::iterator it;
+ set<class SCA_ISensor*>::iterator it;
for (it = m_sensors.begin(); !(it==m_sensors.end()); it++) {
// printf("KX_NetworkEventManager::proceed sensor %.2f\n", curtime);
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
index 0b097ba2ef6..ae88f1d4987 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
@@ -42,9 +42,6 @@ public:
class NG_NetworkDeviceInterface *ndi);
virtual ~KX_NetworkEventManager ();
- virtual void RegisterSensor(class SCA_ISensor* sensor);
- virtual void RemoveSensor(class SCA_ISensor* sensor);
-
virtual void NextFrame();
virtual void EndFrame();
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 3d9c7aafd70..ed712010c73 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -277,6 +277,7 @@ void KX_GameObject::ProcessReplica(KX_GameObject* replica)
replica->m_pSGNode = NULL;
replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
replica->m_pClient_info->m_gameobject = replica;
+ replica->m_state = 0;
}
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index 89699d80031..140dd37f5c6 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -98,6 +98,14 @@ void KX_NearSensor::RegisterSumo(KX_TouchEventManager *touchman)
}
}
+void KX_NearSensor::UnregisterSumo(KX_TouchEventManager* touchman)
+{
+ if (m_physCtrl)
+ {
+ touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl);
+ }
+}
+
CValue* KX_NearSensor::GetReplica()
{
KX_NearSensor* replica = new KX_NearSensor(*this);
diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h
index c6724caccc3..3f7078ef9fd 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.h
+++ b/source/gameengine/Ketsji/KX_NearSensor.h
@@ -77,6 +77,7 @@ public:
const PHY_CollData * coll_data);
virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2);
virtual void RegisterSumo(KX_TouchEventManager *touchman);
+ virtual void UnregisterSumo(KX_TouchEventManager* touchman);
virtual PyObject* _getattr(const STR_String& attr);
diff --git a/source/gameengine/Ketsji/KX_RayEventManager.cpp b/source/gameengine/Ketsji/KX_RayEventManager.cpp
index 4101c6b547e..1af29151adf 100644
--- a/source/gameengine/Ketsji/KX_RayEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_RayEventManager.cpp
@@ -44,14 +44,9 @@ using namespace std;
void KX_RayEventManager::NextFrame()
{
- for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
- SCA_ISensor *sensor = *i;
- sensor->Activate(m_logicmgr, NULL);
+ (*i)->Activate(m_logicmgr, NULL);
}
}
-void KX_RayEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-};
diff --git a/source/gameengine/Ketsji/KX_RayEventManager.h b/source/gameengine/Ketsji/KX_RayEventManager.h
index 3630f9682b9..b816d4d5250 100644
--- a/source/gameengine/Ketsji/KX_RayEventManager.h
+++ b/source/gameengine/Ketsji/KX_RayEventManager.h
@@ -45,7 +45,6 @@ public:
m_logicmgr(logicmgr)
{}
virtual void NextFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
};
#endif //__KX_RAYEVENTMGR
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index ad476e492d0..2828663c63d 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -93,6 +93,9 @@ void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
{
KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
+ if(replica)
+ replica->Release();
+
return (void*)replica;
}
@@ -670,8 +673,12 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
for (oit=m_groupGameObjects.begin(); oit != m_groupGameObjects.end(); oit++)
{
gameobj = (KX_GameObject*)(*oit);
- if (gameobj->GetParent() != NULL)
+
+ KX_GameObject *parent = gameobj->GetParent();
+ if (parent != NULL)
{
+ parent->Release(); // GetParent() increased the refcount
+
// this object is not a top parent. Either it is the child of another
// object in the group and it will be added automatically when the parent
// is added. Or it is the child of an object outside the group and the group
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 423543eef5c..7528fdbbc34 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -100,16 +100,24 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data,
void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
{
KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
- m_sensors.push_back(touchsensor);
+ m_sensors.insert(touchsensor);
touchsensor->RegisterSumo(this);
}
+void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
+{
+ KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
+ m_sensors.erase(touchsensor);
+
+ touchsensor->UnregisterSumo(this);
+}
+
void KX_TouchEventManager::EndFrame()
{
- vector<SCA_ISensor*>::iterator it;
+ set<SCA_ISensor*>::iterator it;
for ( it = m_sensors.begin();
!(it==m_sensors.end());it++)
{
@@ -124,7 +132,7 @@ void KX_TouchEventManager::NextFrame()
{
if (m_sensors.size() > 0)
{
- vector<SCA_ISensor*>::iterator it;
+ set<SCA_ISensor*>::iterator it;
for (it = m_sensors.begin();!(it==m_sensors.end());++it)
static_cast<KX_TouchSensor*>(*it)->SynchronizeTransform();
@@ -157,20 +165,3 @@ void KX_TouchEventManager::NextFrame()
(*it)->Activate(m_logicmgr,NULL);
}
}
-
-
-
-void KX_TouchEventManager::RemoveSensor(class SCA_ISensor* sensor)
-{
- std::vector<SCA_ISensor*>::iterator i =
- std::find(m_sensors.begin(), m_sensors.end(), sensor);
- if (!(i == m_sensors.end()))
- {
- std::swap(*i, m_sensors.back());
- m_sensors.pop_back();
- }
-
- // remove the sensor forever :)
- SCA_EventManager::RemoveSensor(sensor);
-}
-
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index 20ed6126bd0..cc77bccfc31 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -71,8 +71,8 @@ public:
PHY_IPhysicsEnvironment* physEnv);
virtual void NextFrame();
virtual void EndFrame();
- virtual void RemoveSensor(class SCA_ISensor* sensor);
virtual void RegisterSensor(SCA_ISensor* sensor);
+ virtual void RemoveSensor(SCA_ISensor* sensor);
SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
PHY_IPhysicsEnvironment *GetPhysicsEnvironment() { return m_physEnv; }
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index ce3aa1de2ef..60e1d87d318 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -153,6 +153,14 @@ void KX_TouchSensor::RegisterSumo(KX_TouchEventManager *touchman)
}
}
+void KX_TouchSensor::UnregisterSumo(KX_TouchEventManager* touchman)
+{
+ if (m_physCtrl)
+ {
+ touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl);
+ }
+}
+
bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_CollData* colldata)
{
// KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr;
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index 056440ccd6c..b611d296939 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -76,6 +76,7 @@ public:
virtual void ReParent(SCA_IObject* parent);
virtual void RegisterSumo(KX_TouchEventManager* touchman);
+ virtual void UnregisterSumo(KX_TouchEventManager* touchman);
// virtual DT_Bool HandleCollision(void* obj1,void* obj2,
// const DT_CollData * coll_data);
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index d4bd109de1a..f5b463abf02 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -195,6 +195,8 @@ void KX_TrackToActuator::ProcessReplica()
// the replica is tracking the same object => register it
if (m_object)
m_object->RegisterActuator(this);
+ if (m_parentobj)
+ m_parentobj->AddRef();
SCA_IActuator::ProcessReplica();
}
@@ -219,6 +221,14 @@ void KX_TrackToActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
m_object = (SCA_IObject*)(*h_obj);
m_object->RegisterActuator(this);
}
+
+ void **h_parobj = (*obj_map)[m_parentobj];
+ if (h_parobj) {
+ if (m_parentobj)
+ m_parentobj->Release();
+ m_parentobj= (KX_GameObject*)(*h_parobj);
+ m_parentobj->AddRef();
+ }
}
diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
index ec1b7702ffd..7c61902f8e2 100644
--- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
+++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
@@ -65,6 +65,7 @@ public:
{
}
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl) {}
+ virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl) {}
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;}
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index b773f40650b..ea14c5430e2 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -368,7 +368,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
body->setUserPointer(ctrl);
body->setGravity( m_gravity );
- m_controllers.push_back(ctrl);
+ m_controllers.insert(ctrl);
//use explicit group/filter for finer control over collision in bullet => near/radar sensor
m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
@@ -434,36 +434,13 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
{
-
//also remove constraint
-
-
m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
-
-
- {
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_controllers.begin(), m_controllers.end(), ctrl);
- if (!(i == m_controllers.end()))
- {
- std::swap(*i, m_controllers.back());
- m_controllers.pop_back();
- }
- }
+ m_controllers.erase(ctrl);
//remove it from the triggers
- {
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
- if (!(i == m_triggerControllers.end()))
- {
- std::swap(*i, m_triggerControllers.back());
- m_triggerControllers.pop_back();
- }
- }
-
-
+ m_triggerControllers.erase(ctrl);
}
void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
@@ -487,11 +464,10 @@ void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctr
void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctrl)
{
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_controllers.begin(), m_controllers.end(), ctrl);
- if (i == m_controllers.end())
+ if (m_controllers.insert(ctrl).second)
{
btRigidBody* body = ctrl->GetRigidBody();
+ body->setUserPointer(ctrl);
m_dynamicsWorld->addCollisionObject(body,
ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
}
@@ -507,12 +483,12 @@ void CcdPhysicsEnvironment::beginFrame()
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{
+ std::set<CcdPhysicsController*>::iterator it;
+ int i;
- int i,numCtrl = GetNumControllers();
- for (i=0;i<numCtrl;i++)
+ for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
- CcdPhysicsController* ctrl = GetPhysicsController(i);
- ctrl->SynchronizeMotionStates(timeStep);
+ (*it)->SynchronizeMotionStates(timeStep);
}
float subStep = timeStep / float(m_numTimeSubSteps);
@@ -521,11 +497,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
m_dynamicsWorld->stepSimulation(subStep,0);//perform always a full simulation step
}
- numCtrl = GetNumControllers();
- for (i=0;i<numCtrl;i++)
+ for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
- CcdPhysicsController* ctrl = GetPhysicsController(i);
- ctrl->SynchronizeMotionStates(timeStep);
+ (*it)->SynchronizeMotionStates(timeStep);
}
for (i=0;i<m_wrapperVehicles.size();i++)
@@ -852,20 +826,6 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
}
-int CcdPhysicsEnvironment::GetNumControllers()
-{
- return m_controllers.size();
-}
-
-
-CcdPhysicsController* CcdPhysicsEnvironment::GetPhysicsController( int index)
-{
- return m_controllers[index];
-}
-
-
-
-
void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float value0,float value1)
{
btTypedConstraint* typedConstraint = getConstraintById(constraintId);
@@ -905,12 +865,14 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
{
CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_controllers.begin(), m_controllers.end(), ctrl);
- if ((i == m_controllers.end()))
- {
- addCcdPhysicsController(ctrl1);
- }
+ // addSensor() is a "light" function for bullet because it is used
+ // dynamically when the sensor is activated. Use enableCcdPhysicsController() instead
+ //if (m_controllers.insert(ctrl1).second)
+ //{
+ // addCcdPhysicsController(ctrl1);
+ //}
+ enableCcdPhysicsController(ctrl1);
+
//Collision filter/mask is now set at the time of the creation of the controller
//force collision detection with everything, including static objects (might hurt performance!)
//ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::SensorTrigger;
@@ -923,21 +885,15 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
{
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
- if (!(i == m_triggerControllers.end()))
- {
- std::swap(*i, m_triggerControllers.back());
- m_triggerControllers.pop_back();
- }
+ m_triggerControllers.erase((CcdPhysicsController*)ctrl);
}
void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
{
- removeCollisionCallback(ctrl);
- //printf("removeSensor\n");
+ removeCcdPhysicsController((CcdPhysicsController*)ctrl);
}
+
void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
{
/* printf("addTouchCallback\n(response class = %i)\n",response_class);
@@ -975,10 +931,9 @@ void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctr
CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);
//printf("requestCollisionCallback\n");
- m_triggerControllers.push_back(ccdCtrl);
+ m_triggerControllers.insert(ccdCtrl);
}
-
void CcdPhysicsEnvironment::CallbackTriggers()
{
@@ -1011,11 +966,10 @@ void CcdPhysicsEnvironment::CallbackTriggers()
CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer());
CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer());
- std::vector<CcdPhysicsController*>::iterator i =
- std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl0);
+ std::set<CcdPhysicsController*>::const_iterator i = m_triggerControllers.find(ctrl0);
if (i == m_triggerControllers.end())
{
- i = std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl1);
+ i = m_triggerControllers.find(ctrl1);
}
if (!(i == m_triggerControllers.end()))
@@ -1125,7 +1079,6 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radi
CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
-
return sphereController;
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 453749b27b3..fd96522037e 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -18,6 +18,7 @@ subject to the following restrictions:
#include "PHY_IPhysicsEnvironment.h"
#include <vector>
+#include <set>
class CcdPhysicsController;
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
@@ -209,12 +210,6 @@ protected:
}
- int GetNumControllers();
-
- CcdPhysicsController* GetPhysicsController( int index);
-
-
-
const btPersistentManifold* GetManifold(int index) const;
@@ -229,9 +224,9 @@ protected:
- std::vector<CcdPhysicsController*> m_controllers;
+ std::set<CcdPhysicsController*> m_controllers;
- std::vector<CcdPhysicsController*> m_triggerControllers;
+ std::set<CcdPhysicsController*> m_triggerControllers;
PHY_ResponseCallback m_triggerCallbacks[PHY_NUM_RESPONSE];
void* m_triggerCallbacksUserPtrs[PHY_NUM_RESPONSE];
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
index f0761618e4e..b5a61f72e4a 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
@@ -80,6 +80,7 @@ public:
{
}
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl) {}
+ virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl) {}
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;}
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;}
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
index b5bf67b14ea..f0791bbf89f 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
@@ -98,12 +98,17 @@ void SM_Scene::addTouchCallback(int response_class, DT_ResponseCallback callback
void SM_Scene::addSensor(SM_Object& object)
{
- object.calcXform();
- m_objectList.push_back(&object);
- DT_AddObject(m_scene, object.getObjectHandle());
- DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[SENSOR_RESPONSE]);
- DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[SENSOR_RESPONSE]);
- DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[SENSOR_RESPONSE]);
+ T_ObjectList::iterator i =
+ std::find(m_objectList.begin(), m_objectList.end(), &object);
+ if (i == m_objectList.end())
+ {
+ object.calcXform();
+ m_objectList.push_back(&object);
+ DT_AddObject(m_scene, object.getObjectHandle());
+ DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[SENSOR_RESPONSE]);
+ DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass [SENSOR_RESPONSE]);
+ DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[SENSOR_RESPONSE]);
+ }
}
void SM_Scene::add(SM_Object& object) {
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
index 16ba45a0be5..65018d2523e 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
@@ -228,6 +228,12 @@ void SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ct
m_sumoScene->requestCollisionCallback(*smObject);
}
}
+
+void SumoPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
+{
+ // intentionally empty
+}
+
PHY_IPhysicsController* SumoPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
{
DT_ShapeHandle shape = DT_NewSphere(0.0);
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
index ce5cd70e8cc..8b9fb463034 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
@@ -84,6 +84,7 @@ public:
virtual void removeSensor(PHY_IPhysicsController* ctrl);
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user);
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl);
+ virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl);
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position);
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight);
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index c148210903f..5b275066665 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -104,6 +104,7 @@ class PHY_IPhysicsEnvironment
virtual void removeSensor(PHY_IPhysicsController* ctrl)=0;
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0;
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl)=0;
+ virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl)=0;
//These two methods are *solely* used to create controllers for sensor! Don't use for anything else
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0;
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0;
diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h
index 0327a3f4763..e3af43fb839 100644
--- a/source/gameengine/Rasterizer/RAS_CameraData.h
+++ b/source/gameengine/Rasterizer/RAS_CameraData.h
@@ -42,7 +42,7 @@ struct RAS_CameraData
int m_viewporttop;
float m_focallength;
- RAS_CameraData(float lens = 35., float clipstart = 0.1, float clipend = 100., bool perspective = true,
+ RAS_CameraData(float lens = 35.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true,
float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0,
int viewportright = 0, int viewporttop = 0) :
m_lens(lens),
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 9c0460aad2d..af5228e4c35 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -35,6 +35,8 @@
#include "MT_MinMax.h"
#include "MT_Point3.h"
+#include <algorithm>
+
STR_String RAS_MeshObject::s_emptyname = "";
@@ -674,7 +676,7 @@ void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
slots[j].get(vertexarray, indexarray, j*nvert, nvert, pnorm);
/* sort (stable_sort might be better, if flickering happens?) */
- sort(slots.begin(), slots.end(), backtofront());
+ std::sort(slots.begin(), slots.end(), backtofront());
/* get indices from temporary array again */
for(j=0; j<totpoly; j++)