~ubuntu-branches/ubuntu/lucid/blender/lucid

« back to all changes in this revision

Viewing changes to source/gameengine/Ketsji/KX_Camera.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2009-08-06 22:32:19 UTC
  • mfrom: (1.2.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806223219-8z4eej1u8levu4pz
Tags: 2.49a+dfsg-0ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/control: Build-depend on python-2.6 rather than python-2.5.
  - debian/misc/*.desktop: Add Spanish translation to .desktop 
    files.
  - debian/pyversions: 2.6.
  - debian/rules: Clean *.o of source/blender/python/api2_2x/
* New upstream release (LP: #382153).
* Refreshed patches:
  - 01_sanitize_sys.patch
  - 02_tmp_in_HOME
  - 10_use_systemwide_ftgl
  - 70_portability_platform_detection
* Removed patches merged upstream:
  - 30_fix_python_syntax_warning
  - 90_ubuntu_ffmpeg_52_changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: KX_Camera.cpp 15444 2008-07-05 17:05:05Z lukep $
 
2
 * $Id: KX_Camera.cpp 20828 2009-06-12 12:56:12Z campbellbarton $
3
3
 *
4
4
 * ***** BEGIN GPL LICENSE BLOCK *****
5
5
 *
28
28
 * Camera in the gameengine. Cameras are also used for views.
29
29
 */
30
30
 
 
31
#include "GL/glew.h"
31
32
#include "KX_Camera.h"
32
33
#include "KX_Scene.h"
33
34
#include "KX_PythonInit.h"
41
42
                                         SG_Callbacks callbacks,
42
43
                                         const RAS_CameraData& camdata,
43
44
                                         bool frustum_culling,
 
45
                                         bool delete_node,
44
46
                                         PyTypeObject *T)
45
47
                                        :
46
48
                                        KX_GameObject(sgReplicationInfo,callbacks,T),
47
49
                                        m_camdata(camdata),
48
50
                                        m_dirty(true),
49
51
                                        m_normalized(false),
50
 
                                        m_frustum_culling(frustum_culling && camdata.m_perspective),
 
52
                                        m_frustum_culling(frustum_culling),
51
53
                                        m_set_projection_matrix(false),
52
 
                                        m_set_frustum_center(false)
 
54
                                        m_set_frustum_center(false),
 
55
                                        m_delete_node(delete_node)
53
56
{
54
57
        // setting a name would be nice...
55
58
        m_name = "cam";
63
66
 
64
67
KX_Camera::~KX_Camera()
65
68
{
 
69
        if (m_delete_node && m_pSGNode)
 
70
        {
 
71
                // for shadow camera, avoids memleak
 
72
                delete m_pSGNode;
 
73
                m_pSGNode = NULL;
 
74
        }
66
75
}       
67
76
 
68
77
 
71
80
        KX_Camera* replica = new KX_Camera(*this);
72
81
        
73
82
        // this will copy properties and so on...
74
 
        CValue::AddDataToReplica(replica);
75
 
        ProcessReplica(replica);
 
83
        replica->ProcessReplica();
76
84
        
77
85
        return replica;
78
86
}
79
 
        
80
 
void KX_Camera::ProcessReplica(KX_Camera* replica)
 
87
 
 
88
void KX_Camera::ProcessReplica()
81
89
{
82
 
        KX_GameObject::ProcessReplica(replica);
 
90
        KX_GameObject::ProcessReplica();
 
91
        // replicated camera are always registered in the scene
 
92
        m_delete_node = false;
83
93
}
84
94
 
85
95
MT_Transform KX_Camera::GetWorldToCamera() const
190
200
        return m_camdata.m_lens;
191
201
}
192
202
 
 
203
float KX_Camera::GetScale() const
 
204
{
 
205
        return m_camdata.m_scale;
 
206
}
 
207
 
193
208
 
194
209
 
195
210
float KX_Camera::GetCameraNear() const
259
274
        if (m_set_frustum_center)
260
275
                return;
261
276
 
262
 
        // The most extreme points on the near and far plane. (normalized device coords)
263
 
        MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.);
 
277
    // compute sphere for the general case and not only symmetric frustum:
 
278
    // the mirror code in ImageRender can use very asymmetric frustum.
 
279
    // We will put the sphere center on the line that goes from origin to the center of the far clipping plane
 
280
    // This is the optimal position if the frustum is symmetric or very asymmetric and probably close
 
281
    // to optimal for the general case. The sphere center position is computed so that the distance to 
 
282
    // the near and far extreme frustum points are equal.
 
283
 
 
284
    // get the transformation matrix from device coordinate to camera coordinate
264
285
        MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix;
265
286
        clip_camcs_matrix.invert();
266
 
        
267
 
        // Transform to hom camera local space
268
 
        hnear = clip_camcs_matrix*hnear;
269
 
        hfar = clip_camcs_matrix*hfar;
270
 
        
271
 
        // Tranform to 3d camera local space.
272
 
        MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]);
273
 
        MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]);
274
 
        
275
 
        // Compute center
276
 
        m_frustum_center = MT_Point3(0., 0.,
277
 
                (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(m_camdata.m_clipend - m_camdata.m_clipstart)));
278
 
        m_frustum_radius = m_frustum_center.distance(farpoint);
279
 
        
 
287
 
 
288
        if (m_projection_matrix[3][3] == MT_Scalar(0.0)) 
 
