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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/VideoTexture/ImageRender.cpp')
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp594
1 files changed, 297 insertions, 297 deletions
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 6038416ba68..f7546d876b2 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -65,29 +65,29 @@ ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) :
m_owncamera(false),
m_observer(NULL),
m_mirror(NULL),
- m_clip(100.f)
+ m_clip(100.f)
{
// initialize background color
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();
+ // 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)
{
- if (m_owncamera)
- m_camera->Release();
+ if (m_owncamera)
+ m_camera->Release();
}
// set background color
void ImageRender::setBackground (int red, int green, int blue, int alpha)
{
- m_background[0] = (red < 0) ? 0.f : (red > 255) ? 1.f : float(red)/255.f;
+ 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;
@@ -97,157 +97,157 @@ void ImageRender::setBackground (int red, int green, int blue, int alpha)
// capture image from viewport
void ImageRender::calcImage (unsigned int texId, double ts)
{
- 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();
+ 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, ts);
- // restore OpenGL state
- m_canvas->EndFrame();
+ // 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;
- }
+ 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;
+ }
// Store settings to be restored later
- const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode();
+ const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode();
RAS_Rect area = m_canvas->GetWindowArea();
- // 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
+ // 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);
+ frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
m_camera->SetProjectionMatrix(projmat);
- } else if (m_camera->hasValidProjectionMatrix())
+ } else if (m_camera->hasValidProjectionMatrix())
{
m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix());
- } else
- {
+ } 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();
+ float aspect_ratio = 1.0f;
+ Scene *blenderScene = m_scene->GetBlenderScene();
MT_Matrix4x4 projmat;
// 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*blenderScene->r.xasp) / float(blenderScene->r.ysch*blenderScene->r.yasp);
+ // works the same in Blender and in Blender player
+ if (blenderScene->r.ysch != 0)
+ aspect_ratio = float(blenderScene->r.xsch*blenderScene->r.xasp) / float(blenderScene->r.ysch*blenderScene->r.yasp);
if (orthographic) {
RAS_FramingManager::ComputeDefaultOrtho(
- nearfrust,
- farfrust,
- m_camera->GetScale(),
- aspect_ratio,
- frustrum
- );
+ nearfrust,
+ farfrust,
+ m_camera->GetScale(),
+ aspect_ratio,
+ frustrum
+ );
projmat = m_rasterizer->GetOrthoMatrix(
- frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
- } else
+ frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
+ } else
{
RAS_FramingManager::ComputeDefaultFrustum(
- nearfrust,
- farfrust,
- lens,
- aspect_ratio,
- frustrum);
+ nearfrust,
+ farfrust,
+ lens,
+ aspect_ratio,
+ frustrum);
projmat = m_rasterizer->GetFrustumMatrix(
- frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
+ frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
}
m_camera->SetProjectionMatrix(projmat);
}
@@ -257,8 +257,8 @@ void ImageRender::Render()
m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldOrientation(), m_camera->NodeGetWorldPosition(), m_camera->GetCameraData()->m_perspective);
m_camera->SetModelviewMatrix(viewmat);
- // restore the stereo mode now that the matrix is computed
- m_rasterizer->SetStereoMode(stereomode);
+ // restore the stereo mode now that the matrix is computed
+ m_rasterizer->SetStereoMode(stereomode);
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
@@ -328,11 +328,11 @@ static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds
// get background color
PyObject * getBackground (PyImage * self, void * closure)
{
- return Py_BuildValue("[BBBB]",
- getImageRender(self)->getBackground(0),
- getImageRender(self)->getBackground(1),
- getImageRender(self)->getBackground(2),
- getImageRender(self)->getBackground(3));
+ return Py_BuildValue("[BBBB]",
+ getImageRender(self)->getBackground(0),
+ getImageRender(self)->getBackground(1),
+ getImageRender(self)->getBackground(2),
+ getImageRender(self)->getBackground(3));
}
// set color
@@ -433,24 +433,24 @@ static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds
PyObject * scene;
// reference object for mirror
PyObject * observer;
- // object holding the mirror
- PyObject * mirror;
- // material of the mirror
- short materialID = 0;
+ // object holding the mirror
+ PyObject * mirror;
+ // material of the mirror
+ short materialID = 0;
// parameter keywords
static const char *kwlist[] = {"scene", "observer", "mirror", "material", NULL};
// get parameters
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|h",
- const_cast<char**>(kwlist), &scene, &observer, &mirror, &materialID))
+ const_cast<char**>(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*>BGE_PROXY_REF(scene);
+ if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type))
+ scenePtr = static_cast<KX_Scene*>BGE_PROXY_REF(scene);
else
- THRWEXCP(SceneInvalid, S_OK);
+ THRWEXCP(SceneInvalid, S_OK);
if(scenePtr==NULL) /* incase the python proxy reference is invalid */
THRWEXCP(SceneInvalid, S_OK);
@@ -458,11 +458,11 @@ static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds
// get observer pointer
KX_GameObject * observerPtr (NULL);
if (observer != NULL && PyObject_TypeCheck(observer, &KX_GameObject::Type))
- observerPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(observer);
- else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type))
- observerPtr = static_cast<KX_Camera*>BGE_PROXY_REF(observer);
+ observerPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(observer);
+ else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type))
+ observerPtr = static_cast<KX_Camera*>BGE_PROXY_REF(observer);
else
- THRWEXCP(ObserverInvalid, S_OK);
+ THRWEXCP(ObserverInvalid, S_OK);
if(observerPtr==NULL) /* incase the python proxy reference is invalid */
THRWEXCP(ObserverInvalid, S_OK);
@@ -470,27 +470,27 @@ static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds
// get mirror pointer
KX_GameObject * mirrorPtr (NULL);
if (mirror != NULL && PyObject_TypeCheck(mirror, &KX_GameObject::Type))
- mirrorPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(mirror);
+ mirrorPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(mirror);
else
- THRWEXCP(MirrorInvalid, S_OK);
+ THRWEXCP(MirrorInvalid, S_OK);
if(mirrorPtr==NULL) /* incase the python proxy reference is invalid */
THRWEXCP(MirrorInvalid, S_OK);
- // locate the material in the mirror
+ // locate the material in the mirror
RAS_IPolyMaterial * material = getMaterial(mirror, materialID);
if (material == NULL)
- THRWEXCP(MaterialNotAvail, S_OK);
+ 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;
- }
+ 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)
@@ -530,7 +530,7 @@ 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
+ // 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},
@@ -552,164 +552,164 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj
m_scene(scene),
m_observer(observer),
m_mirror(mirror),
- m_clip(100.f)
+ 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
+ // 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;
+ 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;
// make sure this camera will delete its node
m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata, true, true);
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 = normal_quad_v3( normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ());
- } else
- {
- area = normal_tri_v3( normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ());
- }
- area = fabs(area);
- mirrorArea += area;
- mul_v3_fl(normal, area);
- add_v3_v3v3(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
- mul_v3_fl(mirrorNormal, 1.0f/mirrorArea);
- if (normalize_v3(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
+ // 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 = normal_quad_v3( normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ());
+ } else
+ {
+ area = normal_tri_v3( normal,(float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ());
+ }
+ area = fabs(area);
+ mirrorArea += area;
+ mul_v3_fl(normal, area);
+ add_v3_v3v3(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
+ mul_v3_fl(mirrorNormal, 1.0f/mirrorArea);
+ if (normalize_v3(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]))
+ fabs(mirrorNormal[2]) > fabs(mirrorNormal[0]))
{
// the mirror is more horizontal than vertical
- copy_v3_v3(axis, yaxis);
+ copy_v3_v3(axis, yaxis);
}
else
{
// the mirror is more vertical than horizontal
- copy_v3_v3(axis, zaxis);
+ copy_v3_v3(axis, zaxis);
+ }
+ dist = dot_v3v3(mirrorNormal, axis);
+ if (fabs(dist) < FLT_EPSILON)
+ {
+ // the mirror is already fully aligned with up axis
+ copy_v3_v3(mirrorUp, axis);
+ }
+ else
+ {
+ // projection of axis to mirror plane through normal
+ copy_v3_v3(vec, mirrorNormal);
+ mul_v3_fl(vec, dist);
+ sub_v3_v3v3(mirrorUp, axis, vec);
+ if (normalize_v3(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
+ negate_v3_v3(mirrorMat[2], mirrorNormal);
+ copy_v3_v3(mirrorMat[1], mirrorUp);
+ cross_v3_v3v3(mirrorMat[0], mirrorMat[1], mirrorMat[2]);
+ // transpose to make it a orientation matrix from local space to mirror space
+ transpose_m3(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++)
+ {
+ copy_v3_v3(vec, (float*)(*it)->getXYZ());
+ mul_m3_v3(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);
}
- dist = dot_v3v3(mirrorNormal, axis);
- if (fabs(dist) < FLT_EPSILON)
- {
- // the mirror is already fully aligned with up axis
- copy_v3_v3(mirrorUp, axis);
- }
- else
- {
- // projection of axis to mirror plane through normal
- copy_v3_v3(vec, mirrorNormal);
- mul_v3_fl(vec, dist);
- sub_v3_v3v3(mirrorUp, axis, vec);
- if (normalize_v3(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
- negate_v3_v3(mirrorMat[2], mirrorNormal);
- copy_v3_v3(mirrorMat[1], mirrorUp);
- cross_v3_v3v3(mirrorMat[0], mirrorMat[1], mirrorMat[2]);
- // transpose to make it a orientation matrix from local space to mirror space
- transpose_m3(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++)
- {
- copy_v3_v3(vec, (float*)(*it)->getXYZ());
- mul_m3_v3(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
- transpose_m3(mirrorMat);
- mul_m3_v3(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;
+ // 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
+ transpose_m3(mirrorMat);
+ mul_m3_v3(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);
}