Ejemplo n.º 1
0
class Node(Editable):
    FLAG_NO_TRANSLATE = 0x1
    FLAG_NO_ROTATE = 0x2
    FLAG_NO_SCALE = 0x4
    FLAG_NO_PIVOT = 0x8
    FLAG_PIVOT_REVC = 0x200
    FLAG_PIVOT_REVD = 0x400

    def define(self):
        self.uint16('flag_')
        for i in range(3):
            for j in range(3):
                self.int16('rot_{0}{1}_fx16'.format(i, j),
                           default=int(i == j) * 4096)
        self.int32('trans_x_fx32')
        self.int32('trans_y_fx32')
        self.int32('trans_z_fx32')
        self.int16('pivot_a_fx16')
        self.int16('pivot_b_fx16')
        self.int32('scale_x_fx32', default=4096)
        self.int32('scale_y_fx32', default=4096)
        self.int32('scale_z_fx32', default=4096)
        self.int32('inv_scale_x_fx32', default=4096)
        self.int32('inv_scale_y_fx32', default=4096)
        self.int32('inv_scale_z_fx32', default=4096)

    def load(self, reader):
        reader = BinaryIO.reader(reader)
        self.flag_ = reader.readUInt16()
        self.rot_00_fx16 = reader.readInt16()
        if self.flag_ & self.FLAG_NO_TRANSLATE:
            self.trans_x_fx32 = 0
            self.trans_y_fx32 = 0
            self.trans_z_fx32 = 0
        else:
            self.trans_x_fx32 = reader.readInt32()
            self.trans_y_fx32 = reader.readInt32()
            self.trans_z_fx32 = reader.readInt32()
        if self.flag_ & self.FLAG_NO_ROTATE:
            for i in range(3):
                for j in range(3):
                    setattr(self, 'rot_{0}{1}_fx16'.format(i, j),
                            int(i == j) * 4096)
        elif self.flag_ & self.FLAG_NO_PIVOT:
            self.rot_01_fx16 = reader.readInt16()
            self.rot_02_fx16 = reader.readInt16()
            self.rot_10_fx16 = reader.readInt16()
            self.rot_11_fx16 = reader.readInt16()
            self.rot_12_fx16 = reader.readInt16()
            self.rot_20_fx16 = reader.readInt16()
            self.rot_21_fx16 = reader.readInt16()
            self.rot_22_fx16 = reader.readInt16()
        else:
            for i in range(3):
                for j in range(3):
                    setattr(self, 'rot_{0}{1}_fx16'.format(i, j),
                            int(i == j) * 4096)
            self.pivot_a_fx16 = reader.readInt16()
            self.pivot_b_fx16 = reader.readInt16()
            pivot = (self.flag_ >> 4) & 0xf
            if self.flag_ & self.FLAG_PIVOT_REVC:
                pivoc_c = -self.pivot_b_fx16
            else:
                pivoc_c = self.pivot_b_fx16
            if self.flag_ & self.FLAG_PIVOT_REVD:
                pivoc_d = -self.pivot_a_fx16
            else:
                pivoc_d = self.pivot_a_fx16
            if pivot == 0:
                self.rot_11_fx16 = self.pivot_a_fx16
                self.rot_12_fx16 = self.pivot_b_fx16
                self.rot_21_fx16 = pivoc_c
                self.rot_22_fx16 = pivoc_d
            elif pivot == 4:
                self.rot_00_fx16 = self.pivot_a_fx16
                self.rot_02_fx16 = self.pivot_b_fx16
                self.rot_20_fx16 = pivoc_c
                self.rot_22_fx16 = pivoc_d
            elif pivot == 8:
                self.rot_00_fx16 = self.pivot_a_fx16
                self.rot_01_fx16 = self.pivot_b_fx16
                self.rot_10_fx16 = pivoc_c
                self.rot_11_fx16 = pivoc_d
            else:
                raise NotImplementedError(
                    'Pivot {0} is not supported'.format(pivot))

        if self.flag_ & self.FLAG_NO_SCALE:
            self.scale_x_fx32 = 4096
            self.scale_y_fx32 = 4096
            self.scale_z_fx32 = 4096
            self.inv_scale_x_fx32 = 4096
            self.inv_scale_y_fx32 = 4096
            self.inv_scale_z_fx32 = 4096
        else:
            self.scale_x_fx32 = reader.readInt32()
            self.scale_y_fx32 = reader.readInt32()
            self.scale_z_fx32 = reader.readInt32()
            self.inv_scale_x_fx32 = reader.readInt32()
            self.inv_scale_y_fx32 = reader.readInt32()
            self.inv_scale_z_fx32 = reader.readInt32()

    def save(self, writer):
        writer = BinaryIO.writer(writer)
        flag = self.flag
        writer.writeUInt16(flag)
        writer.writeInt16(self.rot_00_fx16)
        if not (self.flag & self.FLAG_NO_TRANSLATE):
            writer.writeInt32(self.trans_x_fx32)
            writer.writeInt32(self.trans_y_fx32)
            writer.writeInt32(self.trans_z_fx32)
        if not (self.flag & self.FLAG_NO_ROTATE):
            writer.writeInt16(self.rot_01_fx16)
            writer.writeInt16(self.rot_02_fx16)
            writer.writeInt16(self.rot_10_fx16)
            writer.writeInt16(self.rot_11_fx16)
            writer.writeInt16(self.rot_20_fx16)
            writer.writeInt16(self.rot_21_fx16)
            writer.writeInt16(self.rot_22_fx16)
        if not (self.flag & self.FLAG_NO_SCALE):
            try:
                self.inv_scale_x = 1 / self.scale_x
            except ZeroDivisionError:
                self.inv_scale_x = 0.0
            try:
                self.inv_scale_y = 1 / self.scale_y
            except ZeroDivisionError:
                self.inv_scale_y = 0.0
            try:
                self.inv_scale_z = 1 / self.scale_z
            except ZeroDivisionError:
                self.inv_scale_z = 0.0
            writer.writeInt32(self.scale_x_fx32)
            writer.writeInt32(self.scale_y_fx32)
            writer.writeInt32(self.scale_z_fx32)
            writer.writeInt32(self.inv_scale_x_fx32)
            writer.writeInt32(self.inv_scale_y_fx32)
            writer.writeInt32(self.inv_scale_z_fx32)
        return writer

    @property
    def flag(self):
        flag = 0
        if not self.trans_x_fx32 and not self.trans_y_fx32 and\
                not self.trans_z_fx32:
            flag |= self.FLAG_NO_TRANSLATE
        for i in range(3):
            for j in range(3):
                if getattr(self, 'rot_{0}{1}_fx16'.format(i, j))\
                        != int(i == j)*4096:
                    break
            else:
                continue
            break
        else:
            flag |= self.FLAG_NO_ROTATE
        flag |= self.FLAG_NO_PIVOT
        if self.scale_x_fx32 == 4096 and self.scale_y_fx32 == 4096\
                and self.scale_z_fx32 == 4096:
            flag |= self.FLAG_NO_SCALE
            # TODO: make sure inv_scale match
        return flag

    @flag.setter
    def flag(self, value):
        self.flag_ = value

    trans_x = Editable.fx_property('trans_x_fx32')
    trans_y = Editable.fx_property('trans_y_fx32')
    trans_z = Editable.fx_property('trans_z_fx32')
    pivot_a = Editable.fx_property('pivot_a_fx16')
    pivot_b = Editable.fx_property('pivot_b_fx16')
    scale_x = Editable.fx_property('scale_x_fx32')
    scale_y = Editable.fx_property('scale_y_fx32')
    scale_z = Editable.fx_property('scale_z_fx32')
    inv_scale_x = Editable.fx_property('inv_scale_x_fx32')
    inv_scale_y = Editable.fx_property('inv_scale_y_fx32')
    inv_scale_z = Editable.fx_property('inv_scale_z_fx32')