289
        {
 
290
                // frustrum projection
 
291
                // detect which of the corner of the far clipping plane is the farthest to the origin
 
292
                MT_Vector4 nfar;    // far point in device normalized coordinate
 
293
                MT_Point3 farpoint; // most extreme far point in camera coordinate
 
294
                MT_Point3 nearpoint;// most extreme near point in camera coordinate
 
295
                MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate
 
296
                MT_Scalar F=-1.0, N; // square distance of far and near point to origin
 
297
                MT_Scalar f, n;     // distance of far and near point to z axis. f is always > 0 but n can be < 0
 
298
                MT_Scalar e, s;     // far and near clipping distance (<0)
 
299
                MT_Scalar c;        // slope of center line = distance of far clipping center to z axis / far clipping distance
 
300
                MT_Scalar z;        // projection of sphere center on z axis (<0)
 
301
                // tmp value
 
302
                MT_Vector4 npoint(1., 1., 1., 1.);
 
303
                MT_Vector4 hpoint;
 
304
                MT_Point3 point;
 
305
                MT_Scalar len;
 
306
                for (int i=0; i<4; i++)
 
307
                {
 
308
                hpoint = clip_camcs_matrix*npoint;
 
309
                        point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]);
 
310
                        len = point.dot(point);
 
311
                        if (len > F)
 
312
                        {
 
313
                                nfar = npoint;
 
314
                                farpoint = point;
 
315
                                F = len;
 
316
                        }
 
317
                        // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane
 
318
                        len = npoint[0];
 
319
                        npoint[0] = -npoint[1];
 
320
                        npoint[1] = len;
 
321
                        farcenter += point;
 
322
                }
 
323
                // the far center is the average of the far clipping points
 
324
                farcenter *= 0.25;
 
325
                // the extreme near point is the opposite point on the near clipping plane
 
326
                nfar.setValue(-nfar[0], -nfar[1], -1., 1.);
 
327
                nfar = clip_camcs_matrix*nfar;
 
328
                nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]);
 
329
                // this is a frustrum projection
 
330
                N = nearpoint.dot(nearpoint);
 
331
                e = farpoint[2];
 
332
                s = nearpoint[2];
 
333
                // projection on XY plane for distance to axis computation
 
334
                MT_Point2 farxy(farpoint[0], farpoint[1]);
 
335
                // f is forced positive by construction
 
336
                f = farxy.length();
 
337
                // get corresponding point on the near plane
 
338
                farxy *= s/e;
 
339
                // this formula preserve the sign of n
 
340
                n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length();
 
341
                c = MT_Point2(farcenter[0], farcenter[1]).length()/e;
 
342
                // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case
 
343
                z = (F-N)/(2.0*(e-s+c*(f-n)));
 
344
                m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z);
 
345
                m_frustum_radius = m_frustum_center.distance(farpoint);
 
346
        } 
 
347
        else
 
348
        {
 
349
                // orthographic projection
 
350
                // The most extreme points on the near and far plane. (normalized device coords)
 
351
                MT_Vector4 hnear(1., 1., 1., 1.), hfar(-1., -1., -1., 1.);
 
352
                
 
353
                // Transform to hom camera local space
 
354
                hnear = clip_camcs_matrix*hnear;
 
355
                hfar = clip_camcs_matrix*hfar;
 
356
                
 
357
                // Tranform to 3d camera local space.
 
358
                MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]);
 
359
                MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]);
 
360
                
 
361
                // just use mediant point
 
362
                m_frustum_center = (farpoint + nearpoint)*0.5;
 
363
                m_frustum_radius = m_frustum_center.distance(farpoint);
 
364
        }
280
365
        // Transform to world space.
281
366
        m_frustum_center = GetCameraToWorld()(m_frustum_center);
282
367
        m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]);
403
488
 
404
489
PyMethodDef KX_Camera::Methods[] = {
405
490
        KX_PYMETHODTABLE(KX_Camera, sphereInsideFrustum),
406
 
        KX_PYMETHODTABLE(KX_Camera, boxInsideFrustum),
407
 
        KX_PYMETHODTABLE(KX_Camera, pointInsideFrustum),
408
 
        KX_PYMETHODTABLE(KX_Camera, getCameraToWorld),
409
 
        KX_PYMETHODTABLE(KX_Camera, getWorldToCamera),
410
 
        KX_PYMETHODTABLE(KX_Camera, getProjectionMatrix),
411
 
        KX_PYMETHODTABLE(KX_Camera, setProjectionMatrix),
412
 
        KX_PYMETHODTABLE(KX_Camera, enableViewport),
 
491
        KX_PYMETHODTABLE_O(KX_Camera, boxInsideFrustum),
 
492
        KX_PYMETHODTABLE_O(KX_Camera, pointInsideFrustum),
 
493
        KX_PYMETHODTABLE_NOARGS(KX_Camera, getCameraToWorld),
 
494
        KX_PYMETHODTABLE_NOARGS(KX_Camera, getWorldToCamera),
413
495
        KX_PYMETHODTABLE(KX_Camera, setViewport),
414
 
        KX_PYMETHODTABLE(KX_Camera, setOnTop),
 
496
        KX_PYMETHODTABLE_NOARGS(KX_Camera, setOnTop),
 
497
        KX_PYMETHODTABLE_O(KX_Camera, getScreenPosition),
 
498
        KX_PYMETHODTABLE(KX_Camera, getScreenVect),
 
499
        KX_PYMETHODTABLE(KX_Camera, getScreenRay),
 
500
 
 
501
        // DEPRECATED
 
502
        KX_PYMETHODTABLE_O(KX_Camera, enableViewport),
 
503
        KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix),
 
