BGE: Remove old world bge.render API
[blender.git] / source / gameengine / Ketsji / KX_WorldInfo.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/Ketsji/KX_WorldInfo.cpp
29  *  \ingroup ketsji
30  */
31
32
33 #include "KX_WorldInfo.h"
34 #include "KX_PythonInit.h"
35 #include "KX_PyMath.h"
36 #include "RAS_IRasterizer.h"
37 #include "GPU_material.h"
38
39 /* This little block needed for linking to Blender... */
40 #ifdef WIN32
41 #include "BLI_winstuff.h"
42 #endif
43
44 /* This list includes only data type definitions */
45 #include "DNA_scene_types.h"
46 #include "DNA_world_types.h"
47
48 #include "BLI_math.h"
49
50 #include "BKE_global.h"
51 #include "BKE_scene.h"
52 /* end of blender include block */
53
54
55 KX_WorldInfo::KX_WorldInfo(Scene *blenderscene, World *blenderworld)
56 {
57         if (blenderworld) {
58                 m_name = blenderworld->id.name + 2;
59                 m_do_color_management = BKE_scene_check_color_management_enabled(blenderscene);
60                 m_hasworld = true;
61                 m_hasmist = ((blenderworld->mode) & WO_MIST ? true : false);
62                 m_misttype = blenderworld->mistype;
63                 m_miststart = blenderworld->miststa;
64                 m_mistdistance = blenderworld->mistdist;
65                 m_mistintensity = blenderworld->misi;
66                 setMistColor(blenderworld->horr, blenderworld->horg, blenderworld->horb);
67                 setBackColor(blenderworld->horr, blenderworld->horg, blenderworld->horb);
68                 setAmbientColor(blenderworld->ambr, blenderworld->ambg, blenderworld->ambb);
69         }
70         else {
71                 m_hasworld = false;
72         }
73 }
74
75 KX_WorldInfo::~KX_WorldInfo()
76 {
77 }
78
79 const STR_String& KX_WorldInfo::GetName()
80 {
81         return m_name;
82 }
83
84 bool KX_WorldInfo::hasWorld()
85 {
86         return m_hasworld;
87 }
88
89 void KX_WorldInfo::setBackColor(float r, float g, float b)
90 {
91         m_backgroundcolor[0] = r;
92         m_backgroundcolor[1] = g;
93         m_backgroundcolor[2] = b;
94
95         if (m_do_color_management) {
96                 linearrgb_to_srgb_v3_v3(m_con_backgroundcolor, m_backgroundcolor);
97         }
98         else {
99                 copy_v3_v3(m_con_backgroundcolor, m_backgroundcolor);
100         }
101 }
102
103 void KX_WorldInfo::setMistType(short type)
104 {
105         m_misttype = type;
106 }
107
108 void KX_WorldInfo::setUseMist(bool enable)
109 {
110         m_hasmist = enable;
111 }
112
113 void KX_WorldInfo::setMistStart(float d)
114 {
115         m_miststart = d;
116 }
117
118 void KX_WorldInfo::setMistDistance(float d)
119 {
120         m_mistdistance = d;
121 }
122
123 void KX_WorldInfo::setMistIntensity(float intensity)
124 {
125         m_mistintensity = intensity;
126 }
127 void KX_WorldInfo::setMistColor(float r, float g, float b)
128 {
129         m_mistcolor[0] = r;
130         m_mistcolor[1] = g;
131         m_mistcolor[2] = b;
132
133         if (m_do_color_management) {
134                 linearrgb_to_srgb_v3_v3(m_con_mistcolor, m_mistcolor);
135         }
136         else {
137                 copy_v3_v3(m_con_mistcolor, m_mistcolor);
138         }
139 }
140
141 void KX_WorldInfo::setAmbientColor(float r, float g, float b)
142 {
143         m_ambientcolor[0] = r;
144         m_ambientcolor[1] = g;
145         m_ambientcolor[2] = b;
146
147         if (m_do_color_management) {
148                 linearrgb_to_srgb_v3_v3(m_con_ambientcolor, m_ambientcolor);
149         }
150         else {
151                 copy_v3_v3(m_con_ambientcolor, m_ambientcolor);
152         }
153 }
154
155 void KX_WorldInfo::UpdateBackGround()
156 {
157         if (m_hasworld) {
158                 RAS_IRasterizer *m_rasterizer = KX_GetActiveEngine()->GetRasterizer();
159
160                 if (m_rasterizer->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID) {
161                         m_rasterizer->SetBackColor(m_con_backgroundcolor);
162                         GPU_horizon_update_color(m_backgroundcolor);
163                 }
164         }
165 }
166
167 void KX_WorldInfo::UpdateWorldSettings()
168 {
169         if (m_hasworld) {
170                 RAS_IRasterizer *m_rasterizer = KX_GetActiveEngine()->GetRasterizer();
171
172                 if (m_rasterizer->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID) {
173                         m_rasterizer->SetAmbientColor(m_con_ambientcolor);
174                         GPU_ambient_update_color(m_ambientcolor);
175
176                         if (m_hasmist) {
177                                 m_rasterizer->SetFog(m_misttype, m_miststart, m_mistdistance, m_mistintensity, m_con_mistcolor);
178                                 GPU_mist_update_values(m_misttype, m_miststart, m_mistdistance, m_mistintensity, m_mistcolor);
179                                 m_rasterizer->EnableFog(true);
180                                 GPU_mist_update_enable(true);
181                         }
182                         else {
183                                 m_rasterizer->EnableFog(false);
184                                 GPU_mist_update_enable(false);
185                         }
186                 }
187         }
188 }
189
190 #ifdef WITH_PYTHON
191
192 /* -------------------------------------------------------------------------
193  * Python functions
194  * ------------------------------------------------------------------------- */
195 PyObject *KX_WorldInfo::py_repr(void)
196 {
197         return PyUnicode_From_STR_String(GetName());
198 }
199
200 /* -------------------------------------------------------------------------
201  * Python Integration Hooks
202  * ------------------------------------------------------------------------- */
203 PyTypeObject KX_WorldInfo::Type = {
204         PyVarObject_HEAD_INIT(NULL, 0)
205         "KX_WorldInfo",
206         sizeof(PyObjectPlus_Proxy),
207         0,
208         py_base_dealloc,
209         0,
210         0,
211         0,
212         0,
213         py_base_repr,
214         0,0,0,0,0,0,0,0,0,
215         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
216         0,0,0,0,0,0,0,
217         Methods,
218         0,
219         0,
220         &PyObjectPlus::Type,
221         0,0,0,0,0,0,
222         py_base_new
223 };
224
225 PyMethodDef KX_WorldInfo::Methods[] = {
226         {NULL,NULL} /* Sentinel */
227 };
228
229 PyAttributeDef KX_WorldInfo::Attributes[] = {
230         KX_PYATTRIBUTE_BOOL_RW("mist_enable", KX_WorldInfo, m_hasmist),
231         KX_PYATTRIBUTE_FLOAT_RW("mist_start", 0.0f, 10000.0f, KX_WorldInfo, m_miststart),
232         KX_PYATTRIBUTE_FLOAT_RW("mist_distance", 0.001f, 10000.0f, KX_WorldInfo, m_mistdistance),
233         KX_PYATTRIBUTE_FLOAT_RW("mist_intensity", 0.0f, 1.0f, KX_WorldInfo, m_mistintensity),
234         KX_PYATTRIBUTE_SHORT_RW("mist_type", 0, 2, true, KX_WorldInfo, m_misttype),
235         KX_PYATTRIBUTE_RO_FUNCTION("KX_MIST_QUADRATIC", KX_WorldInfo, pyattr_get_mist_typeconst),
236         KX_PYATTRIBUTE_RO_FUNCTION("KX_MIST_LINEAR", KX_WorldInfo, pyattr_get_mist_typeconst),
237         KX_PYATTRIBUTE_RO_FUNCTION("KX_MIST_INV_QUADRATIC", KX_WorldInfo, pyattr_get_mist_typeconst),
238         KX_PYATTRIBUTE_RW_FUNCTION("mist_color", KX_WorldInfo, pyattr_get_mist_color, pyattr_set_mist_color),
239         KX_PYATTRIBUTE_RW_FUNCTION("background_color", KX_WorldInfo, pyattr_get_back_color, pyattr_set_back_color),
240         KX_PYATTRIBUTE_RW_FUNCTION("ambient_color", KX_WorldInfo, pyattr_get_ambient_color, pyattr_set_ambient_color),
241         { NULL } /* Sentinel */
242 };
243
244 /* Attribute get/set functions */
245
246 #ifdef USE_MATHUTILS
247
248 /*----------------------mathutils callbacks ----------------------------*/
249
250 /* subtype */
251 #define MATHUTILS_VEC_CB_MIST_COLOR 1
252 #define MATHUTILS_VEC_CB_BACK_COLOR 2
253 #define MATHUTILS_VEC_CB_AMBIENT_COLOR 3
254
255 static unsigned char mathutils_world_vector_cb_index = -1; /* index for our callbacks */
256
257 static int mathutils_world_generic_check(BaseMathObject *bmo)
258 {
259         KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
260         if (self == NULL)
261                 return -1;
262                 
263         return 0;
264 }
265
266 static int mathutils_world_vector_get(BaseMathObject *bmo, int subtype)
267 {
268         KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
269         if (self == NULL)
270                 return -1;
271
272         switch (subtype) {
273                 case MATHUTILS_VEC_CB_MIST_COLOR:
274                         copy_v3_v3(bmo->data, self->m_mistcolor);
275                         break;
276                 case MATHUTILS_VEC_CB_BACK_COLOR:
277                         copy_v3_v3(bmo->data, self->m_backgroundcolor);
278                         break;
279                 case MATHUTILS_VEC_CB_AMBIENT_COLOR:
280                         copy_v3_v3(bmo->data, self->m_ambientcolor);
281                         break;
282         default:
283                 return -1;
284         }
285         return 0;
286 }
287
288 static int mathutils_world_vector_set(BaseMathObject *bmo, int subtype)
289 {
290         KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
291
292         if (self == NULL)
293                 return -1;
294
295         switch (subtype) {
296                 case MATHUTILS_VEC_CB_MIST_COLOR:
297                         self->setMistColor(bmo->data[0], bmo->data[1], bmo->data[2]);
298                         break;
299                 case MATHUTILS_VEC_CB_BACK_COLOR:
300                         self->setBackColor(bmo->data[0], bmo->data[1], bmo->data[2]);
301                         break;
302                 case MATHUTILS_VEC_CB_AMBIENT_COLOR:
303                         self->setAmbientColor(bmo->data[0], bmo->data[1], bmo->data[2]);
304                         break;
305         default:
306                 return -1;
307         }
308         return 0;
309 }
310
311 static int mathutils_world_vector_get_index(BaseMathObject *bmo, int subtype, int index)
312 {
313         KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
314
315         if (self == NULL)
316                 return -1;
317
318         switch (subtype) {
319                 case MATHUTILS_VEC_CB_MIST_COLOR:
320                 {
321                         const float *color = self->m_mistcolor;
322                         bmo->data[index] = color[index];
323                 }
324                 break;
325                 case MATHUTILS_VEC_CB_BACK_COLOR:
326                 {
327                         const float *color = self->m_backgroundcolor;
328                         bmo->data[index] = color[index];
329                 }
330                         break;
331                 case MATHUTILS_VEC_CB_AMBIENT_COLOR:
332                 {
333                         const float *color = self->m_ambientcolor;
334                         bmo->data[index] = color[index];
335                 }
336                 break;
337         default:
338                 return -1;
339         }
340         return 0;
341 }
342
343 static int mathutils_world_vector_set_index(BaseMathObject *bmo, int subtype, int index)
344 {
345         KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
346
347         if (self == NULL)
348                 return -1;
349
350         float color[4];
351         switch (subtype) {
352                 case MATHUTILS_VEC_CB_MIST_COLOR:
353                         copy_v3_v3(color, self->m_mistcolor);
354                         color[index] = bmo->data[index];
355                         self->setMistColor(color[0], color[1], color[2]);
356                 break;
357                 case MATHUTILS_VEC_CB_BACK_COLOR:
358                         copy_v3_v3(color, self->m_backgroundcolor);
359                         color[index] = bmo->data[index];
360                         self->setBackColor(color[0], color[1], color[2]);
361                 break;
362                 case MATHUTILS_VEC_CB_AMBIENT_COLOR:
363                         copy_v3_v3(color, self->m_ambientcolor);
364                         color[index] = bmo->data[index];
365                         self->setAmbientColor(color[0], color[1], color[2]);
366                         break;
367         default:
368                 return -1;
369         }
370         return 0;
371 }
372
373 static Mathutils_Callback mathutils_world_vector_cb = {
374         mathutils_world_generic_check,
375         mathutils_world_vector_get,
376         mathutils_world_vector_set,
377         mathutils_world_vector_get_index,
378         mathutils_world_vector_set_index
379 };
380
381 void KX_WorldInfo_Mathutils_Callback_Init()
382 {
383         // register mathutils callbacks, ok to run more than once.
384         mathutils_world_vector_cb_index = Mathutils_RegisterCallback(&mathutils_world_vector_cb);
385 }
386 #endif // USE_MATHUTILS
387
388
389 PyObject *KX_WorldInfo::pyattr_get_mist_typeconst(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
390 {
391         PyObject *retvalue;
392
393         const char* type = attrdef->m_name;
394
395         if (!strcmp(type, "KX_MIST_QUADRATIC")) {
396                 retvalue = PyLong_FromLong(KX_MIST_QUADRATIC);
397         } 
398         else if (!strcmp(type, "KX_MIST_LINEAR")) {
399                 retvalue = PyLong_FromLong(KX_MIST_LINEAR);
400         } 
401         else if (!strcmp(type, "KX_MIST_INV_QUADRATIC")) {
402                 retvalue = PyLong_FromLong(KX_MIST_INV_QUADRATIC);
403         }
404         else {
405                 /* should never happen */
406                 PyErr_SetString(PyExc_TypeError, "invalid mist type");
407                 retvalue = NULL;
408         }
409
410         return retvalue;
411 }
412
413 PyObject *KX_WorldInfo::pyattr_get_mist_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
414 {
415 #ifdef USE_MATHUTILS
416         return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_MIST_COLOR);
417 #else
418         KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
419         return PyObjectFrom(MT_Vector3(self->m_mistcolor));
420 #endif
421 }
422
423 int KX_WorldInfo::pyattr_set_mist_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
424 {
425         KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
426
427         MT_Vector3 color;
428         if (PyVecTo(value, color))
429         {
430                 self->setMistColor(color[0], color[1], color[2]);
431                 return PY_SET_ATTR_SUCCESS;
432         }
433         return PY_SET_ATTR_FAIL;
434 }
435
436 PyObject *KX_WorldInfo::pyattr_get_back_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
437 {
438
439 #ifdef USE_MATHUTILS
440         return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_BACK_COLOR);
441 #else
442         KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
443         return PyObjectFrom(MT_Vector3(self->m_backgroundcolor));
444 #endif
445 }
446
447 int KX_WorldInfo::pyattr_set_back_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
448 {
449         KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
450
451         MT_Vector3 color;
452         if (PyVecTo(value, color))
453         {
454                 self->setBackColor(color[0], color[1], color[2]);
455                 return PY_SET_ATTR_SUCCESS;
456         }
457         return PY_SET_ATTR_FAIL;
458 }
459
460 PyObject *KX_WorldInfo::pyattr_get_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
461 {
462 #ifdef USE_MATHUTILS
463         return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_AMBIENT_COLOR);
464 #else
465         KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
466         return PyObjectFrom(MT_Vector3(self->m_ambientcolor));
467 #endif
468 }
469
470 int KX_WorldInfo::pyattr_set_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
471 {
472         KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
473
474         MT_Vector3 color;
475         if (PyVecTo(value, color))
476         {
477                 self->setAmbientColor(color[0], color[1], color[2]);
478                 return PY_SET_ATTR_SUCCESS;
479         }
480         return PY_SET_ATTR_FAIL;
481 }
482
483 #endif /* WITH_PYTHON */