This file is indexed.

/usr/share/pyshared/collada/camera.py is in python-collada 0.4-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
####################################################################
#                                                                  #
# THIS FILE IS PART OF THE pycollada LIBRARY SOURCE CODE.          #
# USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     #
# GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE #
# IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       #
#                                                                  #
# THE pycollada SOURCE CODE IS (C) COPYRIGHT 2011                  #
# by Jeff Terrace and contributors                                 #
#                                                                  #
####################################################################

"""Contains objects for representing cameras"""

import numpy

from collada.common import DaeObject, E, tag
from collada.common import DaeIncompleteError, DaeBrokenRefError, \
        DaeMalformedError
from collada.xmlutil import etree as ElementTree


class Camera(DaeObject):
    """Base camera class holding data from <camera> tags."""

    @staticmethod
    def load(collada, localscope, node):
        tecnode = node.find('%s/%s' % (tag('optics'),tag('technique_common')))
        if tecnode is None or len(tecnode) == 0:
            raise DaeIncompleteError('Missing common technique in camera')
        camnode = tecnode[0]
        if camnode.tag == tag('perspective'):
            return PerspectiveCamera.load(collada, localscope, node)
        elif camnode.tag == tag('orthographic'):
            return OrthographicCamera.load(collada, localscope, node)
        else:
            raise DaeUnsupportedError('Unrecognized camera type: %s' % camnode.tag)


class PerspectiveCamera(Camera):
    """Perspective camera as defined in COLLADA tag <perspective>."""

    def __init__(self, id, znear, zfar, xfov=None, yfov=None,
            aspect_ratio=None, xmlnode = None):
        """Create a new perspective camera.

        Note: ``aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov)``

        You can specify one of:
         * :attr:`xfov` alone
         * :attr:`yfov` alone
         * :attr:`xfov` and :attr:`yfov`
         * :attr:`xfov` and :attr:`aspect_ratio`
         * :attr:`yfov` and :attr:`aspect_ratio`

        Any other combination will raise :class:`collada.common.DaeMalformedError`

        :param str id:
          Identifier for the camera
        :param float znear:
          Distance to the near clipping plane
        :param float zfar:
          Distance to the far clipping plane
        :param float xfov:
          Horizontal field of view, in degrees
        :param float yfov:
          Vertical field of view, in degrees
        :param float aspect_ratio:
          Aspect ratio of the field of view
        :param xmlnode:
          If loaded from xml, the xml node

        """

        self.id = id
        """Identifier for the camera"""
        self.xfov = xfov
        """Horizontal field of view, in degrees"""
        self.yfov = yfov
        """Vertical field of view, in degrees"""
        self.aspect_ratio = aspect_ratio
        """Aspect ratio of the field of view"""
        self.znear = znear
        """Distance to the near clipping plane"""
        self.zfar = zfar
        """Distance to the far clipping plane"""

        self._checkValidParams()

        if xmlnode is not  None:
            self.xmlnode = xmlnode
            """ElementTree representation of the data."""
        else:
            self._recreateXmlNode()

    def _recreateXmlNode(self):
        perspective_node = E.perspective()
        if self.xfov is not None:
            perspective_node.append(E.xfov(str(self.xfov)))
        if self.yfov is not None:
            perspective_node.append(E.yfov(str(self.yfov)))
        if self.aspect_ratio is not None:
            perspective_node.append(E.aspect_ratio(str(self.aspect_ratio)))
        perspective_node.append(E.znear(str(self.znear)))
        perspective_node.append(E.zfar(str(self.zfar)))
        self.xmlnode = E.camera(
            E.optics(
                E.technique_common(perspective_node)
            )
        , id=self.id, name=self.id)

    def _checkValidParams(self):
        if self.xfov is not None and self.yfov is None \
                and self.aspect_ratio is None:
            pass
        elif self.xfov is None and self.yfov is not None \
                and self.aspect_ratio is None:
            pass
        elif self.xfov is not None and self.yfov is None \
                and self.aspect_ratio is not None:
            pass
        elif self.xfov is None and self.yfov is not None \
                and self.aspect_ratio is not None:
            pass
        elif self.xfov is not None and self.yfov is not None \
                and self.aspect_ratio is None:
            pass
        else:
            raise DaeMalformedError("Received invalid combination of xfov (%s), yfov (%s), and aspect_ratio (%s)" %
                    (str(self.xfov), str(self.yfov), str(self.aspect_ratio)))

    def save(self):
        """Saves the perspective camera's properties back to xmlnode"""
        self._checkValidParams()
        self._recreateXmlNode()


    @staticmethod
    def load(collada, localscope, node):
        persnode = node.find( '%s/%s/%s'%(tag('optics'),tag('technique_common'),
            tag('perspective') ))

        if persnode is None:
            raise DaeIncompleteError('Missing perspective for camera definition')

        xfov = persnode.find( tag('xfov') )
        yfov = persnode.find( tag('yfov') )
        aspect_ratio = persnode.find( tag('aspect_ratio') )
        znearnode = persnode.find( tag('znear') )
        zfarnode = persnode.find( tag('zfar') )
        id = node.get('id', '')

        try:
            if xfov is not None:
                xfov = float(xfov.text)
            if yfov is not None:
                yfov = float(yfov.text)
            if aspect_ratio is not None:
                aspect_ratio = float(aspect_ratio.text)
            znear = float(znearnode.text)
            zfar = float(zfarnode.text)
        except (TypeError, ValueError) as ex:
            raise DaeMalformedError('Corrupted float values in camera definition')

        #There are some exporters that incorrectly output all three of these.
        # Worse, they actually got the caculation of aspect_ratio wrong!
        # So instead of failing to load, let's just add one more hack because of terrible exporters
        if xfov is not None and yfov is not None and aspect_ratio is not None:
            aspect_ratio = None

        return PerspectiveCamera(id, znear, zfar, xfov=xfov, yfov=yfov,
                aspect_ratio=aspect_ratio, xmlnode=node)

    def bind(self, matrix):
        """Create a bound camera of itself based on a transform matrix.

        :param numpy.array matrix:
          A numpy transformation matrix of size 4x4

        :rtype: :class:`collada.camera.BoundPerspectiveCamera`

        """
        return BoundPerspectiveCamera(self, matrix)

    def __str__(self): return '<PerspectiveCamera id=%s>' % self.id
    def __repr__(self): return str(self)