504
        KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix),
415
505
        
416
506
        {NULL,NULL} //Sentinel
417
507
};
418
508
 
419
 
char KX_Camera::doc[] = "Module KX_Camera\n\n"
420
 
"Constants:\n"
421
 
"\tINSIDE\n"
422
 
"\tINTERSECT\n"
423
 
"\tOUTSIDE\n"
424
 
"Attributes:\n"
425
 
"\tlens -> float\n"
426
 
"\t\tThe camera's lens value\n"
427
 
"\tnear -> float\n"
428
 
"\t\tThe camera's near clip distance\n"
429
 
"\tfar -> float\n"
430
 
"\t\tThe camera's far clip distance\n"
431
 
"\tfrustum_culling -> bool\n"
432
 
"\t\tNon zero if this camera is frustum culling.\n"
433
 
"\tprojection_matrix -> [[float]]\n"
434
 
"\t\tThis camera's projection matrix.\n"
435
 
"\tmodelview_matrix -> [[float]] (read only)\n"
436
 
"\t\tThis camera's model view matrix.\n"
437
 
"\t\tRegenerated every frame from the camera's position and orientation.\n"
438
 
"\tcamera_to_world -> [[float]] (read only)\n"
439
 
"\t\tThis camera's camera to world transform.\n"
440
 
"\t\tRegenerated every frame from the camera's position and orientation.\n"
441
 
"\tworld_to_camera -> [[float]] (read only)\n"
442
 
"\t\tThis camera's world to camera transform.\n"
443
 
"\t\tRegenerated every frame from the camera's position and orientation.\n"
444
 
"\t\tThis is camera_to_world inverted.\n";
 
509
PyAttributeDef KX_Camera::Attributes[] = {
 
510
        
 
511
        KX_PYATTRIBUTE_BOOL_RW("frustum_culling", KX_Camera, m_frustum_culling),
 
512
        KX_PYATTRIBUTE_RW_FUNCTION("perspective", KX_Camera, pyattr_get_perspective, pyattr_set_perspective),
 
513
        
 
514
        KX_PYATTRIBUTE_RW_FUNCTION("lens",      KX_Camera,      pyattr_get_lens, pyattr_set_lens),
 
515
        KX_PYATTRIBUTE_RW_FUNCTION("near",      KX_Camera,      pyattr_get_near, pyattr_set_near),
 
516
        KX_PYATTRIBUTE_RW_FUNCTION("far",       KX_Camera,      pyattr_get_far,  pyattr_set_far),
 
517
        
 
518
        KX_PYATTRIBUTE_RW_FUNCTION("useViewport",       KX_Camera,      pyattr_get_use_viewport,  pyattr_set_use_viewport),
 
519
        
 
520
        KX_PYATTRIBUTE_RW_FUNCTION("projection_matrix", KX_Camera,      pyattr_get_projection_matrix, pyattr_set_projection_matrix),
 
521
        KX_PYATTRIBUTE_RO_FUNCTION("modelview_matrix",  KX_Camera,      pyattr_get_modelview_matrix),
 
522
        KX_PYATTRIBUTE_RO_FUNCTION("camera_to_world",   KX_Camera,      pyattr_get_camera_to_world),
 
523
        KX_PYATTRIBUTE_RO_FUNCTION("world_to_camera",   KX_Camera,      pyattr_get_world_to_camera),
 
524
        
 
525
        /* Grrr, functions for constants? */
 
526
        KX_PYATTRIBUTE_RO_FUNCTION("INSIDE",    KX_Camera, pyattr_get_INSIDE),
 
527
        KX_PYATTRIBUTE_RO_FUNCTION("OUTSIDE",   KX_Camera, pyattr_get_OUTSIDE),
 
528
        KX_PYATTRIBUTE_RO_FUNCTION("INTERSECT", KX_Camera, pyattr_get_INTERSECT),
 
529
        
 
530
        { NULL }        //Sentinel
 
531
};
445
532
 
446
533
PyTypeObject KX_Camera::Type = {
447
 
        PyObject_HEAD_INIT(&PyType_Type)
448
 
                0,
 
534
#if (PY_VERSION_HEX >= 0x02060000)
 
535
        PyVarObject_HEAD_INIT(NULL, 0)
 
536
#else
 
537
        /* python 2.5 and below */
 
538
        PyObject_HEAD_INIT( NULL )  /* required py macro */
 
539
        0,                          /* ob_size */
 
540
#endif
449
541
                "KX_Camera",
450
 
                sizeof(KX_Camera),
451
 
                0,
452
 
                PyDestructor,
453
 
                0,
454
 
                __getattr,
455
 
                __setattr,
456
 
                0, //&MyPyCompare,
457
 
                __repr,
458
 
                0, //&cvalue_as_number,
459
 
                0,
460
 
                0,
461
 
                0,
462
 
                0, 0, 0, 0, 0, 0,
463
 
                doc
 
542
                sizeof(PyObjectPlus_Proxy),
 
543
                0,
 
544
                py_base_dealloc,
 
545
                0,
 
546
                0,
 
547
                0,
 
548
                0,
 
549
                py_base_repr,
 
550
                0,
 
551
                &KX_GameObject::Sequence,
 
552
                &KX_GameObject::Mapping,
 
553
                0,0,0,
 
554
                py_base_getattro,
 
555
                py_base_setattro,
 
556
                0,
 
557
                Py_TPFLAGS_DEFAULT,
 
558
                0,0,0,0,0,0,0,
 
559
                Methods
464
560
};
465
561
 
 
562
 
 
563
 
 
564
 
 
565
 
 
566
 
