forked from K0lb3/UnityPy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAnimationClip.c
More file actions
150 lines (135 loc) · 4.11 KB
/
Copy pathAnimationClip.c
File metadata and controls
150 lines (135 loc) · 4.11 KB
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
#include "AnimationClip.h"
#include <Python.h>
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
/* AnimationClip.py */
static float *UnpackFloats(uint32_t m_NumItems, float m_Range, float m_Start, uint8_t *m_Data, char m_BitSize, int itemCountInChunk, int chunkStride, int start, int numChunks)
{
int bitPos = m_BitSize * start;
int indexPos = bitPos / 8;
bitPos %= 8;
float scale = 1.0f / m_Range;
if (numChunks == -1)
numChunks = (int)m_NumItems / itemCountInChunk;
// TODO: might be better to use ulong instead of uint
uint32_t end = chunkStride * numChunks / 4;
// TODO: check if this is correct
float *data = (float *)malloc(sizeof(float) * numChunks * itemCountInChunk);
float *dataStart = data;
for (uint32_t index = 0; index != end; index += chunkStride / 4)
{
for (int i = 0; i < itemCountInChunk; ++i)
{
uint32_t x = 0;
int bits = 0;
while (bits < m_BitSize)
{
x |= (uint32_t)((m_Data[indexPos] >> bitPos) << bits);
int num = MIN(m_BitSize - bits, 8 - bitPos);
bitPos += num;
bits += num;
if (bitPos == 8)
{
indexPos++;
bitPos = 0;
}
}
x &= (uint32_t)(1 << m_BitSize) - 1u;
*data++ = (x / (scale * ((1 << m_BitSize) - 1)) + m_Start);
}
}
return dataStart;
}
// TODO: check if bitPos, bits, and num can be reduced to chars
static int *UnpackInts(uint32_t m_NumItems, uint8_t *m_Data, char m_BitSize)
{
int *data = (int *)malloc(m_NumItems * sizeof(int));
int indexPos = 0;
int bitPos = 0;
for (uint32_t i = 0; i < m_NumItems; i++)
{
int bits = 0;
data[i] = 0;
while (bits < m_BitSize)
{
data[i] |= (m_Data[indexPos] >> bitPos) << bits;
int num = MIN(m_BitSize - bits, 8 - bitPos);
bitPos += num;
bits += num;
if (bitPos == 8)
{
indexPos++;
bitPos = 0;
}
}
data[i] &= (1 << m_BitSize) - 1;
}
return data;
}
// TODO: implement unpack quaternions
PyObject *unpack_floats(PyObject *self, PyObject *args)
{
// define vars
uint32_t m_NumItems;
float m_Range;
float m_Start;
uint8_t *m_Data;
char m_BitSize;
int itemCountInChunk;
int chunkStride;
int start;
int numChunks;
Py_ssize_t data_size;
start = 0;
numChunks = -1;
if (!PyArg_ParseTuple(args, "Iffy#bii|ii", &m_NumItems, &m_Range, &m_Start, &m_Data, &data_size, &m_BitSize, &itemCountInChunk, &chunkStride, &start, &numChunks))
return NULL;
// decode
float *array = UnpackFloats(m_NumItems, m_Range, m_Start, m_Data, m_BitSize, itemCountInChunk, chunkStride, start, numChunks);
if (numChunks == -1)
numChunks = (int)m_NumItems / itemCountInChunk;
Py_ssize_t array_len = numChunks * itemCountInChunk;
// return
PyObject *lst = PyList_New(array_len);
if (!lst)
return NULL;
for (Py_ssize_t i = 0; i < array_len; i++)
{
PyObject *num = PyFloat_FromDouble(array[i]);
if (!num)
{
Py_DECREF(lst);
return NULL;
}
PyList_SET_ITEM(lst, i, num); // reference to num stolen
}
free(array);
return lst;
}
PyObject *unpack_ints(PyObject *self, PyObject *args)
{
// define vars
uint32_t m_NumItems;
uint8_t *m_Data;
char m_BitSize;
Py_ssize_t data_size;
if (!PyArg_ParseTuple(args, "Iy#b", &m_NumItems, &m_Data, &data_size, &m_BitSize))
return NULL;
// decode
int *array = UnpackInts(m_NumItems, m_Data, m_BitSize);
// return
PyObject *lst = PyList_New(m_NumItems);
if (!lst)
return NULL;
for (uint32_t i = 0; i < m_NumItems; i++)
{
PyObject *num = PyLong_FromLong(array[i]);
if (!num)
{
Py_DECREF(lst);
return NULL;
}
PyList_SET_ITEM(lst, i, num); // reference to num stolen
}
free(array);
return lst;
}