class OrthographicCamera(Camera):
    """Orthographic camera as defined in COLLADA tag <orthographic>."""

    def __init__(self, id, znear, zfar, xmag=None, ymag=None, aspect_ratio=None, xmlnode = None):
        """Create a new orthographic camera.

        Note: ``aspect_ratio = xmag / ymag``

        You can specify one of:
         * :attr:`xmag` alone
         * :attr:`ymag` alone
         * :attr:`xmag` and :attr:`ymag`
         * :attr:`xmag` and :attr:`aspect_ratio`
         * :attr:`ymag` and :attr:`aspect_ratio`

        Any other combination will raise :class:`collada.common.DaeMalformedError`

        :param str id:
          Identifier for the camera
        :param float znear:
          Distance to the near clipping plane
        :param float zfar:
          Distance to the far clipping plane
        :param float xmag:
          Horizontal magnification of the view
        :param float ymag:
          Vertical magnification of the view
        :param float aspect_ratio:
          Aspect ratio of the field of view
        :param xmlnode:
          If loaded from xml, the xml node

        """

        self.id = id
        """Identifier for the camera"""
        self.xmag = xmag
        """Horizontal magnification of the view"""
        self.ymag = ymag
        """Vertical magnification of the view"""
        self.aspect_ratio = aspect_ratio
        """Aspect ratio of the field of view"""
        self.znear = znear
        """Distance to the near clipping plane"""
        self.zfar = zfar
        """Distance to the far clipping plane"""

        self._checkValidParams()

        if xmlnode is not  None:
            self.xmlnode = xmlnode
            """ElementTree representation of the data."""
        else:
            self._recreateXmlNode()

    def _recreateXmlNode(self):
        orthographic_node = E.orthographic()
        if self.xmag is not None:
            orthographic_node.append(E.xmag(str(self.xmag)))
        if self.ymag is not None:
            orthographic_node.append(E.ymag(str(self.ymag)))
        if self.aspect_ratio is not None:
            orthographic_node.append(E.aspect_ratio(str(self.aspect_ratio)))
        orthographic_node.append(E.znear(str(self.znear)))
        orthographic_node.append(E.zfar(str(self.zfar)))
        self.xmlnode = E.camera(
            E.optics(
                E.technique_common(orthographic_node)
            )
        , id=self.id, name=self.id)

    def _checkValidParams(self):
        if self.xmag is not None and self.ymag is None \
                and self.aspect_ratio is None:
            pass
        elif self.xmag is None and self.ymag is not None \
                and self.aspect_ratio is None:
            pass
        elif self.xmag is not None and self.ymag is None \
                and self.aspect_ratio is not None:
            pass
        elif self.xmag is None and self.ymag is not None \
                and self.aspect_ratio is not None:
            pass
        elif self.xmag is not None and self.ymag is not None \
                and self.aspect_ratio is None:
            pass
        else:
            raise DaeMalformedError("Received invalid combination of xmag (%s), ymag (%s), and aspect_ratio (%s)" %
                    (str(self.xmag), str(self.ymag), str(self.aspect_ratio)))

    def save(self):
        """Saves the orthographic camera's properties back to xmlnode"""
        self._checkValidParams()
        self._recreateXmlNode()


    @staticmethod
    def load(collada, localscope, node):
        orthonode = node.find('%s/%s/%s' % (
            tag('optics'),
            tag('technique_common'),
            tag('orthographic')))

        if orthonode is None: raise DaeIncompleteError('Missing orthographic for camera definition')

        xmag = orthonode.find( tag('xmag') )
        ymag = orthonode.find( tag('ymag') )
        aspect_ratio = orthonode.find( tag('aspect_ratio') )
        znearnode = orthonode.find( tag('znear') )
        zfarnode = orthonode.find( tag('zfar') )
        id = node.get('id', '')

        try:
            if xmag is not None:
                xmag = float(xmag.text)
            if ymag is not None:
                ymag = float(ymag.text)
            if aspect_ratio is not None:
                aspect_ratio = float(aspect_ratio.text)
            znear = float(znearnode.text)
            zfar = float(zfarnode.text)
        except (TypeError, ValueError) as ex:
            raise DaeMalformedError('Corrupted float values in camera definition')

        #There are some exporters that incorrectly output all three of these.
        # Worse, they actually got the caculation of aspect_ratio wrong!
        # So instead of failing to load, let's just add one more hack because of terrible exporters
        if xmag is not None and ymag is not None and aspect_ratio is not None:
            aspect_ratio = None

        return OrthographicCamera(id, znear, zfar, xmag=xmag, ymag=ymag,
                aspect_ratio=aspect_ratio, xmlnode=node)

    def bind(self, matrix):
        """Create a bound camera of itself based on a transform matrix.

        :param numpy.array matrix:
          A numpy transformation matrix of size 4x4

        :rtype: :class:`collada.camera.BoundOrthographicCamera`

        """
        return BoundOrthographicCamera(self, matrix)

    def __str__(self):
        return '<OrthographicCamera id=%s>' % self.id

    def __repr__(self):
        return str(self)