466
567
PyParentObject KX_Camera::Parents[] = {
467
568
        &KX_Camera::Type,
468
569
        &KX_GameObject::Type,
471
572
                NULL
472
573
};
473
574
 
474
 
PyObject* KX_Camera::_getattr(const STR_String& attr)
475
 
{
476
 
        if (attr == "INSIDE")
477
 
                return PyInt_FromLong(INSIDE); /* new ref */
478
 
        if (attr == "OUTSIDE")
479
 
                return PyInt_FromLong(OUTSIDE); /* new ref */
480
 
        if (attr == "INTERSECT")
481
 
                return PyInt_FromLong(INTERSECT); /* new ref */
482
 
        
483
 
        if (attr == "lens")
484
 
                return PyFloat_FromDouble(GetLens()); /* new ref */
485
 
        if (attr == "near")
486
 
                return PyFloat_FromDouble(GetCameraNear()); /* new ref */
487
 
        if (attr == "far")
488
 
                return PyFloat_FromDouble(GetCameraFar()); /* new ref */
489
 
        if (attr == "frustum_culling")
490
 
                return PyInt_FromLong(m_frustum_culling); /* new ref */
491
 
        if (attr == "perspective")
492
 
                return PyInt_FromLong(m_camdata.m_perspective); /* new ref */
493
 
        if (attr == "projection_matrix")
494
 
                return PyObjectFrom(GetProjectionMatrix()); /* new ref */
495
 
        if (attr == "modelview_matrix")
496
 
                return PyObjectFrom(GetModelviewMatrix()); /* new ref */
497
 
        if (attr == "camera_to_world")
498
 
                return PyObjectFrom(GetCameraToWorld()); /* new ref */
499
 
        if (attr == "world_to_camera")
500
 
                return PyObjectFrom(GetWorldToCamera()); /* new ref */
501
 
        
502
 
        _getattr_up(KX_GameObject);
503
 
}
504
 
 
505
 
int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue)
506
 
{
507
 
        if (PyInt_Check(pyvalue))
508
 
        {
509
 
                if (attr == "frustum_culling")
510
 
                {
511
 
                        m_frustum_culling = PyInt_AsLong(pyvalue);
512
 
                        return 0;
513
 
                }
514
 
                
515
 
                if (attr == "perspective")
516
 
                {
517
 
                        m_camdata.m_perspective = PyInt_AsLong(pyvalue);
518
 
                        return 0;
519
 
                }
520
 
        }
521
 
        
522
 
        if (PyFloat_Check(pyvalue))
523
 
        {
524
 
                if (attr == "lens")
525
 
                {
526
 
                        m_camdata.m_lens = PyFloat_AsDouble(pyvalue);
527
 
                        m_set_projection_matrix = false;
528
 
                        return 0;
529
 
                }
530
 
                if (attr == "near")
531
 
                {
532
 
                        m_camdata.m_clipstart = PyFloat_AsDouble(pyvalue);
533
 
                        m_set_projection_matrix = false;
534
 
                        return 0;
535
 
                }
536
 
                if (attr == "far")
537
 
                {
538
 
                        m_camdata.m_clipend = PyFloat_AsDouble(pyvalue);
539
 
                        m_set_projection_matrix = false;
540
 
                        return 0;
541
 
                }
542
 
        }
543
 
        
544
 
        if (PyObject_IsMT_Matrix(pyvalue, 4))
545
 
        {
546
 
                if (attr == "projection_matrix")
547
 
                {
548
 
                        MT_Matrix4x4 mat;
549
 
                        if (PyMatTo(pyvalue, mat))
550
 
                        {
551
 
                                SetProjectionMatrix(mat);
552
 
                                return 0;
553
 
                        }
554
 
                        return 1;
555
 
                }
556
 
        }
557
 
        return KX_GameObject::_setattr(attr, pyvalue);
558
 
}
559
 
 
560
 
KX_PYMETHODDEF_DOC(KX_Camera, sphereInsideFrustum,
 
575
PyObject* KX_Camera::py_getattro(PyObject *attr)
 
576
{
 
577
        py_getattro_up(KX_GameObject);
 
578
}
 
579
 
 
580
PyObject* KX_Camera::py_getattro_dict() {
 
581
        py_getattro_dict_up(KX_GameObject);
 
582
}
 
583
 
 
584
int KX_Camera::py_setattro(PyObject *attr, PyObject *value)
 
585
{       
 
586
        py_setattro_up(KX_GameObject);
 
587
}
 
588
 
 
589
KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum,
561
590
"sphereInsideFrustum(center, radius) -> Integer\n"
562
591
"\treturns INSIDE, OUTSIDE or INTERSECT if the given sphere is\n"
563
592
"\tinside/outside/intersects this camera's viewing frustum.\n\n"
577
606
{
578
607
        PyObject *pycenter;
579
608
        float radius;
580
 
        if (PyArg_ParseTuple(args, "Of", &pycenter, &radius))
 
609
        if (PyArg_ParseTuple(args, "Of:sphereInsideFrustum", &pycenter, &radius))
581
610
        {
582
611
                MT_Point3 center;
583
612
                if (PyVecTo(pycenter, center))
586
615
                }
587
616
        }
588
617
 
589
 
        PyErr_SetString(PyExc_TypeError, "sphereInsideFrustum: Expected arguments: (center, radius)");
 
618
        PyErr_SetString(PyExc_TypeError, "camera.sphereInsideFrustum(center, radius): KX_Camera, expected arguments: (center, radius)");
590
619
        
591
620
        return NULL;
592
621
}
593
622
 