Ejemplo n.º 2
0
    trans_y = Editable.fx_property('trans_y_fx32')
    trans_z = Editable.fx_property('trans_z_fx32')
    pivot_a = Editable.fx_property('pivot_a_fx16')
    pivot_b = Editable.fx_property('pivot_b_fx16')
    scale_x = Editable.fx_property('scale_x_fx32')
    scale_y = Editable.fx_property('scale_y_fx32')
    scale_z = Editable.fx_property('scale_z_fx32')
    inv_scale_x = Editable.fx_property('inv_scale_x_fx32')
    inv_scale_y = Editable.fx_property('inv_scale_y_fx32')
    inv_scale_z = Editable.fx_property('inv_scale_z_fx32')


for i in range(3):
    for j in range(3):
        setattr(Node, 'rot_{0}{1}'.format(i, j),
                Editable.fx_property('rot_{0}{1}_fx16'.format(i, j)))


class NodeSet(object):
    def __init__(self):
        self.nodedict = G3DResDict()
        self.nodes = []

    def load(self, reader):
        start = reader.tell()
        self.nodedict.load(reader)
        self.nodes = []
        for i in range(self.nodedict.num):
            ofs, = struct.unpack('I', self.nodedict.data[i])
            reader.seek(start + ofs)
            self.nodes.append(Node(reader=reader))