class BoundCamera(object):
    """Base class for bound cameras"""
    pass

class BoundPerspectiveCamera(BoundCamera):
    """Perspective camera bound to a scene with a transform. This gets created when a
        camera is instantiated in a scene. Do not create this manually."""

    def __init__(self, cam, matrix):
        self.xfov = cam.xfov
        """Horizontal field of view, in degrees"""
        self.yfov = cam.yfov
        """Vertical field of view, in degrees"""
        self.aspect_ratio = cam.aspect_ratio
        """Aspect ratio of the field of view"""
        self.znear = cam.znear
        """Distance to the near clipping plane"""
        self.zfar = cam.zfar
        """Distance to the far clipping plane"""
        self.matrix = matrix
        """The matrix bound to"""
        self.position = matrix[:3,3]
        """The position of the camera"""
        self.direction = -matrix[:3,2]
        """The direction the camera is facing"""
        self.up = matrix[:3,1]
        """The up vector of the camera"""
        self.original = cam
        """Original :class:`collada.camera.PerspectiveCamera` object this is bound to."""

    def __str__(self):
        return '<BoundPerspectiveCamera bound to %s>' % self.original.id

    def __repr__(self):
        return str(self)

class BoundOrthographicCamera(BoundCamera):
    """Orthographic camera bound to a scene with a transform. This gets created when a
        camera is instantiated in a scene. Do not create this manually."""

    def __init__(self, cam, matrix):
        self.xmag = cam.xmag
        """Horizontal magnification of the view"""
        self.ymag = cam.ymag
        """Vertical magnification of the view"""
        self.aspect_ratio = cam.aspect_ratio
        """Aspect ratio of the field of view"""
        self.znear = cam.znear
        """Distance to the near clipping plane"""
        self.zfar = cam.zfar
        """Distance to the far clipping plane"""
        self.matrix = matrix
        """The matrix bound to"""
        self.position = matrix[:3,3]
        """The position of the camera"""
        self.direction = -matrix[:3,2]
        """The direction the camera is facing"""
        self.up = matrix[:3,1]
        """The up vector of the camera"""
        self.original = cam
        """Original :class:`collada.camera.OrthographicCamera` object this is bound to."""

    def __str__(self):
        return '<BoundOrthographicCamera bound to %s>' % self.original.id

    def __repr__(self):
        return str(self)