594
 
KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum,
 
623
KX_PYMETHODDEF_DOC_O(KX_Camera, boxInsideFrustum,
595
624
"boxInsideFrustum(box) -> Integer\n"
596
625
"\treturns INSIDE, OUTSIDE or INTERSECT if the given box is\n"
597
626
"\tinside/outside/intersects this camera's viewing frustum.\n\n"
616
645
"\t\t# Box is outside the frustum !\n"
617
646
)
618
647
{
619
 
        PyObject *pybox;
620
 
        if (PyArg_ParseTuple(args, "O", &pybox))
621
 
        {
622
 
                unsigned int num_points = PySequence_Size(pybox);
623
 
                if (num_points != 8)
624
 
                {
625
 
                        PyErr_Format(PyExc_TypeError, "boxInsideFrustum: Expected eight (8) points, got %d", num_points);
 
648
        unsigned int num_points = PySequence_Size(value);
 
649
        if (num_points != 8)
 
650
        {
 
651
                PyErr_Format(PyExc_TypeError, "camera.boxInsideFrustum(box): KX_Camera, expected eight (8) points, got %d", num_points);
 
652
                return NULL;
 
653
        }
 
654
        
 
655
        MT_Point3 box[8];
 
656
        for (unsigned int p = 0; p < 8 ; p++)
 
657
        {
 
658
                PyObject *item = PySequence_GetItem(value, p); /* new ref */
 
659
                bool error = !PyVecTo(item, box[p]);
 
660
                Py_DECREF(item);
 
661
                if (error)
626
662
                        return NULL;
627
 
                }
628
 
                
629
 
                MT_Point3 box[8];
630
 
                for (unsigned int p = 0; p < 8 ; p++)
631
 
                {
632
 
                        PyObject *item = PySequence_GetItem(pybox, p); /* new ref */
633
 
                        bool error = !PyVecTo(item, box[p]);
634
 
                        Py_DECREF(item);
635
 
                        if (error)
636
 
                                return NULL;
637
 
                }
638
 
                
639
 
                return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */
640
663
        }
641
664
        
642
 
        PyErr_SetString(PyExc_TypeError, "boxInsideFrustum: Expected argument: list of points.");
643
 
        return NULL;
 
665
        return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */
644
666
}
645
667
 
646
 
KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum,
 
668
KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum,
647
669
"pointInsideFrustum(point) -> Bool\n"
648
670
"\treturns 1 if the given point is inside this camera's viewing frustum.\n\n"
649
671
"\tpoint = The point to test (in world coordinates.)\n\n"
660
682
)
661
683
{
662
684
        MT_Point3 point;
663
 
        if (PyVecArgTo(args, point))
 
685
        if (PyVecTo(value, point))
664
686
        {
665
687
                return PyInt_FromLong(PointInsideFrustum(point)); /* new ref */
666
688
        }
667
689
        
668
 
        PyErr_SetString(PyExc_TypeError, "pointInsideFrustum: Expected point argument.");
 
690
        PyErr_SetString(PyExc_TypeError, "camera.pointInsideFrustum(point): KX_Camera, expected point argument.");
669
691
        return NULL;
670
692
}
671
693
 
672
 
KX_PYMETHODDEF_DOC(KX_Camera, getCameraToWorld,
 
694
KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getCameraToWorld,
673
695
"getCameraToWorld() -> Matrix4x4\n"
674
696
"\treturns the camera to world transformation matrix, as a list of four lists of four values.\n\n"
675
697
"\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n"
678
700
        return PyObjectFrom(GetCameraToWorld()); /* new ref */
679
701
}
680
702
 
681
 
KX_PYMETHODDEF_DOC(KX_Camera, getWorldToCamera,
 
703
KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getWorldToCamera,
682
704
"getWorldToCamera() -> Matrix4x4\n"
683
705
"\treturns the world to camera transformation matrix, as a list of four lists of four values.\n\n"
684
706
"\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n"
687
709
        return PyObjectFrom(GetWorldToCamera()); /* new ref */
688
710
}
689
711
 
690
 
KX_PYMETHODDEF_DOC(KX_Camera, getProjectionMatrix,
 
712
KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getProjectionMatrix,
691
713
"getProjectionMatrix() -> Matrix4x4\n"
692
714
"\treturns this camera's projection matrix, as a list of four lists of four values.\n\n"
693
715
"\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n"
694
716
)
695
717
{
 
718
        ShowDeprecationWarning("getProjectionMatrix()", "the projection_matrix property");
696
719
        return PyObjectFrom(GetProjectionMatrix()); /* new ref */
697
720
}
698
721
 
699
 
