- Joined
- Aug 27, 2006
- Messages
- 223
- Reaction score
- 183
Blender 2.4x *.p3m Importer w/ KOM (Un)packer
Warning: I have never played Grand Chase and these posts are for sharing knowledge only.
Installation: (Pictorial Steps http://forum.ragezone.com/f311/elu-blender-importer-488857/#post4297496)
Usage:
License:
Source:
----------
KOM Unpacker
Usage:
License:
Source:
Warning: I have never played Grand Chase and these posts are for sharing knowledge only.
Installation: (Pictorial Steps http://forum.ragezone.com/f311/elu-blender-importer-488857/#post4297496)
- Download and install Blender 2.46+ from Blender.org
- Download and install Python 2.6.x from
You must be registered to see links(Windows Users)
- Save code below
- Copy p3m_import.py into your Blender scripts directory.
Usage:
- Click File > Import > Perfect 3D Model Import (*.p3m)...
- Select *.p3m file
- Click Ok
License:
You must be registered to see links
Source:
Copy and save as p3m_import.py
Code:
#!BPY
# Copyright (c) 2009-2012 AJ
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""
Name: 'Perfect 3D Model Import (*.p3m)...'
Blender: 246
Group: 'Import'
Tooltip: 'Import Grand Chase: Perfect 3D Model *.p3m game files'
"""
__author__ = 'AJ'
__email__ = ''
__url__ = ('blender', 'elysiun', 'Project homepage, http://www.ragezone.com/')
__version__ = '0.0.2'
__bpydoc__ = """ \
This prototype script imports Grand Chase: Perfect 3D Model *.p3m game files
"""
import Blender
import struct
LEFT_TO_RIGHT = Blender.Mathutils.Matrix([-1.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 1.0])
def p3m_read(file_path):
file_name = Blender.sys.basename(file_path)
file_name, file_ext = Blender.sys.splitext(file_name)
file_object = None
try:
file_object = open(file_path, 'rb')
data_chunk = file_object.read(27)
if data_chunk != 'Perfact 3D Model (Ver 0.5)\0':
return
data_chunk = file_object.read(2)
unknown_0, unknown_1 = struct.unpack_from('<2B', data_chunk)
for x in xrange(unknown_0):
file_object.read(24)
for x in xrange(unknown_1):
file_object.read(28)
data_chunk = file_object.read(4)
vertex_count, face_count = struct.unpack_from('<2H', data_chunk)
data_chunk = file_object.read(260)
face_data_chunk = file_object.read(face_count * 3 * 2)
mesh_object1 = Blender.Object.New('Mesh', file_name + '_1')
mesh1 = mesh_object1.getData(mesh = True)
if mesh1 is None:
mesh1 = Blender.Mesh.New(file_name + '_1')
mesh_object1.link(mesh1)
mesh1.vertexUV = True
data_chunk = file_object.read(vertex_count * 40)
for x in xrange(vertex_count):
p = struct.unpack_from('<3f', data_chunk, x * 40)
n = struct.unpack_from('<3f', data_chunk, x * 40 + 8 + 12)
t = struct.unpack_from('<2f', data_chunk, x * 40 + 8 + 12 + 12)
position = Blender.Mathutils.Vector(p)
normal = Blender.Mathutils.Vector(n)
uv = Blender.Mathutils.Vector(t)
mesh1.verts.extend(position)
vertex = mesh1.verts[-1]
vertex.no = normal
vertex.uvco = uv
vertex.uvco[1] = 1.0 - vertex.uvco[1]
mesh_object2 = Blender.Object.New('Mesh', file_name + '_2')
mesh2 = mesh_object2.getData(mesh = True)
if mesh2 is None:
mesh2 = Blender.Mesh.New(file_name + '_2')
mesh_object2.link(mesh2)
mesh2.vertexUV = True
data_chunk = file_object.read(vertex_count * 32)
for x in xrange(vertex_count):
p = struct.unpack_from('<3f', data_chunk, x * 32)
n = struct.unpack_from('<3f', data_chunk, x * 32 + 12)
t = struct.unpack_from('<2f', data_chunk, x * 32 + 12 + 12)
position = Blender.Mathutils.Vector(p)
normal = Blender.Mathutils.Vector(n)
uv = Blender.Mathutils.Vector(t)
mesh2.verts.extend(position)
vertex = mesh2.verts[-1]
vertex.no = normal
vertex.uvco = uv
vertex.uvco[1] = 1.0 - vertex.uvco[1]
for x in xrange(face_count):
f = struct.unpack_from('<3H', face_data_chunk, x * 6)
mesh1.faces.extend([mesh1.verts[y] for y in f])
face = mesh1.faces[-1]
face.uv = [vertex.uvco for vertex in face.verts]
mesh2.faces.extend([mesh2.verts[y] for y in f])
face = mesh2.faces[-1]
face.uv = [vertex.uvco for vertex in face.verts]
mesh1.faceUV = True
mesh2.faceUV = True
world_matrix = mesh_object1.getMatrix()
mesh_object1.setMatrix(world_matrix * LEFT_TO_RIGHT)
world_matrix = mesh_object2.getMatrix()
mesh_object2.setMatrix(world_matrix * LEFT_TO_RIGHT)
scene = Blender.Scene.GetCurrent()
scene.objects.link(mesh_object1)
scene.objects.link(mesh_object2)
except IOError, (errno, strerror):
Blender.Draw.PupMenu("Error%%t|I/O error(%d): %s." % (errno, strerror))
except Exception, err:
Blender.Draw.PupMenu("Error%%t|.%s" % err)
finally:
if file_object is not None:
file_object.close()
def main():
def p3m_file_selector(file_path):
if file_path and not Blender.sys.exists(file_path):
Blender.Draw.PupMenu("Error%%t|The file %s does not exist." % file_path)
else:
p3m_read(file_path)
Blender.Window.FileSelector(p3m_file_selector, 'Ok', Blender.sys.makename(ext='.p3m'))
if __name__ == "__main__":
main()
----------
KOM Unpacker
Usage:
- Open Command Prompt/Console/Terminal
- Run kom_extract.py in a Python shell followed by the path to *.kom file. Eg. "C:\Python26\python.exe kom_extract.py C:\****soft Online\GrandChase\Model\Model_Pet.kom"
License:
You must be registered to see links
Source:
Copy and save as kom_extract.py
Code:
#!/usr/bin/python
# Copyright (c) 2009-2012 AJ
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import getopt
import os
import struct
import sys
import zlib
class Entry(object):
def __init__(self, name, uncompressed_size, compressed_size, relative_offset):
self.__name = name[0:name.find('\0')]
self.__uncompressed_size = uncompressed_size
self.__compressed_size = compressed_size
self.__relative_offset = relative_offset
def get_name(self):
return self.__name
def get_uncompressed_size(self):
return self.__uncompressed_size
def get_compressed_size(self):
return self.__compressed_size
def get_relative_offset(self):
return self.__relative_offset
name = property(get_name)
uncompressed_size = property(get_uncompressed_size)
compressed_size = property(get_compressed_size)
relative_offset = property(get_relative_offset)
def main(argv):
if len(argv) < 1:
sys.exit(2)
try:
options, arguments = getopt.getopt(argv, 'vf:', ['verbose', 'file='])
except getopt.GetoptError:
sys.exit(2)
verbose = False
file_name = None
for option, argument in options:
if option in ('v', '--verbose'):
verbose = True
elif option in ('f', '--file'):
file_name = argument
if file_name is None:
file_name = argv[0]
if os.path.isfile(file_name) == False:
sys.exit(2)
file_object = None
file_data = None
try:
file_object = open(file_name, 'rb')
if file_object is not None:
file_data = file_object.read()
finally:
if file_object is not None:
file_object.close()
file_object = None
offset = 0
version = struct.unpack_from('<26s26x', file_data, offset)[0]
offset += 52
entry_count = struct.unpack_from('<I4x', file_data, offset)[0]
offset += 8
entries = []
for x in xrange(entry_count):
entry = Entry(*struct.unpack_from('<60s3I', file_data, offset))
entries.append(entry)
offset += 72
for entry in entries:
entry_file_data = file_data[offset + entry.relative_offset:offset + entry.relative_offset + entry.compressed_size]
entry_file_data = zlib.decompress(entry_file_data)
try:
file_object = open(entry.name, 'wb')
if file_object is not None:
file_object.write(entry_file_data)
finally:
if file_object is not None:
file_object.close()
file_object = None
if __name__ == "__main__":
main(sys.argv[1:])
Last edited: