diff options
author | Porteries Tristan <republicthunderbolt9@gmail.com> | 2015-07-03 12:47:48 +0300 |
---|---|---|
committer | Porteries Tristan <republicthunderbolt9@gmail.com> | 2015-07-03 12:47:48 +0300 |
commit | 145ab8c49efe0de188a55f4c682dd5fcf916f105 (patch) | |
tree | 543a2dd491a0601be32d7486bd2ee92868656d8d /source/gameengine/Ketsji/KX_BlenderMaterial.cpp | |
parent | 659e5234afcd09db6b9000990d66d3e59880e29a (diff) |
BGE: Extend Python API for KX_BlenderMaterial (specular, diffuse…)
Add support for material diffuse, specular… in KX_BlenderMaterial python proxy. And use mathutils in KX_BlenderMaterial for the specular and diffuse color in KX_BlenderMaterial.
Reviewers: sybren, brita_, kupoman, agoose77, dfelinto, moguri, campbellbarton, hg1
Reviewed By: moguri, campbellbarton, hg1
Subscribers: dfelinto
Projects: #game_engine
Differential Revision: https://developer.blender.org/D1298
Diffstat (limited to 'source/gameengine/Ketsji/KX_BlenderMaterial.cpp')
-rw-r--r-- | source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 7ec2673bf1f..abe565f8e2f 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -30,6 +30,7 @@ #include "KX_Light.h" #include "KX_GameObject.h" #include "KX_MeshProxy.h" +#include "KX_PyMath.h" #include "MT_Vector3.h" #include "MT_Vector4.h" @@ -52,6 +53,7 @@ #include "BKE_mesh.h" // ------------------------------------ #include "BLI_utildefines.h" +#include "BLI_math.h" #define spit(x) std::cout << x << std::endl; @@ -844,6 +846,11 @@ void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val) OnConstruction(); } +BL_Material *KX_BlenderMaterial::GetBLMaterial() +{ + return mMaterial; +} + void KX_BlenderMaterial::SetBlenderGLSLShader() { if (!mBlenderShader) @@ -855,6 +862,111 @@ void KX_BlenderMaterial::SetBlenderGLSLShader() } } +#ifdef USE_MATHUTILS + +#define MATHUTILS_COL_CB_MATERIAL_SPECULAR_COLOR 1 +#define MATHUTILS_COL_CB_MATERIAL_DIFFUSE_COLOR 2 + +static unsigned char mathutils_kxblendermaterial_color_cb_index = -1; /* index for our callbacks */ + +static int mathutils_kxblendermaterial_generic_check(BaseMathObject *bmo) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>BGE_PROXY_REF(bmo->cb_user); + if (!self) + return -1; + + return 0; +} + +static int mathutils_kxblendermaterial_color_get(BaseMathObject *bmo, int subtype) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial*>BGE_PROXY_REF(bmo->cb_user); + if (!self) + return -1; + + switch (subtype) { + case MATHUTILS_COL_CB_MATERIAL_DIFFUSE_COLOR: + { + copy_v3_v3(bmo->data, self->GetBLMaterial()->matcolor); + break; + } + case MATHUTILS_COL_CB_MATERIAL_SPECULAR_COLOR: + { + copy_v3_v3(bmo->data, self->GetBLMaterial()->speccolor); + break; + } + } + + return 0; +} + +static int mathutils_kxblendermaterial_color_set(BaseMathObject *bmo, int subtype) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>BGE_PROXY_REF(bmo->cb_user); + if (!self) + return -1; + + switch (subtype) { + case MATHUTILS_COL_CB_MATERIAL_DIFFUSE_COLOR: + { + BL_Material *mat = self->GetBLMaterial(); + copy_v3_v3(mat->matcolor, bmo->data); + mat->material->r = bmo->data[0]; + mat->material->g = bmo->data[1]; + mat->material->b = bmo->data[2]; + break; + } + case MATHUTILS_COL_CB_MATERIAL_SPECULAR_COLOR: + { + BL_Material *mat = self->GetBLMaterial(); + copy_v3_v3(mat->speccolor, bmo->data); + mat->material->specr = bmo->data[0]; + mat->material->specg = bmo->data[1]; + mat->material->specb = bmo->data[2]; + break; + } + } + + return 0; +} + +static int mathutils_kxblendermaterial_color_get_index(BaseMathObject *bmo, int subtype, int index) +{ + /* lazy, avoid repeteing the case statement */ + if (mathutils_kxblendermaterial_color_get(bmo, subtype) == -1) + return -1; + return 0; +} + +static int mathutils_kxblendermaterial_color_set_index(BaseMathObject *bmo, int subtype, int index) +{ + float f = bmo->data[index]; + + /* lazy, avoid repeateing the case statement */ + if (mathutils_kxblendermaterial_color_get(bmo, subtype) == -1) + return -1; + + bmo->data[index] = f; + return mathutils_kxblendermaterial_color_set(bmo, subtype); +} + +static Mathutils_Callback mathutils_kxblendermaterial_color_cb = { + mathutils_kxblendermaterial_generic_check, + mathutils_kxblendermaterial_color_get, + mathutils_kxblendermaterial_color_set, + mathutils_kxblendermaterial_color_get_index, + mathutils_kxblendermaterial_color_set_index +}; + + +void KX_BlenderMaterial_Mathutils_Callback_Init() +{ + // register mathutils callbacks, ok to run more than once. + mathutils_kxblendermaterial_color_cb_index = Mathutils_RegisterCallback(&mathutils_kxblendermaterial_color_cb); +} + +#endif // USE_MATHUTILS + #ifdef WITH_PYTHON PyMethodDef KX_BlenderMaterial::Methods[] = @@ -869,6 +981,14 @@ PyAttributeDef KX_BlenderMaterial::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("shader", KX_BlenderMaterial, pyattr_get_shader), KX_PYATTRIBUTE_RO_FUNCTION("material_index", KX_BlenderMaterial, pyattr_get_materialIndex), KX_PYATTRIBUTE_RW_FUNCTION("blending", KX_BlenderMaterial, pyattr_get_blending, pyattr_set_blending), + KX_PYATTRIBUTE_RW_FUNCTION("alpha", KX_BlenderMaterial, pyattr_get_alpha, pyattr_set_alpha), + KX_PYATTRIBUTE_RW_FUNCTION("hardness", KX_BlenderMaterial, pyattr_get_hardness, pyattr_set_hardness), + KX_PYATTRIBUTE_RW_FUNCTION("specularIntensity", KX_BlenderMaterial, pyattr_get_specular_intensity, pyattr_set_specular_intensity), + KX_PYATTRIBUTE_RW_FUNCTION("specularColor", KX_BlenderMaterial, pyattr_get_specular_color, pyattr_set_specular_color), + KX_PYATTRIBUTE_RW_FUNCTION("diffuseIntensity", KX_BlenderMaterial, pyattr_get_diffuse_intensity, pyattr_set_diffuse_intensity), + KX_PYATTRIBUTE_RW_FUNCTION("diffuseColor", KX_BlenderMaterial, pyattr_get_diffuse_color, pyattr_set_diffuse_color), + KX_PYATTRIBUTE_RW_FUNCTION("emit", KX_BlenderMaterial, pyattr_get_emit, pyattr_set_emit), + { NULL } //Sentinel }; @@ -913,6 +1033,170 @@ PyObject *KX_BlenderMaterial::pyattr_get_blending(void *self_v, const KX_PYATTRI return Py_BuildValue("(ll)", (long int)bfunc[0], (long int)bfunc[1]); } +PyObject *KX_BlenderMaterial::pyattr_get_alpha(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + return PyFloat_FromDouble(self->GetBLMaterial()->alpha); +} + +int KX_BlenderMaterial::pyattr_set_alpha(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + float val = PyFloat_AsDouble(value); + + if (val == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "material.%s = float: KX_BlenderMaterial, expected a float", attrdef->m_name); + return PY_SET_ATTR_FAIL; + } + + CLAMP(val, 0.0f, 1.0f); + + BL_Material *mat = self->GetBLMaterial(); + mat->alpha = mat->material->alpha = val; + return PY_SET_ATTR_SUCCESS; +} +PyObject *KX_BlenderMaterial::pyattr_get_hardness(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + return PyLong_FromLong(self->GetBLMaterial()->hard); +} + +int KX_BlenderMaterial::pyattr_set_hardness(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + int val = PyLong_AsLong(value); + + if (val == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "material.%s = int: KX_BlenderMaterial, expected a int", attrdef->m_name); + return PY_SET_ATTR_FAIL; + } + + CLAMP(val, 1, 511); + + BL_Material *mat = self->GetBLMaterial(); + mat->hard = mat->material->har = val; + return PY_SET_ATTR_SUCCESS; +} + +PyObject *KX_BlenderMaterial::pyattr_get_specular_intensity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + return PyFloat_FromDouble(self->GetBLMaterial()->spec_f); +} + +int KX_BlenderMaterial::pyattr_set_specular_intensity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + float val = PyFloat_AsDouble(value); + + if (val == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "material.%s = float: KX_BlenderMaterial, expected a float", attrdef->m_name); + return PY_SET_ATTR_FAIL; + } + + CLAMP(val, 0.0f, 1.0f); + + BL_Material *mat = self->GetBLMaterial(); + mat->spec_f = mat->material->spec = val; + return PY_SET_ATTR_SUCCESS; +} + +PyObject *KX_BlenderMaterial::pyattr_get_specular_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ +#ifdef USE_MATHUTILS + return Color_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), mathutils_kxblendermaterial_color_cb_index, MATHUTILS_COL_CB_MATERIAL_SPECULAR_COLOR); +#else + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + return PyColorFromVector(MT_Vector3(self->GetBLMaterial()->speccolor)); +#endif +} + +int KX_BlenderMaterial::pyattr_set_specular_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + MT_Vector3 color; + if (!PyVecTo(value, color)) + return PY_SET_ATTR_FAIL; + + BL_Material *mat = self->GetBLMaterial(); + color.getValue(mat->speccolor); + mat->material->specr = color[0]; + mat->material->specg = color[1]; + mat->material->specb = color[2]; + return PY_SET_ATTR_SUCCESS; +} + +PyObject *KX_BlenderMaterial::pyattr_get_diffuse_intensity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + return PyFloat_FromDouble(self->GetBLMaterial()->ref); +} + +int KX_BlenderMaterial::pyattr_set_diffuse_intensity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + float val = PyFloat_AsDouble(value); + + if (val == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "material.%s = float: KX_BlenderMaterial, expected a float", attrdef->m_name); + return PY_SET_ATTR_FAIL; + } + + CLAMP(val, 0.0f, 1.0f); + + BL_Material *mat = self->GetBLMaterial(); + mat->ref = mat->material->ref = val; + return PY_SET_ATTR_SUCCESS; +} + +PyObject *KX_BlenderMaterial::pyattr_get_diffuse_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ +#ifdef USE_MATHUTILS + return Color_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), mathutils_kxblendermaterial_color_cb_index, MATHUTILS_COL_CB_MATERIAL_DIFFUSE_COLOR); +#else + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + return PyColorFromVector(MT_Vector3(self->GetBLMaterial()->matcolor)); +#endif +} + +int KX_BlenderMaterial::pyattr_set_diffuse_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + MT_Vector3 color; + if (!PyVecTo(value, color)) + return PY_SET_ATTR_FAIL; + + BL_Material *mat = self->GetBLMaterial(); + color.getValue(mat->matcolor); + mat->material->r = color[0]; + mat->material->g = color[1]; + mat->material->b = color[2]; + return PY_SET_ATTR_SUCCESS; +} + +PyObject *KX_BlenderMaterial::pyattr_get_emit(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + return PyFloat_FromDouble(self->GetBLMaterial()->emit); +} + +int KX_BlenderMaterial::pyattr_set_emit(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_BlenderMaterial *self = static_cast<KX_BlenderMaterial *>(self_v); + float val = PyFloat_AsDouble(value); + + if (val == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "material.%s = float: KX_BlenderMaterial, expected a float", attrdef->m_name); + return PY_SET_ATTR_FAIL; + } + + CLAMP(val, 0.0f, 2.0f); + + BL_Material *mat = self->GetBLMaterial(); + mat->emit = mat->material->emit = val; + return PY_SET_ATTR_SUCCESS; +} + int KX_BlenderMaterial::pyattr_set_blending(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_BlenderMaterial* self = static_cast<KX_BlenderMaterial*>(self_v); |