KX_PYMETHODDEF_DOC(KX_Camera, setProjectionMatrix,
 
722
KX_PYMETHODDEF_DOC_O(KX_Camera, setProjectionMatrix,
700
723
"setProjectionMatrix(MT_Matrix4x4 m) -> None\n"
701
724
"\tSets this camera's projection matrix\n"
702
725
"\n"
738
761
"\tcam = co.getOwner()\n"
739
762
"\tcam.setProjectionMatrix(Perspective(-1.0, 1.0, -1.0, 1.0, 0.1, 1))\n")
740
763
{
741
 
        PyObject *pymat;
742
 
        if (PyArg_ParseTuple(args, "O", &pymat))
 
764
        ShowDeprecationWarning("setProjectionMatrix(mat)", "the projection_matrix property");
 
765
        
 
766
        MT_Matrix4x4 mat;
 
767
        if (!PyMatTo(value, mat))
743
768
        {
744
 
                MT_Matrix4x4 mat;
745
 
                if (PyMatTo(pymat, mat))
746
 
                {
747
 
                        SetProjectionMatrix(mat);
748
 
                        Py_Return;
749
 
                }
 
769
                PyErr_SetString(PyExc_TypeError, "camera.setProjectionMatrix(matrix): KX_Camera, expected 4x4 list as matrix argument.");
 
770
                return NULL;
750
771
        }
751
 
 
752
 
        PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument.");
753
 
        return NULL;
 
772
        
 
773
        SetProjectionMatrix(mat);
 
774
        Py_RETURN_NONE;
754
775
}
755
776
 
756
 
KX_PYMETHODDEF_DOC(KX_Camera, enableViewport,
 
777
KX_PYMETHODDEF_DOC_O(KX_Camera, enableViewport,
757
778
"enableViewport(viewport)\n"
758
779
"Sets this camera's viewport status\n"
759
780
)
760
781
{
761
 
        int viewport;
762
 
        if (PyArg_ParseTuple(args,"i",&viewport))
763
 
        {
764
 
                if(viewport)
765
 
                        EnableViewport(true);
766
 
                else
767
 
                        EnableViewport(false);
768
 
        }
769
 
        else {
 
782
        ShowDeprecationWarning("enableViewport(bool)", "the useViewport property");
 
783
        
 
784
        int viewport = PyObject_IsTrue(value);
 
785
        if (viewport == -1) {
 
786
                PyErr_SetString(PyExc_ValueError, "camera.enableViewport(bool): KX_Camera, expected True/False or 0/1");
770
787
                return NULL;
771
788
        }
772
789
        
773
 
        Py_Return;
 
790
        if(viewport)
 
791
                EnableViewport(true);
 
792
        else
 
793
                EnableViewport(false);
 
794
        
 
795
        Py_RETURN_NONE;
774
796
}
775
797
 
776
 
KX_PYMETHODDEF_DOC(KX_Camera, setViewport,
 
798
KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, setViewport,
777
799
"setViewport(left, bottom, right, top)\n"
778
800
"Sets this camera's viewport\n")
779
801
{
780
802
        int left, bottom, right, top;
781
 
        if (PyArg_ParseTuple(args,"iiii",&left, &bottom, &right, &top))
782
 
        {
783
 
                SetViewport(left, bottom, right, top);
784
 
        } else {
 
803
        if (!PyArg_ParseTuple(args,"iiii:setViewport",&left, &bottom, &right, &top))
785
804
                return NULL;
786
 
        }
787
 
        Py_Return;
 
805
        
 
806
        SetViewport(left, bottom, right, top);
 
807
        Py_RETURN_NONE;
788
808
}
789
809
 
790
 
KX_PYMETHODDEF_DOC(KX_Camera, setOnTop,
 
810
KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, setOnTop,
791
811
"setOnTop()\n"
792
812
"Sets this camera's viewport on top\n")
793
813
{
794
 
        class KX_Scene* scene;
795
 
        
796
 
        scene = PHY_GetActiveScene();
797
 
        MT_assert(scene);
 
814
        class KX_Scene* scene = KX_GetActiveScene();
798
815
        scene->SetCameraOnTop(this);
799
 
        Py_Return;
800
 
}
 
816
        Py_RETURN_NONE;
 
817
}
 
818
 
 
819
PyObject* KX_Camera::pyattr_get_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
820
{
 
821
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
822
        return PyBool_FromLong(self->m_camdata.m_perspective);
 
823
}
 
824
 
 
825
int KX_Camera::pyattr_set_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 
826
{
 
827
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
828
        int param = PyObject_IsTrue( value );
 
829
        if (param == -1) {
 
830
                PyErr_SetString(PyExc_AttributeError, "camera.perspective = bool: KX_Camera, expected True/False or 0/1");
 
831
                return PY_SET_ATTR_FAIL;
 
832
        }
 
833
        
 
834
        self->m_camdata.m_perspective= param;
 
835
        return PY_SET_ATTR_SUCCESS;
 
836
}
 
837
 
 
838
PyObject* KX_Camera::pyattr_get_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
839
{
 
840
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
841
        return PyFloat_FromDouble(self->m_camdata.m_lens);
 
842
}
 
843
 
 
844
int KX_Camera::pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 
845
{
 
846
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
847
        float param = PyFloat_AsDouble(value);
 
848
        if (param == -1) {
 
849
                PyErr_SetString(PyExc_AttributeError, "camera.lens = float: KX_Camera, expected a float greater then zero");
 
850
                return PY_SET_ATTR_FAIL;
 
851
        }
 
852
        
 
853
        self->m_camdata.m_lens= param;
 
854
        self->m_set_projection_matrix = false;
 
855
        return PY_SET_ATTR_SUCCESS;
 
856
}
 
857
 
 
858
PyObject* KX_Camera::pyattr_get_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
859
{
 
860
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
861
        return PyFloat_FromDouble(self->m_camdata.m_clipstart);
 
862
}
 
863
 
 
864
int KX_Camera::pyattr_set_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 
865
{
 
866
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
867
        float param = PyFloat_AsDouble(value);
 
868
        if (param == -1) {
 
869
                PyErr_SetString(PyExc_AttributeError, "camera.near = float: KX_Camera, expected a float greater then zero");
 
870
                return PY_SET_ATTR_FAIL;
 
871
        }
 
872
        
 
873
        self->m_camdata.m_clipstart= param;
 
874
        self->m_set_projection_matrix = false;
 
875
        return PY_SET_ATTR_SUCCESS;
 
876
}
 
877
 
 
878
PyObject* KX_Camera::pyattr_get_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
879
{
 
880
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
881
        return PyFloat_FromDouble(self->m_camdata.m_clipend);
 
882
}
 
883
 
 
884
int KX_Camera::pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 
885
{
 
886
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
887
        float param = PyFloat_AsDouble(value);
 
888
        if (param == -1) {
 
889
                PyErr_SetString(PyExc_AttributeError, "camera.far = float: KX_Camera, expected a float greater then zero");
 
890
                return PY_SET_ATTR_FAIL;
 
891
        }
 
892
        
 
893
        self->m_camdata.m_clipend= param;
 
894
        self->m_set_projection_matrix = false;
 
895
        return PY_SET_ATTR_SUCCESS;
 
896
}
 
897
 
 
898
 
 
899
PyObject* KX_Camera::pyattr_get_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
900
{
 
901
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
902
        return PyBool_FromLong(self->GetViewport());
 
903
}
 
904
 
 
905
int KX_Camera::pyattr_set_use_viewport(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 
906
{
 
907
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
908
        int param = PyObject_IsTrue( value );
 
909
        if (param == -1) {
 
910
                PyErr_SetString(PyExc_AttributeError, "camera.useViewport = bool: KX_Camera, expected True or False");
 
911
                return PY_SET_ATTR_FAIL;
 
912
        }
 
913
        self->EnableViewport((bool)param);
 
914
        return PY_SET_ATTR_SUCCESS;
 
915
}
 
916
 
 
917
 
 
918
PyObject* KX_Camera::pyattr_get_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
919
{
 
920
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
921
        return PyObjectFrom(self->GetProjectionMatrix()); 
 
922
}
 
923
 
 
924
int KX_Camera::pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 
925
{
 
926
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
927
        MT_Matrix4x4 mat;
 
928
        if (!PyMatTo(value, mat)) 
 
929
                return PY_SET_ATTR_FAIL;
 
930
        
 
931
        self->SetProjectionMatrix(mat);
 
932
        return PY_SET_ATTR_SUCCESS;
 
933
}
 
934
 
 
935
PyObject* KX_Camera::pyattr_get_modelview_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
936
{
 
937
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
938
        return PyObjectFrom(self->GetModelviewMatrix()); 
 
939
}
 
940
 
 
941
PyObject* KX_Camera::pyattr_get_camera_to_world(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
942
{
 
943
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
944
        return PyObjectFrom(self->GetCameraToWorld());
 
945
}
 
946
 
 
947
PyObject* KX_Camera::pyattr_get_world_to_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
948
{
 
949
        KX_Camera* self= static_cast<KX_Camera*>(self_v);
 
950
        return PyObjectFrom(self->GetWorldToCamera()); 
 
951
}
 
952
 
 
953
 
 
954
PyObject* KX_Camera::pyattr_get_INSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
955
{       return PyInt_FromLong(INSIDE); }
 
956
PyObject* KX_Camera::pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
957
{       return PyInt_FromLong(OUTSIDE); }
 
958
PyObject* KX_Camera::pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 
959
{       return PyInt_FromLong(INTERSECT); }
 
960
 
 
961
 
 
962
bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix)
 
963
{
 
964
        if (value==NULL) {
 
965
                PyErr_Format(PyExc_TypeError, "%s, python pointer NULL, should never happen", error_prefix);
 
966
                *object = NULL;
 
967
                return false;
 
968
        }
 
969
                
 
970
        if (value==Py_None) {
 
971
                *object = NULL;
 
972
                
 
973
                if (py_none_ok) {
 
974
                        return true;
 
975
                } else {
 
976
                        PyErr_Format(PyExc_TypeError, "%s, expected KX_Camera or a KX_Camera name, None is invalid", error_prefix);
 
977
                        return false;
 
978
                }
 
979
        }
 
980
        
 
981
        if (PyString_Check(value)) {
 
982
                STR_String value_str = PyString_AsString(value);
 
983
                *object = KX_GetActiveScene()->FindCamera(value_str);
 
984
                
 
985
                if (*object) {
 
986
                        return true;
 
987
                } else {
 
988
                        PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, PyString_AsString(value));
 
989
                        return false;
 
990
                }
 
991
        }
 
992
        
 
993
        if (PyObject_TypeCheck(value, &KX_Camera::Type)) {
 
994
                *object = static_cast<KX_Camera*>BGE_PROXY_REF(value);
 
995
                
 
996
                /* sets the error */
 
997
                if (*object==NULL) {
 
998
                        PyErr_Format(PyExc_SystemError, "%s, " BGE_PROXY_ERROR_MSG, error_prefix);
 
999
                        return false;
 
1000
                }
 
1001
                
 
1002
                return true;
 
1003
        }
 
1004
        
 
1005
        *object = NULL;
 
1006
        
 
1007
        if (py_none_ok) {
 
1008
                PyErr_Format(PyExc_TypeError, "%s, expect a KX_Camera, a string or None", error_prefix);
 
1009
        } else {
 
1010
                PyErr_Format(PyExc_TypeError, "%s, expect a KX_Camera or a string", error_prefix);
 
1011
        }
 
1012
        
 
1013
        return false;
 
1014
}
 
1015
 
 
1016
KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition,
 
1017
"getScreenPosition()\n"
 
1018
)
 
1019
 
 
1020
{
 
1021
        MT_Vector3 vect;
 
1022
        KX_GameObject *obj = NULL;
 
1023
 
 
1024
        if (!PyVecTo(value, vect))
 
1025
        {
 
1026
                if(ConvertPythonToGameObject(value, &obj, true, ""))
 
1027
                {
 
1028
                        PyErr_Clear();
 
1029
                        vect = MT_Vector3(obj->NodeGetWorldPosition());
 
1030
                }
 
1031
                else
 
1032
                {
 
1033
                        PyErr_SetString(PyExc_TypeError, "Error in getScreenPosition. Expected a Vector3 or a KX_GameObject or a string for a name of a KX_GameObject");
 
1034
                        return NULL;
 
1035
                }
 
1036
        }
 
1037
 
 
1038
        GLint viewport[4];
 
1039
        GLdouble win[3];
 
1040
        GLdouble modelmatrix[16];
 
1041
        GLdouble projmatrix[16];
 
1042
 
 
1043
        MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix();
 
1044
        MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
 
1045
 
 
1046
        m_modelmatrix.getValue(modelmatrix);
 
1047
        m_projmatrix.getValue(projmatrix);
 
1048
 
 
1049
        glGetIntegerv(GL_VIEWPORT, viewport);
 
1050
 
 
1051
        gluProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]);
 
