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
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-14 20:32:24 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-14 20:32:24 +0300
commitec00764dd2349f723ba22b45515ec34ee81edcc3 (patch)
treecf506e71af7172ec63b89aa3d284fab27a2085e6 /source
parent131fa2e00c35ff78042a4f793891eaeb880d715c (diff)
parent8449f0d77640c466acbda7d6ceeb71bc48317b44 (diff)
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17434:HEAD
Diffstat (limited to 'source')
-rw-r--r--source/Makefile15
-rw-r--r--source/blender/blenkernel/BKE_brush.h1
-rw-r--r--source/blender/blenkernel/BKE_customdata.h8
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/intern/brush.c17
-rw-r--r--source/blender/blenkernel/intern/curve.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c90
-rw-r--r--source/blender/blenkernel/intern/displist.c3
-rw-r--r--source/blender/blenkernel/intern/node.c2
-rw-r--r--source/blender/blenlib/BLI_linklist.h1
-rw-r--r--source/blender/blenlib/BLI_memarena.h1
-rw-r--r--source/blender/blenlib/SConscript2
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c12
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c4
-rw-r--r--source/blender/blenlib/intern/arithb.c4
-rw-r--r--source/blender/blenlib/intern/storage.c10
-rw-r--r--source/blender/blenlib/intern/threads.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c10
-rw-r--r--source/blender/imbuf/IMB_imbuf.h7
-rw-r--r--source/blender/imbuf/intern/imageprocess.c193
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h13
-rw-r--r--source/blender/makesdna/DNA_scriptlink_types.h8
-rw-r--r--source/blender/makesdna/intern/SConscript19
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/TEX_node.h2
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_coord.c66
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_distance.c79
-rw-r--r--source/blender/nodes/intern/TEX_util.c31
-rw-r--r--source/creator/creator.c9
-rw-r--r--source/gameengine/BlenderRoutines/Makefile1
-rw-r--r--source/gameengine/GamePlayer/common/unix/Makefile1
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h1
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp75
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp64
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h4
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h4
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp2
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py48
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp136
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.h5
-rw-r--r--source/gameengine/Rasterizer/RAS_FramingManager.h5
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp8
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h1
-rw-r--r--source/gameengine/VideoTexture/Exception.cpp6
-rw-r--r--source/gameengine/VideoTexture/Exception.h6
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp595
-rw-r--r--source/gameengine/VideoTexture/ImageRender.h48
-rw-r--r--source/gameengine/VideoTexture/ImageViewport.cpp66
-rw-r--r--source/gameengine/VideoTexture/ImageViewport.h14
-rw-r--r--source/gameengine/VideoTexture/Texture.h6
-rw-r--r--source/gameengine/VideoTexture/blendVideoTex.cpp4
-rw-r--r--source/nan_compile.mk36
-rw-r--r--source/nan_definitions.mk57
-rw-r--r--source/nan_link.mk20
57 files changed, 1519 insertions, 317 deletions
diff --git a/source/Makefile b/source/Makefile
index 12f2516a982..fe48b26c14c 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -194,7 +194,7 @@ ifeq ($(WITH_FREETYPE2), true)
else
COMLIB += $(NAN_FTGL)/lib/libftgl.a
ifeq ($(OS), irix)
- COMLIB += $(NAN_FREETYPE)/lib32/libfreetype.a
+ COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
else
COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
endif
@@ -417,9 +417,16 @@ else
NAN_SND_LIBS += $(ALUT)
NAN_SND_LIBS += $(SOUNDSYSTEM)
else
- NAN_SND_LIBS = $(SOUNDSYSTEM)
- NAN_SND_LIBS += $(DUMMYSOUND)
- NAN_SND_LIBS += $(SOUNDSYSTEM)
+ ifeq ($(OS), irix)
+ NAN_SND_LIBS = $(SOUNDSYSTEM)
+ NAN_SND_LIBS += $(DUMMYSOUND)
+ NAN_SND_LIBS += $(SDLSOUND)
+ NAN_SND_LIBS += $(SOUNDSYSTEM)
+ else
+ NAN_SND_LIBS = $(SOUNDSYSTEM)
+ NAN_SND_LIBS += $(DUMMYSOUND)
+ NAN_SND_LIBS += $(SOUNDSYSTEM)
+ endif
endif
endif
endif
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index f1f4653f092..398d203709f 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -53,6 +53,7 @@ int brush_clone_image_delete(struct Brush *brush);
/* sampling */
float brush_sample_falloff(struct Brush *brush, float dist);
+float brush_sample_falloff_noalpha(struct Brush *brush, float dist);
void brush_sample_tex(struct Brush *brush, float *xy, float *rgba);
void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size,
struct ImBuf **imbuf);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index c84b690bc49..10791968f79 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -198,8 +198,12 @@ int CustomData_get_layer_index(const struct CustomData *data, int type);
int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name);
int CustomData_get_active_layer_index(const struct CustomData *data, int type);
int CustomData_get_render_layer_index(const struct CustomData *data, int type);
+int CustomData_get_clone_layer_index(const struct CustomData *data, int type);
+int CustomData_get_mask_layer_index(const struct CustomData *data, int type);
int CustomData_get_active_layer(const struct CustomData *data, int type);
int CustomData_get_render_layer(const struct CustomData *data, int type);
+int CustomData_get_clone_layer(const struct CustomData *data, int type);
+int CustomData_get_mask_layer(const struct CustomData *data, int type);
/* copies the data from source to the data element at index in the first
* layer of type
@@ -227,10 +231,14 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi
/* sets the nth layer of type as active */
void CustomData_set_layer_active(struct CustomData *data, int type, int n);
void CustomData_set_layer_render(struct CustomData *data, int type, int n);
+void CustomData_set_layer_clone(struct CustomData *data, int type, int n);
+void CustomData_set_layer_mask(struct CustomData *data, int type, int n);
/* same as above but works with an index from CustomData_get_layer_index */
void CustomData_set_layer_active_index(struct CustomData *data, int type, int n);
void CustomData_set_layer_render_index(struct CustomData *data, int type, int n);
+void CustomData_set_layer_clone_index(struct CustomData *data, int type, int n);
+void CustomData_set_layer_mask_index(struct CustomData *data, int type, int n);
/* adds flag to the layer flags */
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index fa3a654c1c2..1c5b6b124b2 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -401,6 +401,8 @@ struct TexResult;
#define TEX_NODE_ROTATE 114
#define TEX_NODE_VIEWER 115
#define TEX_NODE_TRANSLATE 116
+#define TEX_NODE_COORD 117
+#define TEX_NODE_DISTANCE 118
/* 201-299 reserved. Use like this: TEX_NODE_PROC + TEX_CLOUDS, etc */
#define TEX_NODE_PROC 200
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 1c53af97dbb..021f76fd2f1 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -328,6 +328,23 @@ float brush_sample_falloff(Brush *brush, float dist)
return 0.0f;
}
+float brush_sample_falloff_noalpha(Brush *brush, float dist)
+{
+ float outer, inner;
+
+ outer = brush->size >> 1;
+ inner = outer*brush->innerradius;
+
+ if (dist <= inner) {
+ return 1.0f;
+ }
+ else if ((dist < outer) && (inner < outer)) {
+ return 1.0f - sqrt((dist - inner)/(outer - inner));
+ }
+ else
+ return 0.0f;
+}
+
void brush_sample_tex(Brush *brush, float *xy, float *rgba)
{
MTex *mtex= brush->mtex[brush->texact];
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 1a671dfe771..7fa4f406c7b 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -833,7 +833,6 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
sum= (float *)MEM_callocN(sizeof(float)*len, "makeNurbcurve1");
resolu= (resolu*SEGMENTSU(nu));
- if((nu->flagu & CU_CYCLIC)==0) resolu++;
if(resolu==0) {
MEM_freeN(sum);
@@ -1685,7 +1684,6 @@ void makeBevelList(Object *ob)
else if((nu->type & 7)==CU_NURBS) {
if(nu->pntsv==1) {
len= (resolu*SEGMENTSU(nu));
- if((nu->flagu & CU_CYCLIC)==0) len++;
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList3");
BLI_addtail(&(cu->bev), bl);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index e93266c85f3..05271aa59a7 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -606,7 +606,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
{
const LayerTypeInfo *typeInfo;
CustomDataLayer *layer, *newlayer;
- int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0;
+ int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
for(i = 0; i < source->totlayer; ++i) {
layer = &source->layers[i];
@@ -618,6 +618,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
number = 0;
lastactive = layer->active;
lastrender = layer->active_rnd;
+ lastclone = layer->active_clone;
+ lastmask = layer->active_mask;
lasttype = type;
}
else
@@ -637,6 +639,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
if(newlayer) {
newlayer->active = lastactive;
newlayer->active_rnd = lastrender;
+ newlayer->active_clone = lastclone;
+ newlayer->active_mask = lastmask;
}
}
}
@@ -736,6 +740,28 @@ int CustomData_get_render_layer_index(const CustomData *data, int type)
return -1;
}
+int CustomData_get_clone_layer_index(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return i + data->layers[i].active_clone;
+
+ return -1;
+}
+
+int CustomData_get_mask_layer_index(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return i + data->layers[i].active_mask;
+
+ return -1;
+}
+
int CustomData_get_active_layer(const CustomData *data, int type)
{
int i;
@@ -758,6 +784,27 @@ int CustomData_get_render_layer(const CustomData *data, int type)
return -1;
}
+int CustomData_get_clone_layer(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return data->layers[i].active_clone;
+
+ return -1;
+}
+
+int CustomData_get_mask_layer(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return data->layers[i].active_mask;
+
+ return -1;
+}
void CustomData_set_layer_active(CustomData *data, int type, int n)
{
@@ -777,6 +824,24 @@ void CustomData_set_layer_render(CustomData *data, int type, int n)
data->layers[i].active_rnd = n;
}
+void CustomData_set_layer_clone(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_clone = n;
+}
+
+void CustomData_set_layer_mask(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_mask = n;
+}
+
/* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */
void CustomData_set_layer_active_index(CustomData *data, int type, int n)
{
@@ -796,6 +861,23 @@ void CustomData_set_layer_render_index(CustomData *data, int type, int n)
data->layers[i].active_rnd = n-i;
}
+void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_clone = n-i;
+}
+
+void CustomData_set_layer_mask_index(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_mask = n-i;
+}
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
{
@@ -882,9 +964,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
if(index > 0 && data->layers[index-1].type == type) {
data->layers[index].active = data->layers[index-1].active;
data->layers[index].active_rnd = data->layers[index-1].active_rnd;
+ data->layers[index].active_clone = data->layers[index-1].active_clone;
+ data->layers[index].active_mask = data->layers[index-1].active_mask;
} else {
data->layers[index].active = 0;
data->layers[index].active_rnd = 0;
+ data->layers[index].active_clone = 0;
+ data->layers[index].active_mask = 0;
}
customData_update_offsets(data);
@@ -944,6 +1030,8 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
for (; i < data->totlayer && data->layers[i].type == type; i++) {
data->layers[i].active--;
data->layers[i].active_rnd--;
+ data->layers[i].active_clone--;
+ data->layers[i].active_mask--;
}
}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 44aa439ee3e..84025204ee4 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -890,7 +890,6 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
}
else if((nu->type & 7)==CU_NURBS) {
len= (resolu*SEGMENTSU(nu));
- if((nu->flagu & CU_CYCLIC)==0) len++;
dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
@@ -1384,7 +1383,7 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender)
for (nu=nubase->first; nu; nu=nu->next) {
if(forRender || nu->hide==0) {
if(nu->pntsv==1) {
- len= nu->pntsu*nu->resolu;
+ len= SEGMENTSU(nu)*nu->resolu;
dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index e189891d884..0e43ecd61e1 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2886,6 +2886,8 @@ static void registerTextureNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &tex_node_curve_time);
nodeRegisterType(ntypelist, &tex_node_invert);
nodeRegisterType(ntypelist, &tex_node_hue_sat);
+ nodeRegisterType(ntypelist, &tex_node_coord);
+ nodeRegisterType(ntypelist, &tex_node_distance);
nodeRegisterType(ntypelist, &tex_node_output);
nodeRegisterType(ntypelist, &tex_node_viewer);
diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h
index e840ffd167a..ed202c11429 100644
--- a/source/blender/blenlib/BLI_linklist.h
+++ b/source/blender/blenlib/BLI_linklist.h
@@ -45,6 +45,7 @@ typedef struct LinkNode {
} LinkNode;
int BLI_linklist_length (struct LinkNode *list);
+int BLI_linklist_index (struct LinkNode *list, void *ptr);
void BLI_linklist_reverse (struct LinkNode **listp);
diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h
index 34d732e1862..a2954f8fa0d 100644
--- a/source/blender/blenlib/BLI_memarena.h
+++ b/source/blender/blenlib/BLI_memarena.h
@@ -50,6 +50,7 @@ typedef struct MemArena MemArena;
struct MemArena* BLI_memarena_new (int bufsize);
void BLI_memarena_free (struct MemArena *ma);
+void BLI_memarena_use_malloc (struct MemArena *ma);
void BLI_memarena_use_calloc (struct MemArena *ma);
void* BLI_memarena_alloc (struct MemArena *ma, int size);
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index 01a9a1eab0e..f664b75af5a 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -23,7 +23,7 @@ if env['OURPLATFORM'] == 'linux2':
cflags='-pthread'
incs += ' ../../../extern/binreloc/include'
-if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'):
incs += ' ' + env['BF_PTHREADS_INC']
env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core', 'intern', 'player'], priority = [85,150,195], compileflags =cflags )
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index 506a1036ed6..962bbeea373 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -50,6 +50,18 @@ int BLI_linklist_length(LinkNode *list) {
}
}
+int BLI_linklist_index(struct LinkNode *list, void *ptr)
+{
+ int index;
+
+ for (index = 0; list; list= list->next, index++) {
+ if (list->link == ptr)
+ return index;
+ }
+
+ return -1;
+}
+
void BLI_linklist_reverse(LinkNode **listp) {
LinkNode *rhead= NULL, *cur= *listp;
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index 69dd13cd335..87d2f0426b2 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -60,6 +60,10 @@ void BLI_memarena_use_calloc(MemArena *ma) {
ma->use_calloc= 1;
}
+void BLI_memarena_use_malloc(MemArena *ma) {
+ ma->use_calloc= 0;
+}
+
void BLI_memarena_free(MemArena *ma) {
BLI_linklist_free(ma->bufs, (void(*)(void*)) MEM_freeN);
MEM_freeN(ma);
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 0f2226fc872..a47d37eb69a 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -1351,8 +1351,8 @@ void Mat4ToQuat( float m[][4], float *q)
void QuatOne(float *q)
{
- q[0]= q[2]= q[3]= 0.0;
- q[1]= 1.0;
+ q[0]= 1.0;
+ q[1]= q[2]= q[3]= 0.0;
}
void NormalQuat(float *q)
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index ca7a376d3a2..8ba03ad1343 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -47,9 +47,9 @@
#include <time.h>
#include <sys/stat.h>
-#if defined (__sun__) || defined (__sun)
+#if defined (__sun__) || defined (__sun) || defined (__sgi)
#include <sys/statvfs.h> /* Other modern unix os's should probably use this also */
-#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sgi) || defined(__sparc) || defined(__sparc__))
+#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__))
#include <sys/statfs.h>
#endif
@@ -179,7 +179,7 @@ double BLI_diskfree(char *dir)
return (double) (freec*bytesps*sectorspc);
#else
-#if defined (__sun__) || defined (__sun)
+#if defined (__sun__) || defined (__sun) || defined (__sgi)
struct statvfs disk;
#else
struct statfs disk;
@@ -204,9 +204,9 @@ double BLI_diskfree(char *dir)
return -1;
#endif
-#if defined (__sun__) || defined (__sun)
+#if defined (__sun__) || defined (__sun) || defined (__sgi)
if (statvfs(name, &disk)) return(-1);
-#elif !defined(__FreeBSD__) && !defined(linux) && (defined (__sgi) || defined(__sparc) || defined(__sparc__))
+#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__))
/* WARNING - This may not be supported by geeneric unix os's - Campbell */
if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1);
#endif
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 9df8bbc81e3..07c02b8024f 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -42,7 +42,7 @@
/* for checking system threads - BLI_system_thread_count */
#ifdef WIN32
-#include "Windows.h"
+#include "windows.h"
#elif defined(__APPLE__)
#include <sys/types.h>
#include <sys/sysctl.h>
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index fa44f00c607..df2c680c951 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8259,6 +8259,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) {
+ Scene *sce;
+
+ /* Note, these will need to be added for painting */
+ for (sce= main->scene.first; sce; sce= sce->id.next) {
+ sce->toolsettings->imapaint.seam_bleed = 2;
+ sce->toolsettings->imapaint.normal_angle = 80;
+ }
+ }
+
if (main->versionfile < 250) {
bScreen *screen;
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index d4d8030bf10..8bc1439fd09 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -403,9 +403,14 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf);
*
* @attention defined in imageprocess.c
*/
-void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float x, float y, int xout, int yout);
+void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+
+void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
+
/**
* Change the ordering of the color bytes pointed to by rect from
* rgba to abgr. size * 4 color bytes are reordered.
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index d7f1ab4419d..fe7e26eac2b 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -80,6 +80,17 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
}
}
}
+static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y)
+
+{
+ int offset = ibuf->x * y * 4 + 4*x;
+
+ if (ibuf->rect)
+ *outI= (unsigned char *)ibuf->rect + offset;
+
+ if (ibuf->rect_float)
+ *outF= (float *)ibuf->rect_float + offset;
+}
/**************************************************************************
* INTERPOLATIONS
@@ -92,32 +103,40 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
/* More info: http://wiki.blender.org/index.php/User:Damiles#Bicubic_pixel_interpolation
*/
/* function assumes out to be zero'ed, only does RGBA */
+
+static float P(float k){
+ float p1, p2, p3, p4;
+ p1 = MAX2(k+2.0f,0);
+ p2 = MAX2(k+1.0f,0);
+ p3 = MAX2(k,0);
+ p4 = MAX2(k-1.0f,0);
+ return (float)(1.0f/6.0f)*( p1*p1*p1 - 4.0f * p2*p2*p2 + 6.0f * p3*p3*p3 - 4.0f * p4*p4*p4);
+}
+
+
+#if 0
+/* older, slower function, works the same as above */
static float P(float k){
return (float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( MAX2(k-1.0f,0) , 3.0f));
}
+#endif
-void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
+void bicubic_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
{
int i,j,n,m,x1,y1;
- unsigned char *dataI,*outI;
- float a,b,w,wx,wy[4], outR,outG,outB,outA,*dataF,*outF;
- int do_rect, do_float;
-
- if (in == NULL) return;
- if (in->rect == NULL && in->rect_float == NULL) return;
+ unsigned char *dataI;
+ float a,b,w,wx,wy[4], outR,outG,outB,outA,*dataF;
- do_rect= (out->rect != NULL);
- do_float= (out->rect_float != NULL);
+ /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
- i= (int)floor(x);
- j= (int)floor(y);
- a= x - i;
- b= y - j;
+ i= (int)floor(u);
+ j= (int)floor(v);
+ a= u - i;
+ b= v - j;
- outR= 0.0f;
- outG= 0.0f;
- outB= 0.0f;
- outA= 0.0f;
+ outR = outG = outB = outA = 0.0f;
+
+/* Optimized and not so easy to read */
/* avoid calling multiple times */
wy[0] = P(b-(-1));
@@ -137,14 +156,14 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in
/* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */
w = wx * wy[m+1];
- if (do_float) {
+ if (outF) {
dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
outR+= dataF[0] * w;
outG+= dataF[1] * w;
outB+= dataF[2] * w;
outA+= dataF[3] * w;
}
- if (do_rect) {
+ if (outI) {
dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1;
outR+= dataI[0] * w;
outG+= dataI[1] * w;
@@ -155,15 +174,42 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in
}
}
}
- if (do_rect) {
- outI= (unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
+
+/* Done with optimized part */
+
+#if 0
+ /* older, slower function, works the same as above */
+ for(n= -1; n<= 2; n++){
+ for(m= -1; m<= 2; m++){
+ x1= i+n;
+ y1= j+m;
+ if (x1>0 && x1 < in->x && y1>0 && y1<in->y) {
+ if (do_float) {
+ dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
+ outR+= dataF[0] * P(n-a) * P(b-m);
+ outG+= dataF[1] * P(n-a) * P(b-m);
+ outB+= dataF[2] * P(n-a) * P(b-m);
+ outA+= dataF[3] * P(n-a) * P(b-m);
+ }
+ if (do_rect) {
+ dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1;
+ outR+= dataI[0] * P(n-a) * P(b-m);
+ outG+= dataI[1] * P(n-a) * P(b-m);
+ outB+= dataI[2] * P(n-a) * P(b-m);
+ outA+= dataI[3] * P(n-a) * P(b-m);
+ }
+ }
+ }
+ }
+#endif
+
+ if (outI) {
outI[0]= (int)outR;
outI[1]= (int)outG;
outI[2]= (int)outB;
outI[3]= (int)outA;
}
- if (do_float) {
- outF= (float *)out->rect_float + out->x * yout * 4 + 4*xout;
+ if (outF) {
outF[0]= outR;
outF[1]= outG;
outF[2]= outB;
@@ -171,23 +217,33 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in
}
}
+
+void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
+{
+
+ unsigned char *outI = NULL;
+ float *outF = NULL;
+
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return;
+
+ pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+
+ bicubic_interpolation_color(in, outI, outF, u, v);
+}
+
/* function assumes out to be zero'ed, only does RGBA */
/* BILINEAR INTERPOLATION */
-void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
+void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
{
- float *row1, *row2, *row3, *row4, a, b, *outF;
- unsigned char *row1I, *row2I, *row3I, *row4I, *outI;
+ float *row1, *row2, *row3, *row4, a, b;
+ unsigned char *row1I, *row2I, *row3I, *row4I;
float a_b, ma_b, a_mb, ma_mb;
float empty[4]= {0.0f, 0.0f, 0.0f, 0.0f};
unsigned char emptyI[4]= {0, 0, 0, 0};
int y1, y2, x1, x2;
- int do_rect, do_float;
-
- if (in==NULL) return;
- if (in->rect==NULL && in->rect_float==NULL) return;
-
- do_rect= (out->rect != NULL);
- do_float= (out->rect_float != NULL);
+
+
+ /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
x1= (int)floor(u);
x2= (int)ceil(u);
@@ -197,16 +253,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
// sample area entirely outside image?
if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return;
- if (do_rect)
- outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
- else
- outI= NULL;
- if (do_float)
- outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout;
- else
- outF= NULL;
-
- if (do_float) {
+ if (outF) {
// sample including outside of edges of image
if (x1<0 || y1<0) row1= empty;
else row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1;
@@ -229,7 +276,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2];
outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3];
}
- if (do_rect) {
+ if (outI) {
// sample including outside of edges of image
if (x1<0 || y1<0) row1I= emptyI;
else row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
@@ -254,45 +301,44 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i
}
}
+void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
+{
+
+ unsigned char *outI = NULL;
+ float *outF = NULL;
+
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return;
+
+ pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+
+ bilinear_interpolation_color(in, outI, outF, u, v);
+}
+
/* function assumes out to be zero'ed, only does RGBA */
/* NEAREST INTERPOLATION */
-void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, int yout)
+void neareast_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v)
{
- float *outF,*dataF;
- unsigned char *dataI,*outI;
+ float *dataF;
+ unsigned char *dataI;
int y1, x1;
- int do_rect, do_float;
-
- if (in==NULL) return;
- if (in->rect==NULL && in->rect_float==NULL) return;
-
- do_rect= (out->rect != NULL);
- do_float= (out->rect_float != NULL);
+ /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */
+
x1= (int)(u);
y1= (int)(v);
- if (do_rect)
- outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
- else
- outI= NULL;
- if (do_float)
- outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout;
- else
- outF= NULL;
-
// sample area entirely outside image?
if (x1<0 || x1>in->x-1 || y1<0 || y1>in->y-1) return;
// sample including outside of edges of image
if (x1<0 || y1<0) {
- if (do_rect) {
+ if (outI) {
outI[0]= 0;
outI[1]= 0;
outI[2]= 0;
outI[3]= 0;
}
- if (do_float) {
+ if (outF) {
outF[0]= 0.0f;
outF[1]= 0.0f;
outF[2]= 0.0f;
@@ -300,14 +346,14 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, in
}
} else {
dataI= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
- if (do_rect) {
+ if (outI) {
outI[0]= dataI[0];
outI[1]= dataI[1];
outI[2]= dataI[2];
outI[3]= dataI[3];
}
dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
- if (do_float) {
+ if (outF) {
outF[0]= dataF[0];
outF[1]= dataF[1];
outF[2]= dataF[2];
@@ -315,3 +361,16 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, in
}
}
}
+
+void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
+{
+
+ unsigned char *outI = NULL;
+ float *outF = NULL;
+
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return;
+
+ pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+
+ neareast_interpolation_color(in, outI, outF, x, y);
+}
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 6c098e220bb..e6b18641d2a 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -37,6 +37,8 @@ typedef struct CustomDataLayer {
int flag; /* general purpose flag */
int active; /* number of the active layer of this type */
int active_rnd; /* number of the layer to render*/
+ int active_clone; /* number of the layer to render*/
+ int active_mask; /* number of the layer to render*/
char pad[4];
char name[32]; /* layer name */
void *data; /* layer data */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 5397d890789..859b3abd7e2 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -344,7 +344,9 @@ typedef struct TimeMarker {
typedef struct ImagePaintSettings {
struct Brush *brush;
short flag, tool;
- int pad3;
+
+ /* for projection painting only */
+ short seam_bleed,normal_angle;
} ImagePaintSettings;
typedef struct ParticleBrushData {
@@ -826,6 +828,15 @@ typedef struct Scene {
#define IMAGEPAINT_DRAW_TOOL 2
#define IMAGEPAINT_DRAW_TOOL_DRAWING 4
+/* projection painting only */
+#define IMAGEPAINT_PROJECT_DISABLE 8 /* Non projection 3D painting */
+#define IMAGEPAINT_PROJECT_XRAY 16
+#define IMAGEPAINT_PROJECT_BACKFACE 32
+#define IMAGEPAINT_PROJECT_FLAT 64
+#define IMAGEPAINT_PROJECT_LAYER_CLONE 128
+#define IMAGEPAINT_PROJECT_LAYER_MASK 256
+#define IMAGEPAINT_PROJECT_LAYER_MASK_INV 512
+
/* toolsettings->uvcalc_flag */
#define UVCALC_FILLHOLES 1
#define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
diff --git a/source/blender/makesdna/DNA_scriptlink_types.h b/source/blender/makesdna/DNA_scriptlink_types.h
index 95e20dd004d..9b50eb91a20 100644
--- a/source/blender/makesdna/DNA_scriptlink_types.h
+++ b/source/blender/makesdna/DNA_scriptlink_types.h
@@ -65,10 +65,12 @@ typedef struct ScriptLink {
/* these are special scriptlinks that can be assigned to
* a given space in a given ScrArea to:
* - (EVENT type) handle events sent to that space;
- * - (DRAW type) draw on the space after its own drawing function finishes
+ * - (EVENT_ALL type): handle release events, too;
+ * - (DRAW type) draw on the space after its own drawing function finishes.
*/
-#define SPACEHANDLER_VIEW3D_EVENT 1
-#define SPACEHANDLER_VIEW3D_DRAW 2
+#define SPACEHANDLER_VIEW3D_DRAW 1
+#define SPACEHANDLER_VIEW3D_EVENT 2
+#define SPACEHANDLER_VIEW3D_EVENT_ALL 3
#ifdef __cplusplus
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index b7d55a0ca1a..4aa8d6a9d54 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -18,9 +18,15 @@ makesdna_tool.Append (CPPPATH = ['#/intern/guardedalloc',
'../../makesdna'])
if env['OURPLATFORM'] == 'linuxcross':
- makesdna_tool.Replace(CC='gcc')
- makesdna_tool.Replace(AR='ar')
- makesdna_tool.Replace(LINK='gcc')
+ USE_WINE = True # when cross compiling on linux 64bit this is useful
+else:
+ USE_WINE = False
+
+if not USE_WINE:
+ if env['OURPLATFORM'] == 'linuxcross':
+ makesdna_tool.Replace(CC='gcc')
+ makesdna_tool.Replace(AR='ar')
+ makesdna_tool.Replace(LINK='gcc')
if sys.platform != 'cygwin':
makesdna_tool.Append (CCFLAGS = cflags)
@@ -30,7 +36,7 @@ if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
targetdir = '#'+targetdir
makesdna_tool.Append (LIBPATH = targetdir)
if env['BF_PROFILE']:
- makesdna_tool.Append (LINKFLAGS = env['BF_PROFILE_FLAGS'])
+ makesdna_tool.Append (LINKFLAGS = env['BF_PROFILE_LINKFLAGS'])
targetdir = root_build_dir + '/makesdna'
@@ -43,7 +49,10 @@ dna_dict = dna.Dictionary()
dna.Depends ('dna.c', makesdna)
dna.Depends ('dna.c', header_files)
if env['OURPLATFORM'] != 'linuxcross':
- dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna $TARGET")
+ if USE_WINE:
+ dna.Command ('dna.c', '', 'wine ' + root_build_dir+os.sep+"makesdna $TARGET")
+ else:
+ dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna $TARGET")
else:
dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna.exe $TARGET")
obj = ['intern/dna.c', 'intern/dna_genfile.c']
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 7f003cb2b42..7daf32361de 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -23,7 +23,7 @@
#
# ***** END GPL LICENSE BLOCK *****
-FILE(GLOB SRC intern/*.c intern/CMP_nodes/*.c intern/SHD_nodes/*.c)
+FILE(GLOB SRC intern/*.c intern/CMP_nodes/*.c intern/SHD_nodes/*.c intern/TEX_nodes/*.c)
SET(INC
. ../../../intern/guardedalloc ../editors/include ../blenlib ../makesdna
diff --git a/source/blender/nodes/TEX_node.h b/source/blender/nodes/TEX_node.h
index 6be2123b96d..40cb65eacce 100644
--- a/source/blender/nodes/TEX_node.h
+++ b/source/blender/nodes/TEX_node.h
@@ -52,6 +52,8 @@ extern bNodeType tex_node_curve_rgb;
extern bNodeType tex_node_curve_time;
extern bNodeType tex_node_invert;
extern bNodeType tex_node_hue_sat;
+extern bNodeType tex_node_coord;
+extern bNodeType tex_node_distance;
extern bNodeType tex_node_rotate;
extern bNodeType tex_node_translate;
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_coord.c b/source/blender/nodes/intern/TEX_nodes/TEX_coord.c
new file mode 100644
index 00000000000..da487c190af
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_coord.c
@@ -0,0 +1,66 @@
+/**
+ *
+ * ***** 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) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Mathias Panzenböck (panzi) <grosser.meister.morti@gmx.net>.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+static bNodeSocketType outputs[]= {
+ { SOCK_VECTOR, 0, "Coordinates", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void vectorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ out[0] = coord[0];
+ out[1] = coord[1];
+ out[2] = coord[2];
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &vectorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_coord= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_COORD,
+ /* name */ "Coordinates",
+ /* width+range */ 120, 110, 160,
+ /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS,
+ /* input sock */ NULL,
+ /* output sock */ outputs,
+ /* storage */ "node_coord",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c
new file mode 100644
index 00000000000..ff9ec4db76b
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c
@@ -0,0 +1,79 @@
+/**
+ *
+ * ***** 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) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Mathias Panzenböck (panzi) <grosser.meister.morti@gmx.net>.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include "BLI_arithb.h"
+#include "../TEX_util.h"
+
+static bNodeSocketType inputs[]= {
+ { SOCK_VECTOR, 1, "Coordinate 1", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f },
+ { SOCK_VECTOR, 1, "Coordinate 2", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void valuefn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float coord1[3], coord2[3];
+ float x, y, z;
+
+ tex_input_vec(coord1, in[0], coord, thread);
+ tex_input_vec(coord2, in[1], coord, thread);
+
+ *out = VecLenf(coord2, coord1);
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &valuefn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_distance= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_DISTANCE,
+ /* name */ "Distance",
+ /* width+range */ 120, 110, 160,
+ /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "node_distance",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
+
diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c
index 10fe3bab26c..562072328a8 100644
--- a/source/blender/nodes/intern/TEX_util.c
+++ b/source/blender/nodes/intern/TEX_util.c
@@ -46,25 +46,32 @@ void tex_call_delegate(TexDelegate *dg, float *out, float *coord, short thread)
dg->fn(out, coord, dg->node, dg->in, thread);
}
-void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread)
+void tex_input(float *out, int sz, bNodeStack *in, float *coord, short thread)
{
TexDelegate *dg = in->data;
if(dg) {
- tex_call_delegate(dg, out, coord, thread);
+ tex_call_delegate(dg, in->vec, coord, thread);
- if(in->hasoutput && in->sockettype == SOCK_VALUE) {
- out[1] = out[2] = out[0];
- out[3] = 1;
- }
- }
- else {
- QUATCOPY(out, in->vec);
+ if(in->hasoutput && in->sockettype == SOCK_VALUE)
+ in->vec[1] = in->vec[2] = in->vec[0];
}
+ memcpy(out, in->vec, sz * sizeof(float));
+}
+
+void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread)
+{
+ tex_input(out, 3, in, coord, thread);
}
void tex_input_rgba(float *out, bNodeStack *in, float *coord, short thread)
{
- tex_input_vec(out, in, coord, thread);
+ tex_input(out, 4, in, coord, thread);
+
+ if(in->hasoutput && in->sockettype == SOCK_VALUE)
+ {
+ out[1] = out[2] = out[0];
+ out[3] = 1;
+ }
if(in->hasoutput && in->sockettype == SOCK_VECTOR) {
out[0] = out[0] * .5f + .5f;
@@ -83,8 +90,8 @@ float tex_input_value(bNodeStack *in, float *coord, short thread)
static void init_preview(bNode *node)
{
- int xsize = node->prvr.xmax - node->prvr.xmin;
- int ysize = node->prvr.ymax - node->prvr.ymin;
+ int xsize = (int)(node->prvr.xmax - node->prvr.xmin);
+ int ysize = (int)(node->prvr.ymax - node->prvr.ymin);
if(xsize == 0) {
xsize = PREV_RES;
diff --git a/source/creator/creator.c b/source/creator/creator.c
index b9f7ffed198..bfc03c976fb 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -29,6 +29,13 @@
#include <stdlib.h>
#include <string.h>
+
+/* for setuid / getuid */
+#ifdef __sgi
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
/* This little block needed for linking to Blender... */
#include "MEM_guardedalloc.h"
@@ -177,7 +184,7 @@ static void print_help(void)
printf (" -t <threads>\tUse amount of <threads> for rendering (background mode only).\n");
printf (" [1-8], 0 for systems processor count.\n");
printf ("\nAnimation playback options:\n");
- printf (" -a <file(s)>\tPlayback <file(s)>, only operates this way when -b is not used.\n");
+ printf (" -a <options> <file(s)>\tPlayback <file(s)>, only operates this way when -b is not used.\n");
printf (" -p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>\n");
printf (" -m\t\tRead from disk (Don't buffer)\n");
printf (" -f <fps> <fps-base>\t\tSpecify FPS to start with\n");
diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile
index 7ee825d186b..b1be56ac47f 100644
--- a/source/gameengine/BlenderRoutines/Makefile
+++ b/source/gameengine/BlenderRoutines/Makefile
@@ -35,6 +35,7 @@ include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(NAN_SUMO)/include -I$(NAN_SOLID)/include
CPPFLAGS += -I$(NAN_SOLID)
CPPFLAGS += -I$(NAN_STRING)/include
diff --git a/source/gameengine/GamePlayer/common/unix/Makefile b/source/gameengine/GamePlayer/common/unix/Makefile
index a2bdb7225a0..3d44a41afee 100644
--- a/source/gameengine/GamePlayer/common/unix/Makefile
+++ b/source/gameengine/GamePlayer/common/unix/Makefile
@@ -35,6 +35,7 @@ include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
CPPFLAGS += -I$(NAN_STRING)/include
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index bf838e60210..3a20bbfbb11 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -185,7 +185,8 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost)
m_savedMass = GetMass();
m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
m_savedCollisionFilterMask = handle->m_collisionFilterMask;
- body->setActivationState(DISABLE_SIMULATION);
+ m_savedActivationState = body->getActivationState();
+ body->forceActivationState(DISABLE_SIMULATION);
GetPhysicsEnvironment()->updateCcdPhysicsController(this,
0.0,
btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
@@ -204,7 +205,7 @@ void KX_BulletPhysicsController::RestoreDynamics()
m_savedCollisionFlags,
m_savedCollisionFilterGroup,
m_savedCollisionFilterMask);
- GetRigidBody()->forceActivationState(ACTIVE_TAG);
+ GetRigidBody()->forceActivationState(m_savedActivationState);
}
}
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
index cdcb82c87ca..d5fca4ec6d3 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
@@ -9,6 +9,7 @@ class KX_BulletPhysicsController : public KX_IPhysicsController ,public CcdPhysi
{
private:
int m_savedCollisionFlags;
+ int m_savedActivationState;
short int m_savedCollisionFilterGroup;
short int m_savedCollisionFilterMask;
MT_Scalar m_savedMass;
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 53b3e348a36..fb91c793765 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -259,10 +259,75 @@ void KX_Camera::ExtractFrustumSphere()
if (m_set_frustum_center)
return;
- // The most extreme points on the near and far plane. (normalized device coords)
- MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.);
+ // compute sphere for the general case and not only symmetric frustum:
+ // the mirror code in ImageRender can use very asymmetric frustum.
+ // We will put the sphere center on the line that goes from origin to the center of the far clipping plane
+ // This is the optimal position if the frustum is symmetric or very asymmetric and probably close
+ // to optimal for the general case. The sphere center position is computed so that the distance to
+ // the near and far extreme frustum points are equal.
+
+ // get the transformation matrix from device coordinate to camera coordinate
MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix;
clip_camcs_matrix.invert();
+
+ // detect which of the corner of the far clipping plane is the farthest to the origin
+ MT_Vector4 nfar; // far point in device normalized coordinate
+ MT_Point3 farpoint; // most extreme far point in camera coordinate
+ MT_Point3 nearpoint;// most extreme near point in camera coordinate
+ MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate
+ MT_Scalar F=1.0, N; // square distance of far and near point to origin
+ MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0
+ MT_Scalar e, s; // far and near clipping distance (<0)
+ MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance
+ MT_Scalar z; // projection of sphere center on z axis (<0)
+ // tmp value
+ MT_Vector4 npoint(1., 1., 1., 1.);
+ MT_Vector4 hpoint;
+ MT_Point3 point;
+ MT_Scalar len;
+ for (int i=0; i<4; i++)
+ {
+ hpoint = clip_camcs_matrix*npoint;
+ point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]);
+ len = point.dot(point);
+ if (len > F)
+ {
+ nfar = npoint;
+ farpoint = point;
+ F = len;
+ }
+ // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane
+ len = npoint[0];
+ npoint[0] = -npoint[1];
+ npoint[1] = len;
+ farcenter += point;
+ }
+ // the far center is the average of the far clipping points
+ farcenter *= 0.25;
+ // the extreme near point is the opposite point on the near clipping plane
+ nfar.setValue(-nfar[0], -nfar[1], -1., 1.);
+ nfar = clip_camcs_matrix*nfar;
+ nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]);
+ N = nearpoint.dot(nearpoint);
+ e = farpoint[2];
+ s = nearpoint[2];
+ // projection on XY plane for distance to axis computation
+ MT_Point2 farxy(farpoint[0], farpoint[1]);
+ // f is forced positive by construction
+ f = farxy.length();
+ // get corresponding point on the near plane
+ farxy *= s/e;
+ // this formula preserve the sign of n
+ n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length();
+ c = MT_Point2(farcenter[0], farcenter[1]).length()/e;
+ // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case
+ z = (F-N)/(2.0*(e-s+c*(f-n)));
+ m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z);
+ m_frustum_radius = m_frustum_center.distance(farpoint);
+
+#if 0
+ // The most extreme points on the near and far plane. (normalized device coords)
+ MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.);
// Transform to hom camera local space
hnear = clip_camcs_matrix*hnear;
@@ -273,10 +338,12 @@ void KX_Camera::ExtractFrustumSphere()
MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]);
// Compute center
+ // don't use camera data in case the user specifies the matrix directly
m_frustum_center = MT_Point3(0., 0.,
- (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(m_camdata.m_clipend - m_camdata.m_clipstart)));
+ (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(nearpoint[2]-farpoint[2] /*m_camdata.m_clipend - m_camdata.m_clipstart*/)));
m_frustum_radius = m_frustum_center.distance(farpoint);
-
+#endif
+
// Transform to world space.
m_frustum_center = GetCameraToWorld()(m_frustum_center);
m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]);
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index a168beb9a70..e4a37b589a8 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -615,6 +615,7 @@ void KX_GameObject::setAngularVelocity(const MT_Vector3& ang_vel,bool local)
m_pPhysicsController1->SetAngularVelocity(ang_vel,local);
}
+
void KX_GameObject::ResolveCombinedVelocities(
const MT_Vector3 & lin_vel,
const MT_Vector3 & ang_vel,
@@ -969,6 +970,10 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS},
{"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O},
{"setWorldPosition", (PyCFunction) KX_GameObject::sPySetWorldPosition, METH_O},
+ {"applyForce", (PyCFunction) KX_GameObject::sPyApplyForce, METH_VARARGS},
+ {"applyTorque", (PyCFunction) KX_GameObject::sPyApplyTorque, METH_VARARGS},
+ {"applyRotation", (PyCFunction) KX_GameObject::sPyApplyRotation, METH_VARARGS},
+ {"applyMovement", (PyCFunction) KX_GameObject::sPyApplyMovement, METH_VARARGS},
{"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS},
{"setLinearVelocity", (PyCFunction) KX_GameObject::sPySetLinearVelocity, METH_VARARGS},
{"getAngularVelocity", (PyCFunction) KX_GameObject::sPyGetAngularVelocity, METH_VARARGS},
@@ -1261,6 +1266,65 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
return SCA_IObject::_setattr(attr, value);
}
+PyObject* KX_GameObject::PyApplyForce(PyObject* self, PyObject* args)
+{
+ int local = 0;
+ PyObject* pyvect;
+
+ if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ MT_Vector3 force;
+ if (PyVecTo(pyvect, force)) {
+ ApplyForce(force, (local!=0));
+ Py_RETURN_NONE;
+ }
+ }
+ return NULL;
+}
+
+PyObject* KX_GameObject::PyApplyTorque(PyObject* self, PyObject* args)
+{
+ int local = 0;
+ PyObject* pyvect;
+
+ if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ MT_Vector3 torque;
+ if (PyVecTo(pyvect, torque)) {
+ ApplyTorque(torque, (local!=0));
+ Py_RETURN_NONE;
+ }
+ }
+ return NULL;
+}
+
+PyObject* KX_GameObject::PyApplyRotation(PyObject* self, PyObject* args)
+{
+ int local = 0;
+ PyObject* pyvect;
+
+ if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ MT_Vector3 rotation;
+ if (PyVecTo(pyvect, rotation)) {
+ ApplyRotation(rotation, (local!=0));
+ Py_RETURN_NONE;
+ }
+ }
+ return NULL;
+}
+
+PyObject* KX_GameObject::PyApplyMovement(PyObject* self, PyObject* args)
+{
+ int local = 0;
+ PyObject* pyvect;
+
+ if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ MT_Vector3 movement;
+ if (PyVecTo(pyvect, movement)) {
+ ApplyMovement(movement, (local!=0));
+ Py_RETURN_NONE;
+ }
+ }
+ return NULL;
+}
PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, PyObject* args)
{
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 20b15787d27..4f26031356f 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -772,6 +772,10 @@ public:
KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition);
KX_PYMETHOD_O(KX_GameObject,SetPosition);
KX_PYMETHOD_O(KX_GameObject,SetWorldPosition);
+ KX_PYMETHOD_VARARGS(KX_GameObject, ApplyForce);
+ KX_PYMETHOD_VARARGS(KX_GameObject, ApplyTorque);
+ KX_PYMETHOD_VARARGS(KX_GameObject, ApplyRotation);
+ KX_PYMETHOD_VARARGS(KX_GameObject, ApplyMovement);
KX_PYMETHOD_VARARGS(KX_GameObject,GetLinearVelocity);
KX_PYMETHOD_VARARGS(KX_GameObject,SetLinearVelocity);
KX_PYMETHOD_VARARGS(KX_GameObject,GetAngularVelocity);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 4184202c518..8516049f6d8 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -184,7 +184,6 @@ private:
void RenderDebugProperties();
void RenderShadowBuffers(KX_Scene *scene);
void SetBackGround(KX_WorldInfo* worldinfo);
- void SetWorldSettings(KX_WorldInfo* worldinfo);
void DoSound(KX_Scene* scene);
public:
@@ -193,6 +192,7 @@ public:
virtual ~KX_KetsjiEngine();
// set the devices and stuff. the client must take care of creating these
+ void SetWorldSettings(KX_WorldInfo* worldinfo);
void SetKeyboardDevice(SCA_IInputDevice* keyboarddevice);
void SetMouseDevice(SCA_IInputDevice* mousedevice);
void SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice);
@@ -205,6 +205,8 @@ public:
void SetGame2IpoMode(bool game2ipo,int startFrame);
RAS_IRasterizer* GetRasterizer(){return m_rasterizer;};
+ RAS_ICanvas* GetCanvas(){return m_canvas;};
+ RAS_IRenderTools* GetRenderTools(){return m_rendertools;};
///returns true if an update happened to indicate -> Render
bool NextFrame();
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index caa71441b1d..476a931355f 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -1249,7 +1249,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
// If the camera is inside this node, then the object is visible.
if (!vis)
{
- vis = gameobj->GetSGNode()->inside( GetActiveCamera()->GetCameraLocation() );
+ vis = gameobj->GetSGNode()->inside( cam->GetCameraLocation() );
}
// Test the object's bound sphere against the view frustum.
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index 505ce253dd1..efeffab2eed 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -123,6 +123,50 @@ class KX_GameObject:
@return: The game object's rotation matrix
@note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed.
"""
+ def applyMovement(movement, local = 0):
+ """
+ Sets the game object's movement.
+
+ @type movement: 3d vector.
+ @param movement: movement vector.
+ @type local: boolean
+ @param local: - False: you get the "global" movement ie: relative to world orientation (default).
+ - True: you get the "local" movement ie: relative to object orientation.
+ """
+ def applyRotation(movement, local = 0):
+ """
+ Sets the game object's rotation.
+
+ @type rotation: 3d vector.
+ @param rotation: rotation vector.
+ @type local: boolean
+ @param local: - False: you get the "global" rotation ie: relative to world orientation (default).
+ - True: you get the "local" rotation ie: relative to object orientation.
+ """
+ def applyForce(force, local = 0):
+ """
+ Sets the game object's force.
+
+ This requires a dynamic object.
+
+ @type force: 3d vector.
+ @param force: force vector.
+ @type local: boolean
+ @param local: - False: you get the "global" force ie: relative to world orientation (default).
+ - True: you get the "local" force ie: relative to object orientation.
+ """
+ def applyTorque(torque, local = 0):
+ """
+ Sets the game object's torque.
+
+ This requires a dynamic object.
+
+ @type torque: 3d vector.
+ @param torque: torque vector.
+ @type local: boolean
+ @param local: - False: you get the "global" torque ie: relative to world orientation (default).
+ - True: you get the "local" torque ie: relative to object orientation.
+ """
def getLinearVelocity(local = 0):
"""
Gets the game object's linear velocity.
@@ -143,6 +187,8 @@ class KX_GameObject:
This method sets game object's velocity through it's centre of mass,
ie no angular velocity component.
+ This requires a dynamic object.
+
@type velocity: 3d vector.
@param velocity: linear velocity vector.
@type local: boolean
@@ -163,6 +209,8 @@ class KX_GameObject:
"""
Sets the game object's angular velocity.
+ This requires a dynamic object.
+
@type velocity: 3d vector.
@param velocity: angular velocity vector.
@type local: boolean
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index d2cfa7d07f9..282c7306285 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -58,7 +58,7 @@
RAS_2DFilterManager::RAS_2DFilterManager():
texturewidth(-1), textureheight(-1),
canvaswidth(-1), canvasheight(-1),
-numberoffilters(0)
+numberoffilters(0), need_tex_update(true)
{
isshadersupported = GLEW_ARB_shader_objects &&
GLEW_ARB_fragment_shader && GLEW_ARB_multitexture;
@@ -217,50 +217,50 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]);
- if (uniformLoc != -1)
- {
+ if (uniformLoc != -1)
+ {
glUniform1iARB(uniformLoc, 0);
- }
+ }
- /* send depth texture to glsl program if it needs */
+ /* send depth texture to glsl program if it needs */
if(texflag[passindex] & 0x1){
- uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture");
- glActiveTextureARB(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texname[1]);
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture");
+ glActiveTextureARB(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
- if (uniformLoc != -1)
- {
- glUniform1iARB(uniformLoc, 1);
- }
- }
+ if (uniformLoc != -1)
+ {
+ glUniform1iARB(uniformLoc, 1);
+ }
+ }
- /* send luminance texture to glsl program if it needs */
+ /* send luminance texture to glsl program if it needs */
if(texflag[passindex] & 0x2){
- uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
- glActiveTextureARB(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, texname[2]);
-
- if (uniformLoc != -1)
- {
- glUniform1iARB(uniformLoc, 2);
- }
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
+ glActiveTextureARB(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+
+ if (uniformLoc != -1)
+ {
+ glUniform1iARB(uniformLoc, 2);
+ }
}
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_TextureCoordinateOffset");
- if (uniformLoc != -1)
- {
- glUniform2fvARB(uniformLoc, 9, textureoffsets);
- }
+ if (uniformLoc != -1)
+ {
+ glUniform2fvARB(uniformLoc, 9, textureoffsets);
+ }
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureWidth");
- if (uniformLoc != -1)
- {
+ if (uniformLoc != -1)
+ {
glUniform1fARB(uniformLoc,texturewidth);
- }
+ }
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureHeight");
- if (uniformLoc != -1)
- {
+ if (uniformLoc != -1)
+ {
glUniform1fARB(uniformLoc,textureheight);
- }
+ }
int i, objProperties = m_properties[passindex].size();
for(i=0; i<objProperties; i++)
@@ -332,20 +332,20 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
RAS_Rect canvas_rect = canvas->GetWindowArea();
canvaswidth = canvas->GetWidth();
canvasheight = canvas->GetHeight();
- texturewidth = canvaswidth;
- textureheight = canvasheight;
+ texturewidth = canvaswidth + canvas_rect.GetLeft();
+ textureheight = canvasheight + canvas_rect.GetBottom();
GLint i,j;
i = 0;
- while ((1 << i) <= texturewidth)
- i++;
- texturewidth = (1 << (i));
+ while ((1 << i) <= texturewidth)
+ i++;
+ texturewidth = (1 << (i));
- // Now for height
- i = 0;
- while ((1 << i) <= textureheight)
- i++;
- textureheight = (1 << (i));
+ // Now for height
+ i = 0;
+ while ((1 << i) <= textureheight)
+ i++;
+ textureheight = (1 << (i));
GLfloat xInc = 1.0f / (GLfloat)texturewidth;
GLfloat yInc = 1.0f / (GLfloat)textureheight;
@@ -360,6 +360,23 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
}
}
+void RAS_2DFilterManager::UpdateCanvasTextureCoord(unsigned int * viewport)
+{
+ /*
+ This function update canvascoord[].
+ These parameters are used to create texcoord[1]
+ That way we can access the texcoord relative to the canvas:
+ (0.0,0.0) bottom left, (1.0,1.0) top right, (0.5,0.5) center
+ */
+ canvascoord[0] = (GLfloat) viewport[0] / viewport[2];
+ canvascoord[0] *= -1;
+ canvascoord[1] = (GLfloat) (texturewidth - viewport[0]) / viewport[2];
+
+ canvascoord[2] = (GLfloat) viewport[1] / viewport[3];
+ canvascoord[2] *= -1;
+ canvascoord[3] = (GLfloat)(textureheight - viewport[1]) / viewport[3];
+}
+
void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
{
bool need_depth=false;
@@ -387,27 +404,35 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if(num_filters <= 0)
return;
+ GLuint viewport[4]={0};
+ glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
+
if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
{
UpdateOffsetMatrix(canvas);
+ UpdateCanvasTextureCoord((unsigned int*)viewport);
+ need_tex_update = true;
+ }
+
+ if(need_tex_update)
+ {
SetupTextures(need_depth, need_luminance);
+ need_tex_update = false;
}
- GLuint viewport[4]={0};
if(need_depth){
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], texturewidth,textureheight, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, texturewidth,textureheight, 0);
}
if(need_luminance){
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1] , texturewidth,textureheight, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0, 0, texturewidth,textureheight, 0);
}
- glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
- glViewport(viewport[0],viewport[1], texturewidth, textureheight);
+ glViewport(0,0, texturewidth, textureheight);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_TEXTURE);
@@ -425,20 +450,15 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], texturewidth, textureheight, 0);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
glClear(GL_COLOR_BUFFER_BIT);
- float canvascoordx, canvascoordy;
-
- canvascoordx = (GLfloat) texturewidth / canvaswidth;
- canvascoordy = (GLfloat) textureheight / canvasheight;
-
glBegin(GL_QUADS);
glColor4f(1.f, 1.f, 1.f, 1.f);
- glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, canvascoordy); glVertex2f(1,1);
- glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, canvascoordy); glVertex2f(-1,1);
- glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex2f(-1,-1);
- glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, 0.0); glVertex2f(1,-1);
+ glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[3]); glVertex2f(1,1);
+ glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[3]); glVertex2f(-1,1);
+ glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[2]); glVertex2f(-1,-1);
+ glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[2]); glVertex2f(1,-1);
glEnd();
}
}
@@ -454,7 +474,7 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game
return;
if(pass<0 || pass>=MAX_RENDER_PASS)
return;
-
+ need_tex_update = true;
if(mode == RAS_2DFILTER_DISABLED)
{
m_enabled[pass] = 0;
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
index 454643a5077..6a420a974d4 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
@@ -44,7 +44,9 @@ private:
void FreeTextures();
void UpdateOffsetMatrix(RAS_ICanvas* canvas);
-
+ void UpdateCanvasTextureCoord(unsigned int * viewport);
+
+ float canvascoord[4];
float textureoffsets[18];
float view[4];
/* texname[0] contains render to texture, texname[1] contains depth texture, texname[2] contains luminance texture*/
@@ -60,6 +62,7 @@ private:
bool isshadersupported;
bool errorprinted;
+ bool need_tex_update;
unsigned int m_filters[MAX_RENDER_PASS];
short m_enabled[MAX_RENDER_PASS];
diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h
index 9cb59f300f7..610bd13ff12 100644
--- a/source/gameengine/Rasterizer/RAS_FramingManager.h
+++ b/source/gameengine/Rasterizer/RAS_FramingManager.h
@@ -212,9 +212,6 @@ public :
RAS_FrameFrustum &frustum
);
-
-private :
-
static
void
ComputeDefaultFrustum(
@@ -225,6 +222,8 @@ private :
RAS_FrameFrustum & frustum
);
+private :
+
static
void
ComputeBestFitViewRect(
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index 411b28fa3b7..b4b90c3608b 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -200,6 +200,7 @@ public:
* @return true if stereo mode is enabled.
*/
virtual bool Stereo()=0;
+ virtual StereoMode GetStereoMode()=0;
virtual bool InterlacedStereo()=0;
/**
* Sets which eye buffer subsequent primitives will be rendered to.
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 87a0a1d8b9e..3cad5fe74f2 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -406,14 +406,16 @@ void RAS_OpenGLRasterizer::SetRenderArea()
break;
}
}
-
void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
{
m_stereomode = stereomode;
}
-
+RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode()
+{
+ return m_stereomode;
+}
bool RAS_OpenGLRasterizer::Stereo()
{
@@ -775,7 +777,7 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
float frustnear,
float frustfar,
float focallength,
- bool
+ bool
){
MT_Matrix4x4 result;
double mat[16];
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 0717cce0ce8..d39fd642f86 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -137,6 +137,7 @@ public:
virtual void SetRenderArea();
virtual void SetStereoMode(const StereoMode stereomode);
+ virtual RAS_IRasterizer::StereoMode GetStereoMode();
virtual bool Stereo();
virtual bool InterlacedStereo();
virtual void SetEye(const StereoEye eye);
diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp
index 3f939de6bc2..8704d49f2a7 100644
--- a/source/gameengine/VideoTexture/Exception.cpp
+++ b/source/gameengine/VideoTexture/Exception.cpp
@@ -204,6 +204,12 @@ void registerAllExceptions(void)
ImageSizesNotMatchDesc.registerDesc();
SceneInvalidDesc.registerDesc();
CameraInvalidDesc.registerDesc();
+ ObserverInvalidDesc.registerDesc();
+ MirrorInvalidDesc.registerDesc();
+ MirrorSizeInvalidDesc.registerDesc();
+ MirrorNormalInvalidDesc.registerDesc();
+ MirrorHorizontalDesc.registerDesc();
+ MirrorTooSmallDesc.registerDesc();
SourceVideoEmptyDesc.registerDesc();
SourceVideoCreationDesc.registerDesc();
}
diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h
index 5345e87f199..1a3c25071b1 100644
--- a/source/gameengine/VideoTexture/Exception.h
+++ b/source/gameengine/VideoTexture/Exception.h
@@ -202,6 +202,12 @@ extern ExpDesc MaterialNotAvailDesc;
extern ExpDesc ImageSizesNotMatchDesc;
extern ExpDesc SceneInvalidDesc;
extern ExpDesc CameraInvalidDesc;
+extern ExpDesc ObserverInvalidDesc;
+extern ExpDesc MirrorInvalidDesc;
+extern ExpDesc MirrorSizeInvalidDesc;
+extern ExpDesc MirrorNormalInvalidDesc;
+extern ExpDesc MirrorHorizontalDesc;
+extern ExpDesc MirrorTooSmallDesc;
extern ExpDesc SourceVideoEmptyDesc;
extern ExpDesc SourceVideoCreationDesc;
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index a8f7871fa21..58697ed3cc7 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -24,96 +24,238 @@ http://www.gnu.org/copyleft/lesser.txt.
#include <PyObjectPlus.h>
#include <structmember.h>
+#include <float.h>
+#include <math.h>
-#include <KX_BlenderCanvas.h>
-#include <KX_BlenderRenderTools.h>
-#include <RAS_IRasterizer.h>
-#include <RAS_OpenGLRasterizer.h>
-#include <KX_WorldInfo.h>
-#include <KX_Light.h>
-#include "ImageRender.h"
+#include <BIF_gl.h>
+
+#include "KX_PythonInit.h"
+#include "DNA_scene_types.h"
+#include "RAS_CameraData.h"
+#include "RAS_MeshObject.h"
+#include "BLI_arithb.h"
+#include "ImageRender.h"
#include "ImageBase.h"
#include "BlendType.h"
#include "Exception.h"
+#include "Texture.h"
-ExceptionID SceneInvalid, CameraInvalid;
+ExceptionID SceneInvalid, CameraInvalid, ObserverInvalid;
+ExceptionID MirrorInvalid, MirrorSizeInvalid, MirrorNormalInvalid, MirrorHorizontal, MirrorTooSmall;
ExpDesc SceneInvalidDesc (SceneInvalid, "Scene object is invalid");
ExpDesc CameraInvalidDesc (CameraInvalid, "Camera object is invalid");
-
-#if 0 // not yet supported
+ExpDesc ObserverInvalidDesc (ObserverInvalid, "Observer object is invalid");
+ExpDesc MirrorInvalidDesc (MirrorInvalid, "Mirror object is invalid");
+ExpDesc MirrorSizeInvalidDesc (MirrorSizeInvalid, "Mirror has no vertex or no size");
+ExpDesc MirrorNormalInvalidDesc (MirrorNormalInvalid, "Cannot determine mirror plane");
+ExpDesc MirrorHorizontalDesc (MirrorHorizontal, "Mirror is horizontal in local space");
+ExpDesc MirrorTooSmallDesc (MirrorTooSmall, "Mirror is too small");
// constructor
-ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) : m_scene(scene),
-m_camera(camera)
+ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) :
+ ImageViewport(),
+ m_render(true),
+ m_scene(scene),
+ m_camera(camera),
+ m_owncamera(false),
+ m_observer(NULL),
+ m_mirror(NULL),
+ m_clip(100.f)
{
- // create screen area
- m_area.winrct.xmin = m_upLeft[0];
- m_area.winrct.ymin = m_upLeft[1];
- m_area.winx = m_size[0];
- m_area.winy = m_size[1];
- // create canvas
- m_canvas = new KX_BlenderCanvas(&m_area);
- // create render tools
- m_rendertools = new KX_BlenderRenderTools();
- // create rasterizer
- m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
- m_rasterizer->Init();
// initialize background colour
- setBackground(0, 0, 255);
- // refresh lights
- refreshLights();
+ setBackground(0, 0, 255, 255);
+ // retrieve rendering objects
+ m_engine = KX_GetActiveEngine();
+ m_rasterizer = m_engine->GetRasterizer();
+ m_canvas = m_engine->GetCanvas();
+ m_rendertools = m_engine->GetRenderTools();
}
// destructor
ImageRender::~ImageRender (void)
{
- // release allocated objects
- delete m_rasterizer;
- delete m_rendertools;
- delete m_canvas;
+ if (m_owncamera)
+ m_camera->Release();
}
// set background color
-void ImageRender::setBackground (unsigned char red, unsigned char green, unsigned char blue)
+void ImageRender::setBackground (int red, int green, int blue, int alpha)
{
- m_background[0] = red;
- m_background[1] = green;
- m_background[2] = blue;
- m_rasterizer->SetBackColor(m_background[0], m_background[1], m_background[2], 1.0);
+ m_background[0] = (red < 0) ? 0.f : (red > 255) ? 1.f : float(red)/255.f;
+ m_background[1] = (green < 0) ? 0.f : (green > 255) ? 1.f : float(green)/255.f;
+ m_background[2] = (blue < 0) ? 0.f : (blue > 255) ? 1.f : float(blue)/255.f;
+ m_background[3] = (alpha < 0) ? 0.f : (alpha > 255) ? 1.f : float(alpha)/255.f;
}
// capture image from viewport
void ImageRender::calcImage (unsigned int texId)
{
- // setup camera
- bool cameraPasive = !m_camera->GetViewport();
- // render scene
- Render();
- // reset camera
- if (cameraPasive) m_camera->EnableViewport(false);
+ if (m_rasterizer->GetDrawingMode() != RAS_IRasterizer::KX_TEXTURED || // no need for texture
+ m_camera->GetViewport() || // camera must be inactive
+ m_camera == m_scene->GetActiveCamera())
+ {
+ // no need to compute texture in non texture rendering
+ m_avail = false;
+ return;
+ }
+ // render the scene from the camera
+ Render();
// get image from viewport
ImageViewport::calcImage(texId);
+ // restore OpenGL state
+ m_canvas->EndFrame();
}
void ImageRender::Render()
{
- //
-}
+ RAS_FrameFrustum frustrum;
+
+ if (!m_render)
+ return;
+
+ if (m_mirror)
+ {
+ // mirror mode, compute camera frustrum, position and orientation
+ // convert mirror position and normal in world space
+ const MT_Matrix3x3 & mirrorObjWorldOri = m_mirror->GetSGNode()->GetWorldOrientation();
+ const MT_Point3 & mirrorObjWorldPos = m_mirror->GetSGNode()->GetWorldPosition();
+ const MT_Vector3 & mirrorObjWorldScale = m_mirror->GetSGNode()->GetWorldScaling();
+ MT_Point3 mirrorWorldPos =
+ mirrorObjWorldPos + mirrorObjWorldScale * (mirrorObjWorldOri * m_mirrorPos);
+ MT_Vector3 mirrorWorldZ = mirrorObjWorldOri * m_mirrorZ;
+ // get observer world position
+ const MT_Point3 & observerWorldPos = m_observer->GetSGNode()->GetWorldPosition();
+ // get plane D term = mirrorPos . normal
+ MT_Scalar mirrorPlaneDTerm = mirrorWorldPos.dot(mirrorWorldZ);
+ // compute distance of observer to mirror = D - observerPos . normal
+ MT_Scalar observerDistance = mirrorPlaneDTerm - observerWorldPos.dot(mirrorWorldZ);
+ // if distance < 0.01 => observer is on wrong side of mirror, don't render
+ if (observerDistance < 0.01f)
+ return;
+ // set camera world position = observerPos + normal * 2 * distance
+ MT_Point3 cameraWorldPos = observerWorldPos + (MT_Scalar(2.0)*observerDistance)*mirrorWorldZ;
+ m_camera->GetSGNode()->SetLocalPosition(cameraWorldPos);
+ // set camera orientation: z=normal, y=mirror_up in world space, x= y x z
+ MT_Vector3 mirrorWorldY = mirrorObjWorldOri * m_mirrorY;
+ MT_Vector3 mirrorWorldX = mirrorObjWorldOri * m_mirrorX;
+ MT_Matrix3x3 cameraWorldOri(
+ mirrorWorldX[0], mirrorWorldY[0], mirrorWorldZ[0],
+ mirrorWorldX[1], mirrorWorldY[1], mirrorWorldZ[1],
+ mirrorWorldX[2], mirrorWorldY[2], mirrorWorldZ[2]);
+ m_camera->GetSGNode()->SetLocalOrientation(cameraWorldOri);
+ m_camera->GetSGNode()->UpdateWorldData(0.0);
+ // compute camera frustrum:
+ // get position of mirror relative to camera: offset = mirrorPos-cameraPos
+ MT_Vector3 mirrorOffset = mirrorWorldPos - cameraWorldPos;
+ // convert to camera orientation
+ mirrorOffset = mirrorOffset * cameraWorldOri;
+ // scale mirror size to world scale:
+ // get closest local axis for mirror Y and X axis and scale height and width by local axis scale
+ MT_Scalar x, y;
+ x = fabs(m_mirrorY[0]);
+ y = fabs(m_mirrorY[1]);
+ float height = (x > y) ?
+ ((x > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]):
+ ((y > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]);
+ x = fabs(m_mirrorX[0]);
+ y = fabs(m_mirrorX[1]);
+ float width = (x > y) ?
+ ((x > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]):
+ ((y > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]);
+ width *= m_mirrorHalfWidth;
+ height *= m_mirrorHalfHeight;
+ // left = offsetx-width
+ // right = offsetx+width
+ // top = offsety+height
+ // bottom = offsety-height
+ // near = -offsetz
+ // far = near+100
+ frustrum.x1 = mirrorOffset[0]-width;
+ frustrum.x2 = mirrorOffset[0]+width;
+ frustrum.y1 = mirrorOffset[1]-height;
+ frustrum.y2 = mirrorOffset[1]+height;
+ frustrum.camnear = -mirrorOffset[2];
+ frustrum.camfar = -mirrorOffset[2]+m_clip;
+ }
+ const float ortho = 100.0;
+ const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode();
+
+ // The screen area that ImageViewport will copy is also the rendering zone
+ m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1);
+ m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]);
+ m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
+ m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime());
+ m_rendertools->BeginFrame(m_rasterizer);
+ m_engine->SetWorldSettings(m_scene->GetWorldInfo());
+ m_rendertools->SetAuxilaryClientInfo(m_scene);
+ m_rasterizer->DisplayFog();
+ // matrix calculation, don't apply any of the stereo mode
+ m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO);
+ if (m_mirror)
+ {
+ // frustrum was computed above
+ // get frustrum matrix and set projection matrix
+ MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
+ frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
+
+ m_camera->SetProjectionMatrix(projmat);
+ } else if (m_camera->hasValidProjectionMatrix())
+ {
+ m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix());
+ } else
+ {
+ float lens = m_camera->GetLens();
+ bool orthographic = !m_camera->GetCameraData()->m_perspective;
+ float nearfrust = m_camera->GetCameraNear();
+ float farfrust = m_camera->GetCameraFar();
+ float aspect_ratio = 1.0f;
+ Scene *blenderScene = m_scene->GetBlenderScene();
+
+ if (orthographic) {
+ lens *= ortho;
+ nearfrust = (nearfrust + 1.0)*ortho;
+ farfrust *= ortho;
+ }
+ // compute the aspect ratio from frame blender scene settings so that render to texture
+ // works the same in Blender and in Blender player
+ if (blenderScene->r.ysch != 0)
+ aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch);
+
+ RAS_FramingManager::ComputeDefaultFrustum(
+ nearfrust,
+ farfrust,
+ lens,
+ aspect_ratio,
+ frustrum);
+
+ MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
+ frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
+
+ m_camera->SetProjectionMatrix(projmat);
+ }
-// refresh lights
-void ImageRender::refreshLights (void)
-{
- // clear lights list
- //m_rendertools->RemoveAllLights();
- // set lights
- //for (int idx = 0; idx < scene->GetLightList()->GetCount(); ++idx)
- // m_rendertools->AddLight(((KX_LightObject*)(scene->GetLightList()->GetValue(idx)))->GetLightData());
-}
+ MT_Transform camtrans(m_camera->GetWorldToCamera());
+ if (!m_camera->GetCameraData()->m_perspective)
+ camtrans.getOrigin()[2] *= ortho;
+ MT_Matrix4x4 viewmat(camtrans);
+
+ m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(),
+ m_camera->GetCameraLocation(), m_camera->GetCameraOrientation());
+ m_camera->SetModelviewMatrix(viewmat);
+ // restore the stereo mode now that the matrix is computed
+ m_rasterizer->SetStereoMode(stereomode);
+
+ // do not update the mesh, we don't want to do it more than once per frame
+ //m_scene->UpdateMeshTransformations();
+ m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
+
+ m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+}
// cast Image pointer to ImageRender
@@ -174,26 +316,31 @@ static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds
// get background color
PyObject * getBackground (PyImage * self, void * closure)
{
- return Py_BuildValue("[BBB]", getImageRender(self)->getBackground()[0],
- getImageRender(self)->getBackground()[1], getImageRender(self)->getBackground()[2]);
+ return Py_BuildValue("[BBBB]",
+ getImageRender(self)->getBackground(0),
+ getImageRender(self)->getBackground(1),
+ getImageRender(self)->getBackground(2),
+ getImageRender(self)->getBackground(3));
}
// set color
static int setBackground (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
- if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 3
+ if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 4
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0))
|| !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))
- || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)))
+ || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2))
+ || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 3)))
{
- PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 3 ints");
+ PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 4 integer between 0 and 255");
return -1;
}
// set background color
getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))),
(unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))),
- (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))));
+ (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))),
+ (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 3))));
// success
return 0;
}
@@ -209,6 +356,10 @@ static PyMethodDef imageRenderMethods[] =
static PyGetSetDef imageRenderGetSets[] =
{
{(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL},
+ // attribute from ImageViewport
+ {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL},
+ {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
+ {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
// attributes from ImageBase class
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
@@ -263,5 +414,329 @@ PyTypeObject ImageRenderType =
Image_allocNew, /* tp_new */
};
+// object initialization
+static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
+{
+ // parameters - scene object
+ PyObject * scene;
+ // reference object for mirror
+ PyObject * observer;
+ // object holding the mirror
+ PyObject * mirror;
+ // material of the mirror
+ short materialID = 0;
+ // parameter keywords
+ static char *kwlist[] = {"scene", "observer", "mirror", "material", NULL};
+ // get parameters
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|h", kwlist, &scene, &observer, &mirror, &materialID))
+ return -1;
+ try
+ {
+ // get scene pointer
+ KX_Scene * scenePtr (NULL);
+ if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type))
+ scenePtr = static_cast<KX_Scene*>(scene);
+ else
+ THRWEXCP(SceneInvalid, S_OK);
+
+ // get observer pointer
+ KX_GameObject * observerPtr (NULL);
+ if (observer != NULL && PyObject_TypeCheck(observer, &KX_GameObject::Type))
+ observerPtr = static_cast<KX_GameObject*>(observer);
+ else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type))
+ observerPtr = static_cast<KX_Camera*>(observer);
+ else
+ THRWEXCP(ObserverInvalid, S_OK);
+
+ // get mirror pointer
+ KX_GameObject * mirrorPtr (NULL);
+ if (mirror != NULL && PyObject_TypeCheck(mirror, &KX_GameObject::Type))
+ mirrorPtr = static_cast<KX_GameObject*>(mirror);
+ else
+ THRWEXCP(MirrorInvalid, S_OK);
+
+ // locate the material in the mirror
+ RAS_IPolyMaterial * material = getMaterial(mirror, materialID);
+ if (material == NULL)
+ THRWEXCP(MaterialNotAvail, S_OK);
+
+ // get pointer to image structure
+ PyImage * self = reinterpret_cast<PyImage*>(pySelf);
+
+ // create source object
+ if (self->m_image != NULL)
+ {
+ delete self->m_image;
+ self->m_image = NULL;
+ }
+ self->m_image = new ImageRender(scenePtr, observerPtr, mirrorPtr, material);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ return -1;
+ }
+ // initialization succeded
+ return 0;
+}
+
+// get background color
+PyObject * getClip (PyImage * self, void * closure)
+{
+ return PyFloat_FromDouble(getImageRender(self)->getClip());
+}
+
+// set clip
+static int setClip (PyImage * self, PyObject * value, void * closure)
+{
+ // check validity of parameter
+ double clip;
+ if (value == NULL || !PyFloat_Check(value) || (clip = PyFloat_AsDouble(value)) < 0.01 || clip > 5000.0)
+ {
+ PyErr_SetString(PyExc_TypeError, "The value must be an float between 0.01 and 5000");
+ return -1;
+ }
+ // set background color
+ getImageRender(self)->setClip(float(clip));
+ // success
+ return 0;
+}
+
+// attributes structure
+static PyGetSetDef imageMirrorGetSets[] =
+{
+ {(char*)"clip", (getter)getClip, (setter)setClip, (char*)"clipping distance", NULL},
+ // attribute from ImageRender
+ {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL},
+ // attribute from ImageViewport
+ {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL},
+ {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
+ {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
+ // attributes from ImageBase class
+ {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
+ {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
+ {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
+ {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL},
+ {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL},
+ {NULL}
+};
+
+
+// constructor
+ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat) :
+ ImageViewport(),
+ m_render(false),
+ m_scene(scene),
+ m_observer(observer),
+ m_mirror(mirror),
+ m_clip(100.f)
+{
+ // this constructor is used for automatic planar mirror
+ // create a camera, take all data by default, in any case we will recompute the frustrum on each frame
+ RAS_CameraData camdata;
+ vector<RAS_TexVert*> mirrorVerts;
+ vector<RAS_TexVert*>::iterator it;
+ float mirrorArea = 0.f;
+ float mirrorNormal[3] = {0.f, 0.f, 0.f};
+ float mirrorUp[3];
+ float dist, vec[3], axis[3];
+ float zaxis[3] = {0.f, 0.f, 1.f};
+ float yaxis[3] = {0.f, 1.f, 0.f};
+ float mirrorMat[3][3];
+ float left, right, top, bottom, back;
+
+ m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata);
+ m_camera->SetName("__mirror__cam__");
+ // don't add the camera to the scene object list, it doesn't need to be accessible
+ m_owncamera = true;
+ // retrieve rendering objects
+ m_engine = KX_GetActiveEngine();
+ m_rasterizer = m_engine->GetRasterizer();
+ m_canvas = m_engine->GetCanvas();
+ m_rendertools = m_engine->GetRenderTools();
+ // locate the vertex assigned to mat and do following calculation in mesh coordinates
+ for (int meshIndex = 0; meshIndex < mirror->GetMeshCount(); meshIndex++)
+ {
+ RAS_MeshObject* mesh = mirror->GetMesh(meshIndex);
+ int numPolygons = mesh->NumPolygons();
+ for (int polygonIndex=0; polygonIndex < numPolygons; polygonIndex++)
+ {
+ RAS_Polygon* polygon = mesh->GetPolygon(polygonIndex);
+ if (polygon->GetMaterial()->GetPolyMaterial() == mat)
+ {
+ RAS_TexVert *v1, *v2, *v3, *v4;
+ float normal[3];
+ float area;
+ // this polygon is part of the mirror,
+ v1 = polygon->GetVertex(0);
+ v2 = polygon->GetVertex(1);
+ v3 = polygon->GetVertex(2);
+ mirrorVerts.push_back(v1);
+ mirrorVerts.push_back(v2);
+ mirrorVerts.push_back(v3);
+ if (polygon->VertexCount() == 4)
+ {
+ v4 = polygon->GetVertex(3);
+ mirrorVerts.push_back(v4);
+ area = CalcNormFloat4((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ(), normal);
+ } else
+ {
+ area = CalcNormFloat((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), normal);
+ }
+ area = fabs(area);
+ mirrorArea += area;
+ VecMulf(normal, area);
+ VecAddf(mirrorNormal, mirrorNormal, normal);
+ }
+ }
+ }
+ if (mirrorVerts.size() == 0 || mirrorArea < FLT_EPSILON)
+ {
+ // no vertex or zero size mirror
+ THRWEXCP(MirrorSizeInvalid, S_OK);
+ }
+ // compute average normal of mirror faces
+ VecMulf(mirrorNormal, 1.0f/mirrorArea);
+ if (Normalize(mirrorNormal) == 0.f)
+ {
+ // no normal
+ THRWEXCP(MirrorNormalInvalid, S_OK);
+ }
+ // the mirror plane has an equation of the type ax+by+cz = d where (a,b,c) is the normal vector
+ // if the mirror is more vertical then horizontal, the Z axis is the up direction.
+ // otherwise the Y axis is the up direction.
+ // If the mirror is not perfectly vertical(horizontal), the Z(Y) axis projection on the mirror
+ // plan by the normal will be the up direction.
+ if (fabs(mirrorNormal[2]) > fabs(mirrorNormal[1]) &&
+ fabs(mirrorNormal[2]) > fabs(mirrorNormal[0]))
+ {
+ // the mirror is more horizontal than vertical
+ VecCopyf(axis, yaxis);
+ }
+ else
+ {
+ // the mirror is more vertical than horizontal
+ VecCopyf(axis, zaxis);
+ }
+ dist = Inpf(mirrorNormal, axis);
+ if (fabs(dist) < FLT_EPSILON)
+ {
+ // the mirror is already fully aligned with up axis
+ VecCopyf(mirrorUp, axis);
+ }
+ else
+ {
+ // projection of axis to mirror plane through normal
+ VecCopyf(vec, mirrorNormal);
+ VecMulf(vec, dist);
+ VecSubf(mirrorUp, axis, vec);
+ if (Normalize(mirrorUp) == 0.f)
+ {
+ // should not happen
+ THRWEXCP(MirrorHorizontal, S_OK);
+ return;
+ }
+ }
+ // compute rotation matrix between local coord and mirror coord
+ // to match camera orientation, we select mirror z = -normal, y = up, x = y x z
+ VecCopyf(mirrorMat[2], mirrorNormal);
+ VecMulf(mirrorMat[2], -1.0f);
+ VecCopyf(mirrorMat[1], mirrorUp);
+ Crossf(mirrorMat[0], mirrorMat[1], mirrorMat[2]);
+ // transpose to make it a orientation matrix from local space to mirror space
+ Mat3Transp(mirrorMat);
+ // transform all vertex to plane coordinates and determine mirror position
+ left = FLT_MAX;
+ right = -FLT_MAX;
+ bottom = FLT_MAX;
+ top = -FLT_MAX;
+ back = -FLT_MAX; // most backward vertex (=highest Z coord in mirror space)
+ for (it = mirrorVerts.begin(); it != mirrorVerts.end(); it++)
+ {
+ VecCopyf(vec, (float*)(*it)->getXYZ());
+ Mat3MulVecfl(mirrorMat, vec);
+ if (vec[0] < left)
+ left = vec[0];
+ if (vec[0] > right)
+ right = vec[0];
+ if (vec[1] < bottom)
+ bottom = vec[1];
+ if (vec[1] > top)
+ top = vec[1];
+ if (vec[2] > back)
+ back = vec[2];
+ }
+ // now store this information in the object for later rendering
+ m_mirrorHalfWidth = (right-left)*0.5f;
+ m_mirrorHalfHeight = (top-bottom)*0.5f;
+ if (m_mirrorHalfWidth < 0.01f || m_mirrorHalfHeight < 0.01f)
+ {
+ // mirror too small
+ THRWEXCP(MirrorTooSmall, S_OK);
+ }
+ // mirror position in mirror coord
+ vec[0] = (left+right)*0.5f;
+ vec[1] = (top+bottom)*0.5f;
+ vec[2] = back;
+ // convert it in local space: transpose again the matrix to get back to mirror to local transform
+ Mat3Transp(mirrorMat);
+ Mat3MulVecfl(mirrorMat, vec);
+ // mirror position in local space
+ m_mirrorPos.setValue(vec[0], vec[1], vec[2]);
+ // mirror normal vector (pointed towards the back of the mirror) in local space
+ m_mirrorZ.setValue(-mirrorNormal[0], -mirrorNormal[1], -mirrorNormal[2]);
+ m_mirrorY.setValue(mirrorUp[0], mirrorUp[1], mirrorUp[2]);
+ m_mirrorX = m_mirrorY.cross(m_mirrorZ);
+ m_render = true;
+
+ setBackground(0, 0, 255, 255);
+}
+
+
+
+
+// define python type
+PyTypeObject ImageMirrorType =
+{
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "VideoTexture.ImageMirror", /*tp_name*/
+ sizeof(PyImage), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)Image_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ "Image source from mirror", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ imageRenderMethods, /* tp_methods */
+ 0, /* tp_members */
+ imageMirrorGetSets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)ImageMirror_init, /* tp_init */
+ 0, /* tp_alloc */
+ Image_allocNew, /* tp_new */
+};
+
-#endif // #if 0
diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h
index 66255f04d2c..c94e2f1e718 100644
--- a/source/gameengine/VideoTexture/ImageRender.h
+++ b/source/gameengine/VideoTexture/ImageRender.h
@@ -42,42 +42,56 @@ class ImageRender : public ImageViewport
public:
/// constructor
ImageRender (KX_Scene * scene, KX_Camera * camera);
+ ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat);
/// destructor
virtual ~ImageRender (void);
/// get background color
- unsigned char * getBackground (void) { return m_background; }
+ int getBackground (int idx) { return (idx < 0 || idx > 3) ? 0 : int(m_background[idx]*255.f); }
/// set background color
- void setBackground (unsigned char red, unsigned char green, unsigned char blue);
+ void setBackground (int red, int green, int blue, int alpha);
+
+ /// clipping distance
+ float getClip (void) { return m_clip; }
+ /// set whole buffer use
+ void setClip (float clip) { m_clip = clip; }
protected:
+ /// true if ready to render
+ bool m_render;
/// rendered scene
KX_Scene * m_scene;
/// camera for render
KX_Camera * m_camera;
-
- /// screen area for rendering
- ScrArea m_area;
- /// rendering device
- RAS_ICanvas * m_canvas;
- /// rasterizer
- RAS_IRasterizer * m_rasterizer;
- /// render tools
- RAS_IRenderTools * m_rendertools;
+ /// do we own the camera?
+ bool m_owncamera;
+ /// for mirror operation
+ KX_GameObject * m_observer;
+ KX_GameObject * m_mirror;
+ float m_clip; // clipping distance
+ float m_mirrorHalfWidth; // mirror width in mirror space
+ float m_mirrorHalfHeight; // mirror height in mirror space
+ MT_Point3 m_mirrorPos; // mirror center position in local space
+ MT_Vector3 m_mirrorZ; // mirror Z axis in local space
+ MT_Vector3 m_mirrorY; // mirror Y axis in local space
+ MT_Vector3 m_mirrorX; // mirror X axis in local space
+ /// canvas
+ RAS_ICanvas* m_canvas;
+ /// rasterizer
+ RAS_IRasterizer* m_rasterizer;
+ /// render tools
+ RAS_IRenderTools* m_rendertools;
+ /// engine
+ KX_KetsjiEngine* m_engine;
/// background colour
- unsigned char m_background[3];
+ float m_background[4];
/// render 3d scene to image
virtual void calcImage (unsigned int texId);
- /// refresh lights
- void refreshLights (void);
- /// methods from KX_KetsjiEngine
- bool BeginFrame();
- void EndFrame();
void Render();
void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam);
void RenderFrame(KX_Scene* scene, KX_Camera* cam);
diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp
index deb66ffb6ba..4c2c81e2208 100644
--- a/source/gameengine/VideoTexture/ImageViewport.cpp
+++ b/source/gameengine/VideoTexture/ImageViewport.cpp
@@ -34,12 +34,12 @@ http://www.gnu.org/copyleft/lesser.txt.
// constructor
-ImageViewport::ImageViewport (void) : m_texInit(false)
+ImageViewport::ImageViewport (void) : m_alpha(false), m_texInit(false)
{
// get viewport rectangle
glGetIntegerv(GL_VIEWPORT, m_viewport);
// create buffer for viewport image
- m_viewportImage = new BYTE [3 * getViewportSize()[0] * getViewportSize()[1]];
+ m_viewportImage = new BYTE [4 * getViewportSize()[0] * getViewportSize()[1]];
// set attributes
setWhole(false);
}
@@ -62,7 +62,7 @@ void ImageViewport::setWhole (bool whole)
m_capSize[idx] = whole ? short(getViewportSize()[idx])
: calcSize(short(getViewportSize()[idx]));
// position
- m_position[idx] = whole ? 0 : (getViewportSize()[idx] - m_capSize[idx]) >> 1;
+ m_position[idx] = whole ? 0 : ((getViewportSize()[idx] - m_capSize[idx]) >> 1);
}
// init image
init(m_capSize[0], m_capSize[1]);
@@ -123,20 +123,31 @@ void ImageViewport::calcImage (unsigned int texId)
&& m_capSize[1] == calcSize(m_capSize[1]) && !m_flip)
{
// just copy current viewport to texture
- glBindTexture(GL_TEXTURE_2D, texId);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1]);
- // image is not available
- m_avail = false;
+ glBindTexture(GL_TEXTURE_2D, texId);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1]);
+ // image is not available
+ m_avail = false;
}
// otherwise copy viewport to buffer, if image is not available
else if (!m_avail)
{
// get frame buffer data
- glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGB,
- GL_UNSIGNED_BYTE, m_viewportImage);
- // filter loaded data
- FilterRGB24 filt;
- filterImage(filt, m_viewportImage, m_capSize);
+ if (m_alpha)
+ {
+ glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA,
+ GL_UNSIGNED_BYTE, m_viewportImage);
+ // filter loaded data
+ FilterRGBA32 filt;
+ filterImage(filt, m_viewportImage, m_capSize);
+ }
+ else
+ {
+ glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGB,
+ GL_UNSIGNED_BYTE, m_viewportImage);
+ // filter loaded data
+ FilterRGB24 filt;
+ filterImage(filt, m_viewportImage, m_capSize);
+ }
}
}
@@ -151,14 +162,14 @@ inline ImageViewport * getImageViewport (PyImage * self)
// get whole
-static PyObject * ImageViewport_getWhole (PyImage * self, void * closure)
+PyObject * ImageViewport_getWhole (PyImage * self, void * closure)
{
if (self->m_image != NULL && getImageViewport(self)->getWhole()) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
// set whole
-static int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure)
+int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure)
{
// check parameter, report failure
if (value == NULL || !PyBool_Check(value))
@@ -172,6 +183,28 @@ static int ImageViewport_setWhole (PyImage * self, PyObject * value, void * clos
return 0;
}
+// get alpha
+PyObject * ImageViewport_getAlpha (PyImage * self, void * closure)
+{
+ if (self->m_image != NULL && getImageViewport(self)->getAlpha()) Py_RETURN_TRUE;
+ else Py_RETURN_FALSE;
+}
+
+// set whole
+int ImageViewport_setAlpha (PyImage * self, PyObject * value, void * closure)
+{
+ // check parameter, report failure
+ if (value == NULL || !PyBool_Check(value))
+ {
+ PyErr_SetString(PyExc_TypeError, "The value must be a bool");
+ return -1;
+ }
+ // set alpha
+ if (self->m_image != NULL) getImageViewport(self)->setAlpha(value == Py_True);
+ // success
+ return 0;
+}
+
// get position
static PyObject * ImageViewport_getPosition (PyImage * self, void * closure)
@@ -202,14 +235,14 @@ static int ImageViewport_setPosition (PyImage * self, PyObject * value, void * c
}
// get capture size
-static PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure)
+PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure)
{
return Py_BuildValue("(ii)", getImageViewport(self)->getCaptureSize()[0],
getImageViewport(self)->getCaptureSize()[1]);
}
// set capture size
-static int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure)
+int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure)
{
// check validity of parameter
if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2
@@ -242,6 +275,7 @@ static PyGetSetDef imageViewportGetSets[] =
{(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to capture", NULL},
{(char*)"position", (getter)ImageViewport_getPosition, (setter)ImageViewport_setPosition, (char*)"upper left corner of captured area", NULL},
{(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of viewport area being captured", NULL},
+ {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
// attributes from ImageBase class
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
diff --git a/source/gameengine/VideoTexture/ImageViewport.h b/source/gameengine/VideoTexture/ImageViewport.h
index 4265906b8f5..0449249cf95 100644
--- a/source/gameengine/VideoTexture/ImageViewport.h
+++ b/source/gameengine/VideoTexture/ImageViewport.h
@@ -43,6 +43,12 @@ public:
bool getWhole (void) { return m_whole; }
/// set whole buffer use
void setWhole (bool whole);
+
+ /// is alpha channel used
+ bool getAlpha (void) { return m_alpha; }
+ /// set whole buffer use
+ void setAlpha (bool alpha) { m_alpha = alpha; }
+
/// get capture size in viewport
short * getCaptureSize (void) { return m_capSize; }
/// set capture size in viewport
@@ -61,6 +67,8 @@ protected:
short m_capSize[2];
/// use whole viewport
bool m_whole;
+ /// use alpha channel
+ bool m_alpha;
/// position of capture rectangle in viewport
GLint m_position[2];
@@ -79,6 +87,12 @@ protected:
GLint * getViewportSize (void) { return m_viewport + 2; }
};
+PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure);
+int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure);
+PyObject * ImageViewport_getWhole (PyImage * self, void * closure);
+int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure);
+PyObject * ImageViewport_getAlpha (PyImage * self, void * closure);
+int ImageViewport_setAlpha (PyImage * self, PyObject * value, void * closure);
#endif
diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h
index 3c371e51537..1bbef8f0f9e 100644
--- a/source/gameengine/VideoTexture/Texture.h
+++ b/source/gameengine/VideoTexture/Texture.h
@@ -32,6 +32,7 @@ http://www.gnu.org/copyleft/lesser.txt.
#include "ImageBase.h"
#include "BlendType.h"
+#include "Exception.h"
// type Texture declaration
@@ -82,5 +83,10 @@ RAS_IPolyMaterial * getMaterial (PyObject *obj, short matID);
// get material ID
short getMaterialID (PyObject * obj, char * name);
+// Exceptions
+extern ExceptionID MaterialNotAvail;
+
+// object type
+extern BlendType<KX_GameObject> gameObjectType;
#endif
diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp
index b38882f8164..ec066811a52 100644
--- a/source/gameengine/VideoTexture/blendVideoTex.cpp
+++ b/source/gameengine/VideoTexture/blendVideoTex.cpp
@@ -132,6 +132,7 @@ extern PyTypeObject FilterBGR24Type;
extern PyTypeObject ImageBuffType;
extern PyTypeObject ImageMixType;
extern PyTypeObject ImageRenderType;
+extern PyTypeObject ImageMirrorType;
extern PyTypeObject ImageViewportType;
extern PyTypeObject ImageViewportType;
@@ -144,7 +145,8 @@ static void registerAllTypes(void)
#endif
pyImageTypes.add(&ImageBuffType, "ImageBuff");
pyImageTypes.add(&ImageMixType, "ImageMix");
- //pyImageTypes.add(&ImageRenderType, "ImageRender");
+ pyImageTypes.add(&ImageRenderType, "ImageRender");
+ pyImageTypes.add(&ImageMirrorType, "ImageMirror");
pyImageTypes.add(&ImageViewportType, "ImageViewport");
pyFilterTypes.add(&FilterBlueScreenType, "FilterBlueScreen");
diff --git a/source/nan_compile.mk b/source/nan_compile.mk
index 4b13ef8f678..19d833b5b0d 100644
--- a/source/nan_compile.mk
+++ b/source/nan_compile.mk
@@ -120,22 +120,34 @@ ifeq ($(OS),freebsd)
endif
ifeq ($(OS),irix)
- CC = cc
- CCC = CC
- CFLAGS += -n32 -mips3 -Xcpluscomm
- CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std
-ifdef MIPS73_ISOHEADERS
- CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS)
-else
- CCFLAGS += -LANG:libc_in_namespace_std=off
-endif
- REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0
- REL_CCFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0
+ ifeq ($(IRIX_USE_GCC),true)
+ CC = gcc
+ CCC = g++
+ CFLAGS += -fPIC -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4
+ CCFLAGS += -fPIC -fpermissive -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4
+ REL_CFLAGS += -O2
+ REL_CCFLAGS += -O2
+ CPPFLAGS += -DXP_UNIX
+ DBG_CFLAGS += -g3 -gdwarf-2 -ggdb
+ DBG_CCFLAGS += -g3 -gdwarf-2 -ggdb
+ else
+ CC = cc
+ CCC = CC
+ CFLAGS += -n32 -mips3 -Xcpluscomm
+ CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std
+ ifdef MIPS73_ISOHEADERS
+ CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS)
+ else
+ CCFLAGS += -LANG:libc_in_namespace_std=off
+ endif
+ REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0
+ REL_CCFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0
+ endif
OPENGL_HEADERS = /usr/include
NAN_DEPEND = true
AR = CC
ARFLAGS = -ar -o
- ARFLAGSQUIET = -ar -o
+ ARFLAGSQUIET = -ar -o
endif
ifeq ($(OS),linux)
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index 424a7c558d7..04a1d107931 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -75,6 +75,7 @@ else
export NAN_SOLID ?= $(LCGDIR)/solid
export NAN_QHULL ?= $(LCGDIR)/qhull
endif
+ export NAN_USE_BULLET ?= true
export NAN_BULLET2 ?= $(LCGDIR)/bullet2
export NAN_SUMO ?= $(SRCHOME)/gameengine/Physics/Sumo
export NAN_FUZZICS ?= $(SRCHOME)/gameengine/Physics/Sumo/Fuzzics
@@ -83,7 +84,7 @@ endif
export NAN_GUARDEDALLOC ?= $(LCGDIR)/guardedalloc
export NAN_IKSOLVER ?= $(LCGDIR)/iksolver
export NAN_BSP ?= $(LCGDIR)/bsp
- export NAN_BOOLOP ?= $(LCGDIR)/boolop
+ export NAN_BOOLOP ?= $(LCGDIR)/boolop
export NAN_SOUNDSYSTEM ?= $(LCGDIR)/SoundSystem
export NAN_STRING ?= $(LCGDIR)/string
export NAN_MEMUTIL ?= $(LCGDIR)/memutil
@@ -116,7 +117,7 @@ endif
export WITH_DDS ?= true
ifeq ($(OS),windows)
- export NAN_WINTAB ?= $(LCGDIR)/wintab
+ export NAN_WINTAB ?= $(LCGDIR)/wintab
ifeq ($(FREE_WINDOWS), true)
export NAN_PTHREADS ?= $(LCGDIR)/pthreads
export NAN_OPENEXR ?= $(LCGDIR)/gcc/openexr
@@ -129,28 +130,34 @@ endif
endif
else
ifeq ($(OS),darwin)
- export NAN_OPENEXR ?= $(LCGDIR)/openexr
- ifeq ($(CPU),powerpc)
- export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a
- else
- export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a
- endif
+ export NAN_OPENEXR ?= $(LCGDIR)/openexr
+ ifeq ($(CPU),powerpc)
+ export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a
+ else
+ export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a
+ endif
else
ifeq ($(OS),linux)
- ifeq ($(WITH_OPENEXR), true)
- NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR )
- NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR )
- NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs-only-l OpenEXR | sed -s "s/-l//g" )))
- endif
+ ifeq ($(WITH_OPENEXR), true)
+ NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR )
+ NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR )
+ NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs-only-l OpenEXR | sed -s "s/-l//g" )))
+ endif
else
ifeq ($(OS), solaris)
# this only exists at the moment for i386-64 CPU Types at the moment
export NAN_OPENEXR ?= $(LCGDIR)/openexr
-
export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a -lrt
else
- export NAN_OPENEXR ?= /usr/local
- export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a
+ ifeq ($(OS), irix)
+ ifeq ($(IRIX_USE_GCC), true)
+ export NAN_OPENEXR ?= $(LCGDIR)/openexr/gcc
+ else
+ export NAN_OPENEXR ?= $(LCGDIR)/openexr
+ endif
+ endif
+ export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR
+ export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a
endif
endif
endif
@@ -331,23 +338,27 @@ endif
export NAN_PYTHON ?= $(LCGDIR)/python
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
- export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a -lpthread
export NAN_OPENAL ?= $(LCGDIR)/openal
export NAN_FMOD ?= $(LCGDIR)/fmod
export NAN_JPEG ?= $(LCGDIR)/jpeg
export NAN_PNG ?= $(LCGDIR)/png
- export NAN_TIFF ?= /usr/freeware
+ export NAN_TIFF ?= $(LCGDIR)/tiff
export NAN_ODE ?= $(LCGDIR)/ode
export NAN_TERRAPLAY ?= $(LCGDIR)/terraplay
export NAN_MESA ?= /usr/src/Mesa-3.1
- export NAN_ZLIB ?= /usr/freeware
+ export NAN_ZLIB ?= $(LCGDIR)/zlib
export NAN_NSPR ?= $(LCGDIR)/nspr
- export NAN_FREETYPE ?= /usr/freeware
- export NAN_GETTEXT ?= /usr/freeware
- export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib32/libintl.a
+ export NAN_FREETYPE ?= $(LCGDIR)/freetype
+ export NAN_ICONV ?= $(LCGDIR)/iconv
+ export NAN_GETTEXT ?= $(LCGDIR)/gettext
+ export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib/libintl.a $(NAN_ICONV)/lib/libiconv.a
export NAN_SDL ?= $(LCGDIR)/sdl
- export NAN_SDLLIBS ?= -L$(NAN_SDL)/lib -lSDL
+ export NAN_SDLLIBS ?= $(NAN_SDL)/lib/libSDL.a
export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include/SDL
+ export NAN_FFMPEG ?= $(LCGDIR)/ffmpeg
+ export NAN_FFMPEGLIBS = $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavcodec.a $(NAN_FFMPEG)/lib/libswscale.a $(NAN_FFMPEG)/lib/libavutil.a $(NAN_FFMPEG)/lib/libogg.a $(NAN_FFMPEG)/lib/libfaad.a $(NAN_FFMPEG)/lib/libmp3lame.a $(NAN_FFMPEG)/lib/libvorbis.a $(NAN_FFMPEG)/lib/libx264.a $(NAN_FFMPEG)/lib/libfaac.a $(NAN_ZLIB)/lib/libz.a
+ export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include
# Uncomment the following line to use Mozilla inplace of netscape
# CPPFLAGS +=-DMOZ_NOT_NET
diff --git a/source/nan_link.mk b/source/nan_link.mk
index 8dda3b8c2df..186fe07e09a 100644
--- a/source/nan_link.mk
+++ b/source/nan_link.mk
@@ -72,11 +72,19 @@ ifeq ($(OS),freebsd)
endif
ifeq ($(OS),irix)
- LDFLAGS += -mips3
- LLIBS = -lmovieGL -lGLU -lGL -lXmu -lXext -lX11 -lc -lm -ldmedia
- LLIBS += -lcl -laudio -ldb -lCio -lz
- LLIBS += -lpthread
- LLIBS += -woff 84,171
+ ifeq ($(IRIX_USE_GCC), true)
+ LDFLAGS += -mabi=n32 -mips4
+ DBG_LDFLAGS += -LD_LAYOUT:lgot_buffer=40
+ else
+ LDFLAGS += -n32 -mips3
+ LDFLAGS += -woff 84,171
+ endif
+ LLIBS = -lmovieGL -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldmedia
+ LLIBS += -lcl -laudio
+ ifneq ($(IRIX_USE_GCC), true)
+ LLIBS += -lCio -ldb
+ endif
+ LLIBS += -lz -lpthread
DYNLDFLAGS = -shared $(LDFLAGS)
endif
@@ -90,7 +98,7 @@ ifeq ($(OS),linux)
ifeq ($(CPU),$(findstring $(CPU), "i386 x86_64 ia64 parisc64 powerpc sparc64"))
COMMENT = "MESA 3.1"
LLIBS = -L$(NAN_MESA)/lib -L/usr/X11R6/lib -lXmu -lXext -lX11 -lXi
- LLIBS += -lutil -lc -lm -ldl -lpthread
+ LLIBS += -lutil -lc -lm -ldl -lpthread
# LLIBS += -L$(NAN_ODE)/lib -lode
LOPTS = -export-dynamic
DADD = -lGL -lGLU