1052
 
 
1053
        vect[0] =  (win[0] - viewport[0]) / viewport[2];
 
1054
        vect[1] =  (win[1] - viewport[1]) / viewport[3];
 
1055
 
 
1056
        vect[1] = 1.0 - vect[1]; //to follow Blender window coordinate system (Top-Down)
 
1057
 
 
1058
        PyObject* ret = PyTuple_New(2);
 
1059
        if(ret){
 
1060
                PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(vect[0]));
 
1061
                PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(vect[1]));
 
1062
                return ret;
 
1063
        }
 
1064
 
 
1065
        return NULL;
 
1066
}
 
1067
 
 
1068
KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect,
 
1069
"getScreenVect()\n"
 
1070
)
 
1071
{
 
1072
        double x,y;
 
1073
        if (!PyArg_ParseTuple(args,"dd:getScreenVect",&x,&y))
 
1074
                return NULL;
 
1075
 
 
1076
        y = 1.0 - y; //to follow Blender window coordinate system (Top-Down)
 
1077
 
 
1078
        MT_Vector3 vect;
 
1079
        MT_Point3 campos, screenpos;
 
1080
 
 
1081
        GLint viewport[4];
 
1082
        GLdouble win[3];
 
1083
        GLdouble modelmatrix[16];
 
1084
        GLdouble projmatrix[16];
 
1085
 
 
1086
        MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix();
 
1087
        MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
 
1088
 
 
1089
        m_modelmatrix.getValue(modelmatrix);
 
1090
        m_projmatrix.getValue(projmatrix);
 
1091
 
 
1092
        glGetIntegerv(GL_VIEWPORT, viewport);
 
1093
 
 
1094
        vect[0] = x * viewport[2];
 
1095
        vect[1] = y * viewport[3];
 
1096
 
 
1097
        vect[0] += viewport[0];
 
1098
        vect[1] += viewport[1];
 
1099
 
 
1100
        glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vect[2]);
 
1101
        gluUnProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]);
 
1102
 
 
1103
        campos = this->GetCameraLocation();
 
1104
        screenpos = MT_Point3(win[0], win[1], win[2]);
 
1105
        vect = campos-screenpos;
 
1106
 
 
1107
        vect.normalize();
 
1108
        return PyObjectFrom(vect);
 
1109
}
 
1110
 
 
1111
KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenRay,
 
1112
"getScreenRay()\n"
 
1113
)
 
1114
{
 
1115
        MT_Vector3 vect;
 
1116
        double x,y,dist;
 
1117
        char *propName = NULL;
 
1118
 
 
1119
        if (!PyArg_ParseTuple(args,"ddd|s:getScreenRay",&x,&y,&dist,&propName))
 
1120
                return NULL;
 
1121
 
 
1122
        PyObject* argValue = PyTuple_New(2);
 
1123
        if (argValue) {
 
1124
                PyTuple_SET_ITEM(argValue, 0, PyFloat_FromDouble(x));
 
1125
                PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(y));
 
1126
        }
 
1127
 
 
1128
        if(!PyVecTo(PygetScreenVect(argValue), vect))
 
1129
        {
 
1130
                Py_DECREF(argValue);
 
1131
                PyErr_SetString(PyExc_TypeError,
 
1132
                        "Error in getScreenRay. Invalid 2D coordinate. Expected a normalized 2D screen coordinate, a distance and an optional property argument");
 
1133
                return NULL;
 
1134
        }
 
1135
        Py_DECREF(argValue);
 
1136
 
 
1137
        dist = -dist;
 
1138
        vect += this->GetCameraLocation();
 
1139
 
 
1140
        argValue = (propName?PyTuple_New(3):PyTuple_New(2));
 
1141
        if (argValue) {
 
1142
                PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect));
 
1143
                PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist));
 
1144
                if (propName)
 
1145
                        PyTuple_SET_ITEM(argValue, 2, PyString_FromString(propName));
 
1146
 
 
1147
                PyObject* ret= this->PyrayCastTo(argValue,NULL);
 
1148
                Py_DECREF(argValue);
 
1149
                return ret;
 
1150
        }
 
1151
 
 
1152
        return NULL;
 
1153
}
 
1154