Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - KittenKoder

Pages: 1 2 3 [4] 5
46
Bugs / Re: Loader.loadOBJ OutOfBounds Exception.
« on: November 11, 2012, 01:11:14 am »
Does obj support animations? I just wanted to test this. Blender can not export into md2 and 3ds does not support animations.

Not directly, however, I can give you a script to export to rough md2, it doesn't optimize the model at all, from Blender:

Code: [Select]
# Dao Nguyen and Bernd Meyer, metaio GmbH

# ***** BEGIN GPL LICENSE BLOCK *****

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

# ***** END GPL LICENCE BLOCK *****

"""
Name: 'MD2 -new- (.md2)...'
Blender: 245
Group: 'Export'
Tooltip: 'Export to Quake2 file format (.md2) -new-'
"""

__version__ = '0.1'
__author__  = [ 'Damien Thebault', 'Erwan Mathieu' ]
__url__     = [ 'https://metabolsim.no-ip.org/trac/metabolsim' ]
__email__   = [ 'Damien Thebault <damien!thebault#laposte!net>', 'Erwan Mathieu <cyberwan#laposte!net>' ]

__bpydoc__ = """\
This script exports a mesh object to the Quake2 "MD2" file format.

If you want to choose the name of the animations, you have to go to the timeline, choose the starting frame, choose 'Frame', 'Add Marker' (M) and then set a name with 'Frame', 'Name Marker' (Ctrl M).

The frames are named <frameName><N> with :<br>
 - <N> the frame number<br>
 - <frameName> the name choosen at the last marker (or 'frame' if the last marker has no name or if there is no last marker)

Skins are set using image textures in materials. If a skin path is too long (>63 chars), the basename will be used.

Usually, importers expect that the name don't have any digit (to be able to detect where the frame name starts and where the frame number starts.

Thanks to Bob Holcomb for MD2_NORMALS taken from his exporter.<br>
Thanks to David Henry for the documentation about the MD2 file format.
"""

#New Header Data
bl_info = {
    "name": "Quake2 MD2 format",
    "description": "Export to Quake2 file format (.md2)",
    "author": "Dao Nguyen and Bernd Meyer, metaio GmbH (based on the initial exporter of Damien Thebault and Erwan Mathieu)",
    "version": (1, 0),
    "blender": (2, 5, 8),
    "api": 31236,
    "location": "File > Export > md2",
    "warning": '', # used for warning icon and text in addons panel
    "wiki_url": "http://metaio.com",
    "tracker_url": "http://metaio.com",
    "support": 'OFFICIAL',
    "category": "Import-Export"}


import bpy
from bpy.props import *

from bpy_extras.io_utils import ExportHelper
from datetime import datetime

import math
from math import pi
import mathutils

import struct
import random
import os


MD2_NORMALS=((-0.525731, 0.000000, 0.850651),
             (-0.442863, 0.238856, 0.864188),
             (-0.295242, 0.000000, 0.955423),
             (-0.309017, 0.500000, 0.809017),
             (-0.162460, 0.262866, 0.951056),
             ( 0.000000, 0.000000, 1.000000),
             ( 0.000000, 0.850651, 0.525731),
             (-0.147621, 0.716567, 0.681718),
             ( 0.147621, 0.716567, 0.681718),
             ( 0.000000, 0.525731, 0.850651),
             ( 0.309017, 0.500000, 0.809017),
             ( 0.525731, 0.000000, 0.850651),
             ( 0.295242, 0.000000, 0.955423),
             ( 0.442863, 0.238856, 0.864188),
             ( 0.162460, 0.262866, 0.951056),
             (-0.681718, 0.147621, 0.716567),
             (-0.809017, 0.309017, 0.500000),
             (-0.587785, 0.425325, 0.688191),
             (-0.850651, 0.525731, 0.000000),
             (-0.864188, 0.442863, 0.238856),
             (-0.716567, 0.681718, 0.147621),
             (-0.688191, 0.587785, 0.425325),
             (-0.500000, 0.809017, 0.309017),
             (-0.238856, 0.864188, 0.442863),
             (-0.425325, 0.688191, 0.587785),
             (-0.716567, 0.681718,-0.147621),
             (-0.500000, 0.809017,-0.309017),
             (-0.525731, 0.850651, 0.000000),
             ( 0.000000, 0.850651,-0.525731),
             (-0.238856, 0.864188,-0.442863),
             ( 0.000000, 0.955423,-0.295242),
             (-0.262866, 0.951056,-0.162460),
             ( 0.000000, 1.000000, 0.000000),
             ( 0.000000, 0.955423, 0.295242),
             (-0.262866, 0.951056, 0.162460),
             ( 0.238856, 0.864188, 0.442863),
             ( 0.262866, 0.951056, 0.162460),
             ( 0.500000, 0.809017, 0.309017),
             ( 0.238856, 0.864188,-0.442863),
             ( 0.262866, 0.951056,-0.162460),
             ( 0.500000, 0.809017,-0.309017),
             ( 0.850651, 0.525731, 0.000000),
             ( 0.716567, 0.681718, 0.147621),
             ( 0.716567, 0.681718,-0.147621),
             ( 0.525731, 0.850651, 0.000000),
             ( 0.425325, 0.688191, 0.587785),
             ( 0.864188, 0.442863, 0.238856),
             ( 0.688191, 0.587785, 0.425325),
             ( 0.809017, 0.309017, 0.500000),
             ( 0.681718, 0.147621, 0.716567),
             ( 0.587785, 0.425325, 0.688191),
             ( 0.955423, 0.295242, 0.000000),
             ( 1.000000, 0.000000, 0.000000),
             ( 0.951056, 0.162460, 0.262866),
             ( 0.850651,-0.525731, 0.000000),
             ( 0.955423,-0.295242, 0.000000),
             ( 0.864188,-0.442863, 0.238856),
             ( 0.951056,-0.162460, 0.262866),
             ( 0.809017,-0.309017, 0.500000),
             ( 0.681718,-0.147621, 0.716567),
             ( 0.850651, 0.000000, 0.525731),
             ( 0.864188, 0.442863,-0.238856),
             ( 0.809017, 0.309017,-0.500000),
             ( 0.951056, 0.162460,-0.262866),
             ( 0.525731, 0.000000,-0.850651),
             ( 0.681718, 0.147621,-0.716567),
             ( 0.681718,-0.147621,-0.716567),
             ( 0.850651, 0.000000,-0.525731),
             ( 0.809017,-0.309017,-0.500000),
             ( 0.864188,-0.442863,-0.238856),
             ( 0.951056,-0.162460,-0.262866),
             ( 0.147621, 0.716567,-0.681718),
             ( 0.309017, 0.500000,-0.809017),
             ( 0.425325, 0.688191,-0.587785),
             ( 0.442863, 0.238856,-0.864188),
             ( 0.587785, 0.425325,-0.688191),
             ( 0.688191, 0.587785,-0.425325),
             (-0.147621, 0.716567,-0.681718),
             (-0.309017, 0.500000,-0.809017),
             ( 0.000000, 0.525731,-0.850651),
             (-0.525731, 0.000000,-0.850651),
             (-0.442863, 0.238856,-0.864188),
             (-0.295242, 0.000000,-0.955423),
             (-0.162460, 0.262866,-0.951056),
             ( 0.000000, 0.000000,-1.000000),
             ( 0.295242, 0.000000,-0.955423),
             ( 0.162460, 0.262866,-0.951056),
             (-0.442863,-0.238856,-0.864188),
             (-0.309017,-0.500000,-0.809017),
             (-0.162460,-0.262866,-0.951056),
             ( 0.000000,-0.850651,-0.525731),
             (-0.147621,-0.716567,-0.681718),
             ( 0.147621,-0.716567,-0.681718),
             ( 0.000000,-0.525731,-0.850651),
             ( 0.309017,-0.500000,-0.809017),
             ( 0.442863,-0.238856,-0.864188),
             ( 0.162460,-0.262866,-0.951056),
             ( 0.238856,-0.864188,-0.442863),
             ( 0.500000,-0.809017,-0.309017),
             ( 0.425325,-0.688191,-0.587785),
             ( 0.716567,-0.681718,-0.147621),
             ( 0.688191,-0.587785,-0.425325),
             ( 0.587785,-0.425325,-0.688191),
             ( 0.000000,-0.955423,-0.295242),
             ( 0.000000,-1.000000, 0.000000),
             ( 0.262866,-0.951056,-0.162460),
             ( 0.000000,-0.850651, 0.525731),
             ( 0.000000,-0.955423, 0.295242),
             ( 0.238856,-0.864188, 0.442863),
             ( 0.262866,-0.951056, 0.162460),
             ( 0.500000,-0.809017, 0.309017),
             ( 0.716567,-0.681718, 0.147621),
             ( 0.525731,-0.850651, 0.000000),
             (-0.238856,-0.864188,-0.442863),
             (-0.500000,-0.809017,-0.309017),
             (-0.262866,-0.951056,-0.162460),
             (-0.850651,-0.525731, 0.000000),
             (-0.716567,-0.681718,-0.147621),
             (-0.716567,-0.681718, 0.147621),
             (-0.525731,-0.850651, 0.000000),
             (-0.500000,-0.809017, 0.309017),
             (-0.238856,-0.864188, 0.442863),
             (-0.262866,-0.951056, 0.162460),
             (-0.864188,-0.442863, 0.238856),
             (-0.809017,-0.309017, 0.500000),
             (-0.688191,-0.587785, 0.425325),
             (-0.681718,-0.147621, 0.716567),
             (-0.442863,-0.238856, 0.864188),
             (-0.587785,-0.425325, 0.688191),
             (-0.309017,-0.500000, 0.809017),
             (-0.147621,-0.716567, 0.681718),
             (-0.425325,-0.688191, 0.587785),
             (-0.162460,-0.262866, 0.951056),
             ( 0.442863,-0.238856, 0.864188),
             ( 0.162460,-0.262866, 0.951056),
             ( 0.309017,-0.500000, 0.809017),
             ( 0.147621,-0.716567, 0.681718),
             ( 0.000000,-0.525731, 0.850651),
             ( 0.425325,-0.688191, 0.587785),
             ( 0.587785,-0.425325, 0.688191),
             ( 0.688191,-0.587785, 0.425325),
             (-0.955423, 0.295242, 0.000000),
             (-0.951056, 0.162460, 0.262866),
             (-1.000000, 0.000000, 0.000000),
             (-0.850651, 0.000000, 0.525731),
             (-0.955423,-0.295242, 0.000000),
             (-0.951056,-0.162460, 0.262866),
             (-0.864188, 0.442863,-0.238856),
             (-0.951056, 0.162460,-0.262866),
             (-0.809017, 0.309017,-0.500000),
             (-0.864188,-0.442863,-0.238856),
             (-0.951056,-0.162460,-0.262866),
             (-0.809017,-0.309017,-0.500000),
             (-0.681718, 0.147621,-0.716567),
             (-0.681718,-0.147621,-0.716567),
             (-0.850651, 0.000000,-0.525731),
             (-0.688191, 0.587785,-0.425325),
             (-0.587785, 0.425325,-0.688191),
             (-0.425325, 0.688191,-0.587785),
             (-0.425325,-0.688191,-0.587785),
             (-0.587785,-0.425325,-0.688191),
             (-0.688191,-0.587785,-0.425325))


class MD2:
def __init__(self, anim, basename):
self.anim = anim
self.basename = basename
self.object = None
self.progressBarDisplayed = -10
return

def setObject(self, object):
self.object = object

def write(self, filename):
self.ident = 'IDP2'
self.version = 8

self.skinwidth = 2**10-1 #1023
self.skinheight = 2**10-1 #1023

# self.framesize : see below

mesh = self.object.data

skins = Util.getSkins(mesh)

self.num_skins = len(skins)
self.num_xyz = len(mesh.vertices)
self.num_st = len(mesh.polygons)*3
self.num_tris = len(mesh.polygons)
self.num_glcmds = self.num_tris * (1+3*3) + 1
if self.anim:
self.num_frames = 1 + bpy.context.scene.frame_end - bpy.context.scene.frame_start

else:
self.num_frames = 1

self.framesize = 40+4*self.num_xyz

self.ofs_skins = 68 # size of the header
self.ofs_st = self.ofs_skins + 64*self.num_skins
self.ofs_tris = self.ofs_st + 4*self.num_st
self.ofs_frames = self.ofs_tris + 12*self.num_tris
self.ofs_glcmds = self.ofs_frames + self.framesize*self.num_frames
self.ofs_end = self.ofs_glcmds + 4*self.num_glcmds

file = open(filename, 'wb')
try:
# write header
bin = struct.pack('<4B16i', #bin = struct.pack('<4s16i',
                  ord('I'), #self.ident,
                  ord('D'),
                  ord('P'),
                  ord('2'),
                  self.version,
                  self.skinwidth,
                  self.skinheight,
                  self.framesize,
                  self.num_skins,
                  self.num_xyz,
                  self.num_st, #  number of texture coordinates
                  self.num_tris,
                  self.num_glcmds,
                  self.num_frames,
                  self.ofs_skins,
                  self.ofs_st,
                  self.ofs_tris,
                  self.ofs_frames,
                  self.ofs_glcmds,
                  self.ofs_end)
file.write(bin)

# write skin file names
for skin in skins:
if len(skin) > 63 and self.basename == False:
print("WARNING: The texture path '"+skin+"' is too long. It is automatically truncated to the file basename.")

if len(skin) > 63 or self.basename:
skin = os.path.basename(skin)

bin = struct.pack('<64s', bytes(skin[0:63], encoding='utf8'))
file.write(bin) # skin name


#define meshTextureFaces
if len(mesh.uv_textures) != 0:
#meshTextureFaces = mesh.uv_textures[0].data
meshTextureFaces = self.object.to_mesh(bpy.context.scene, True, 'PREVIEW').tessface_uv_textures.active
else:
meshTextureFaces = mesh.polygons

#for meshTextureFace in meshTextureFaces: # for face in mesh.polygons:
for meshTextureFace in meshTextureFaces.data:
try:
#uvs = meshTextureFace.uv
uvs = (meshTextureFace.uv1, meshTextureFace.uv2, meshTextureFace.uv3)
except:
uvs = ([0,0],[0,0],[0,0])

# (u,v) in blender -> (u,1-v)
bin = struct.pack('<6h',
  int(uvs[0][0]*self.skinwidth),
  int((1-uvs[0][1])*self.skinheight),
  int(uvs[1][0]*self.skinwidth),
  int((1-uvs[1][1])*self.skinheight),
  int(uvs[2][0]*self.skinwidth),
  int((1-uvs[2][1])*self.skinheight),
  )
file.write(bin) # uv
# (uv index is : face.index*3+i)

for face in mesh.polygons:
# 0,2,1 for good cw/ccw
bin = struct.pack('<3h',
                  face.vertices[0],
                  face.vertices[2],
                  face.vertices[1]
                )
file.write(bin) # vert index
bin = struct.pack('<3h',
                  face.index*3 + 0,
                  face.index*3 + 2,
                  face.index*3 + 1,
                  )

file.write(bin) # uv index

if self.anim:
min = None
max = None

timeLineMarkers =[]
for marker in bpy.context.scene.timeline_markers:
timeLineMarkers.append(marker)

# sort the markers. The marker with the frame number closest to 0 will be the first marker in the list.
# The marker with the biggest frame number will be the last marker in the list
timeLineMarkers.sort(key=lambda marker: marker.frame)
markerIdx = 0

# delete markers at same frame positions
if len(timeLineMarkers) > 1:
markerFrame = timeLineMarkers[len(timeLineMarkers)-1].frame
for i in range(len(timeLineMarkers)-2, -1, -1):
if timeLineMarkers[i].frame == markerFrame:
del timeLineMarkers[i]
else:
markerFrame = timeLineMarkers[i].frame

for frame in range(1, self.num_frames+1):
percent = (frame - bpy.context.scene.frame_start) / ( 1. + self.num_frames)

#Display the progress status of the exportation in the console
#problem: "Carriage return" doesn't function properly with python 3.x
progressStatus = math.floor((frame)/(self.num_frames+1)*100)
progressStatusString = ("Exportation progress: "+str((progressStatus//10)*10)+"%")
if progressStatus - self.progressBarDisplayed >= 10:
print(progressStatusString)
self.progressBarDisplayed = (progressStatus//10)*10
if frame == self.num_frames:
print("Exportation progress: 100% - model exported")
# --Blender.Window.DrawProgressBar(percent,
# str(int(percent*100)) + '%' + \
# ' : frame ' + str(frame))

bpy.context.scene.frame_set(frame)
(min, max) = self.findMinMax()

if len(timeLineMarkers) != 0:
if markerIdx + 1 != len(timeLineMarkers):
if frame >= timeLineMarkers[markerIdx + 1].frame:
markerIdx += 1
name = timeLineMarkers[markerIdx].name
else:
name = 'frame'

self.outFrame(file, min, max, name + str(frame))
else:
(min, max) = self.findMinMax()
self.outFrame(file, min, max)

# gl commands
#for meshTextureFace in meshTextureFaces: # for face in mesh.polygons:
for meshTextureFace in meshTextureFaces.data:
try:
uvs = (meshTextureFace.uv1, meshTextureFace.uv2, meshTextureFace.uv3)
#uvs = meshTextureFace.uv
except:
uvs = ([0,0],[0,0],[0,0])
bin = struct.pack('<i', 3)
file.write(bin)
# 0,2,1 for good cw/ccw (also flips/inverts normal)
for vert in [0,2,1]:
# (u,v) in blender -> (u,1-v)
bin = struct.pack('<ffI',
uvs[vert][0],
(1.0 - uvs[vert][1]),
face.vertices[vert])

file.write(bin)
# NULL command
bin = struct.pack('<I', 0)
file.write(bin)
finally:
file.close()

def findMinMax(self, min=None, max=None):
# mesh = Blender.Mesh.New()
# mesh.getFromObject(self.object.name)
# mesh = self.object.create_mesh(bpy.context.scene ,True, self.object.name)
mesh = self.object.to_mesh(bpy.context.scene, True, 'PREVIEW')

mesh.transform(self.object.matrix_world)
mesh.transform(mathutils.Matrix.Rotation(pi/2, 4, 'Z')) # Hoehrer: rotate 90 degrees

if min == None:
min = [mesh.vertices[0].co[0],
       mesh.vertices[0].co[1],
       mesh.vertices[0].co[2]]
if max == None:
max = [mesh.vertices[0].co[0],
       mesh.vertices[0].co[1],
       mesh.vertices[0].co[2]]

for vert in mesh.vertices:
for i in range(3):
if vert.co[i] < min[i]:
min[i] = vert.co[i]
if vert.co[i] > max[i]:
max[i] = vert.co[i]

return (min, max)

def outFrame(self, file, min, max, frameName = 'frame'):
mesh = self.object.to_mesh(bpy.context.scene, True, 'PREVIEW')

mesh.transform(self.object.matrix_world)
mesh.transform(mathutils.Matrix.Rotation(pi/2, 4, 'Z')) # Hoehrer: rotate 90 degrees

bin = struct.pack('<6f16s', #bin = struct.pack('<6f16s',
self.object.scale[0]*(max[0]-min[0])/255., #self.object.getSize()[0]*(max[0]-min[0])/255.
self.object.scale[1]*(max[1]-min[1])/255.,
self.object.scale[2]*(max[2]-min[2])/255.,
min[0],
min[1],
min[2],
bytes(frameName, encoding='utf8'))

file.write(bin) # frame header
for vert in mesh.vertices:
for i in range(162):
dot =  vert.normal[1]*MD2_NORMALS[i][0] + \
      -vert.normal[0]*MD2_NORMALS[i][1] + \
       vert.normal[2]*MD2_NORMALS[i][2]
if (i==0) or (dot > maxDot):
maxDot = dot
bestNormalIndex = i

bin = struct.pack('<4B',
                  int((vert.co[0]-min[0])/(max[0]-min[0])*255.),
                  int((vert.co[1]-min[1])/(max[1]-min[1])*255.),
                  int((vert.co[2]-min[2])/(max[2]-min[2])*255.),
                  bestNormalIndex)

file.write(bin) # vertex

class Util:
@staticmethod
def pickName():
name = '_MD2Obj_'+str(random.random())
return name[0:20]

# deletes an object from Blender (remove + unlink)
@staticmethod
def deleteObject(object):
bpy.context.scene.objects.unlink(object)
bpy.data.objects.remove(object)

# duplicates the given object and returns it
@staticmethod
def duplicateObject(object, name):
# backup the current object selection and current active object
selObjects = bpy.context.selected_objects[:]
actObject = bpy.context.active_object

# deselect all selected objects
bpy.ops.object.select_all(action='DESELECT')
# select the object which we want to duplicate
object.select = True

# duplicate the selected object
bpy.ops.object.duplicate()

# the duplicated object is automatically selected
copyObj = bpy.context.selected_objects[0]

# rename the object with the given name
copyObj.name = name

# select all objects which have been previously selected and make active the previous active object
bpy.context.scene.objects.active = actObject
for obj in selObjects:
obj.select = True

return copyObj

# returns the mesh of the object and return object.data (mesh)
@staticmethod
def triangulateMesh(object):
mesh = object.data

# make the object the active object!
# object.select = True
bpy.context.scene.objects.active = object

bpy.ops.object.mode_set( mode="EDIT" , toggle = False )
bpy.ops.mesh.select_all(action="SELECT")

#for face in mesh.polygons:
#face.select = True

# mesh.quadToTriangle()
# bpy.ops.object.mode_set( mode="OBJECT" , toggle = False )

bpy.ops.mesh.quads_convert_to_tris()
bpy.ops.object.mode_set( mode="OBJECT" , toggle = False )
return mesh

@staticmethod
def getSkins(mesh):
skins = []
for material in mesh.materials:
for texSlot in material.texture_slots:
if texSlot != None:
if texSlot.texture.type == "IMAGE": # if texture.tex.getType() == "Image":
# get the image path and convert it to a relative one (if it is not already a relative path)
imgfile = bpy.path.relpath(texSlot.texture.image.filepath)[2:]
skins.append(imgfile)
return skins


class ObjectInfo:
def __init__(self, object):
self.triang = False
self.vertices = -1
self.faces = -1
self.status = ('','')

self.ismesh = object and object.type == 'MESH'

if self.ismesh:
originalObject = object
mesh = object.data

self.skins = Util.getSkins(mesh)

for face in mesh.polygons:
if len(face.vertices) == 4:
self.triang = True
break

tmpObjectName = Util.pickName()
try:
if self.triang:
object = Util.duplicateObject(object, tmpObjectName)
mesh = Util.triangulateMesh(object)

self.status = (str(len(mesh.vertices)) + ' vertices', str(len(mesh.polygons)) + ' faces')

finally:
if object.name == tmpObjectName:
originalObject.select = True
bpy.context.scene.objects.active = originalObject
# bpy.context.scene.objects.unlink(object)
Util.deleteObject(object)

class Export_MD2(bpy.types.Operator, ExportHelper):
"""Export to Quake2 file format (.md2)"""
bl_idname = "export_quake.md2"
bl_label = "Export to Quake2 file format (.md2)"

filename = StringProperty(name="File Path",
description="Filepath used for processing the script",
maxlen= 1024,default= "")

filename_ext = ".md2"

val_anim = BoolProperty(name="Export animation",
description="default: True",
default=True)

val_basename = BoolProperty(name="Export only basenames (skin)",
description="default: True",
default=True)

# id_export   = 1
# id_cancel   = 2
# id_anim     = 3
# id_update   = 4
# id_help     = 5
# id_basename = 6

def __init__(self):
try:
self.object = bpy.context.selected_objects[0]
except:
self.object = None

# go into object mode before we start the actual export procedure
bpy.ops.object.mode_set( mode="OBJECT" , toggle = False )

self.info = ObjectInfo(self.object)

def execute(self, context):

# if Blender.sys.exists(filename) == 1: #if Blender.sys.exists(filename) == 1:
    # overwrite = Blender.Draw.PupMenu('File already exists, overwrite?%t|Yes%x1|No%x0') #overwrite = Blender.Draw.PupMenu('File already exists, overwrite?%t|Yes%x1|No%x0')
    # if overwrite == 0:
    # return

props = self.properties
filepath = self.filepath
filepath = bpy.path.ensure_ext(filepath, self.filename_ext)

if len(bpy.context.selected_objects[:]) == 0:
raise NameError('Please, select one object!')

if len(bpy.context.selected_objects[:]) > 1:
#self.report({'ERROR'}, "Please, select one and only one object!")
raise NameError('Please, select one and only one object!')


object = self.object
originalObject = object

if object.type != 'MESH':
raise NameError('Selected object must be a mesh!')

# different name each time or we can't unlink it later
tmpObjectName = Util.pickName()
mesh = object.data

'''
print(str(object)+" "+str(mesh)+" "+str(originalObject))
object = Util.duplicateObject(object, tmpObjectName)
print(str(object))
mesh = Util.triangulateMesh(object)
print(str(mesh))

if object.name == tmpObjectName:
originalObject.select = True
print("unlinkt tmpObject")
# bpy.data.objects.remove(object)
'''

if self.info.triang:
object = Util.duplicateObject(object, tmpObjectName)
mesh = Util.triangulateMesh(object)

if self.val_anim:
frame =bpy.context.scene.frame_current

try:
md2 = MD2(self.val_anim, self.val_basename)
md2.setObject(object)
md2.write(filepath) #md2.write(filename)
finally:
if object.name == tmpObjectName:
originalObject.select = True
bpy.context.scene.objects.active = originalObject
Util.deleteObject(object);
if self.val_anim:
bpy.context.scene.frame_set(frame)

# Blender.Window.DrawProgressBar(1.0, '')
# Blender.Window.WaitCursor(False)
# Blender.Draw.Exit()
self.report({'INFO'},  "Model '"+originalObject.name+"' exported")
return {'FINISHED'}

def invoke(self, context, event):
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}


def menuCB(self, context):
self.layout.operator(Export_MD2.bl_idname, text="Quake2 (.md2)")
 
def register():
# initialize()
# bpy.utils.register_class(Export_MD2)
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_export.append(menuCB)
 
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_export.remove(menuCB)
 
if __name__ == "__main__":
register()

Although I didn't write the entire script, I did correct the blender API problems it had. Works great.

47
Projects / Re: New Library And Game
« on: November 11, 2012, 12:26:03 am »
Alright, before I commit to a specific method, which would be harder on the CPU for texture animations:

1. Loading all the frames to the GPU then setting a different frame each "pass."

2. Using an ITextureEffect and updating the buffer directly each "pass."

A "pass" is when the frame actually changes.

48
Bugs / Re: Loader.loadOBJ OutOfBounds Exception.
« on: November 10, 2012, 06:40:15 pm »
I don't believe Blender formats the mtl file in a way that jPCT likes, I found that error as well when I tried loading the mtl file but without the mtl file everything loads fine.

49
Projects / Re: New Library And Game
« on: November 10, 2012, 11:19:01 am »
I may have figured out the error, which will need an overhaul of my original texture system. It seems that my image manager is likely causing the error. Possibly making too many textures, and I know I'm loading too many "dead" images that are only used for a moment in the test app.

The trick of it is that I need to maintain images of some textures, and not others, and some images don't get made into textures, so I'm still ironing out the specific techniques I want to use for this. I was thinking of using the iTextureEffect with the byte arrays for animated textures, though it would limit the variation with objects using the same animation it would improve memory consumption a lot.

50
Projects / Re: New Library And Game
« on: November 10, 2012, 10:58:41 am »
Currently to port an object3D into the new class I'm using super(object3D, true) to reuse mesh data, unsure if it holds the original when I do that or not, if it does then I may just need to fix that.
...the "orginal" what is it supposed to hold? This constructor makes an Object3D share the mesh with another. If you use compile() on your objects, you might consider to use shareCompiledData() as well.

Well, i don't call compile until after the new one is made, I let the old Object3D die after I am finished with it. The point was if there was a reference to the original Object3D somewhere  that i am unaware of. On my end the object is only used to create the new object then it's gone. But the library needs the data that's in the extended Object3D to work efficiently.

51
Projects / Re: New Library And Game
« on: November 09, 2012, 04:12:04 pm »
SNAFU, pretty big one. My method for texture management was too heavy on memory I think, either that or I'm swapping objects to the new class wrong, could be either. I need to sleep on it to figure it out but any ideas may be helpful if anyone has any. Currently to port an object3D into the new class I'm using super(object3D, true) to reuse mesh data, unsure if it holds the original when I do that or not, if it does then I may just need to fix that.

I do need to rework the textures+images system though, it's messy now that I look at it, and far from neat. I neglected a lot of problem areas through the experimental portion of development, and now seeing issues that will arise eventually. Heap stack keeps screaming at me and I think streamlining the textures will help prevent future problems there.

52
Projects / Re: New Library And Game
« on: November 08, 2012, 12:17:51 pm »
Just a quick update on the progress. I am almost happy with the arrangement and will hopefully be out of the experimental phase of development and have a real version to launch. Some of the actor, animation, and manipulation classes are still a bit of a mess though. Trying to make the semantics for the classes to be universal yet comprehensive, without weighing it down.

The current method is:

Actor: Controls the object in the world space, based on game needs. This merges objects with everything else, and is only needed for objects that interact in the world, static map like objects with no animations will not need this class.
Animator: Animated object animations based on time passed. Only needed for objects with animations or animated texture sequences.
Manipulator: Moves the objects or alters some of the object settings based on time passed.

Currently only one manipulator is installed per actor, I am debating multiple manipulators per actor, though manipulators can effect multiple objects or even be used in other classes effecting objects. The base manipulator is an interface, not a class, making it easier to extend hopefully. Considering a "wandering" actor, but I'm having a difficult time figuring out exactly how to work that without limiting it too much or making it too elaborate.

53
Feedback / Re: Old Style RPG
« on: November 06, 2012, 10:25:53 pm »
I am biased toward game controllers. I love console games, never much cared for PC games at all because I don't like gaming with the mouse.

54
Support / Re: Fresh Veiw
« on: November 06, 2012, 09:55:59 pm »
Alright, the final method, which is only called if the object fails and "in bounds" check.

Code: [Select]
public void moveInBounds() {
this.tempvector = this.object.getTranslation(this.tempvector);
this.center = this.object.getTranslation(this.center);
if(this.origin != null) this.tempvector.sub(this.origin);

if(this.bounds.x > 0.0f) this.tempvector.x = (this.tempvector.x < -this.bounds.x) ? -this.bounds.x :
((this.tempvector.x > this.bounds.x) ? this.bounds.x : this.tempvector.x);

if(this.bounds.y > 0.0f) this.tempvector.y = (this.tempvector.y < -this.bounds.y) ? -this.bounds.y :
((this.tempvector.y > this.bounds.y) ? this.bounds.y : this.tempvector.y);

if(this.bounds.z > 0.0f) this.tempvector.z = (this.tempvector.z < -this.bounds.z) ? -this.bounds.z :
((this.tempvector.z > this.bounds.z) ? this.bounds.z : this.tempvector.z);

if(this.origin != null) this.tempvector.add(this.origin);
this.tempvector.sub(this.center);

this.object.translate(this.tempvector);
}

The "in bounds" check is done in a different method, primarily because it has other uses. "center" is a temp SimpleVector that I always use to get the object's center point or translation, I forgot I had that in the class already. lol But I found a reason to have two, so it's all good.

55
Support / Re: Fresh Veiw
« on: November 06, 2012, 09:41:25 pm »
It's not just assigning, it's comparing to the bounds as if they are minimum and maximum values. So it's like clipping or constraints.
I know. That's why i wrote "if everything is within the bounds". I tried to simplify the case.

I think I discovered the problem, it's in the object's transformed center and the point it translates from, they are not the same point in the object. I was looking at the incorrect point, I needed to change getTransformedCenter with getTranslation.
That was the confusing part...but if you use getTranslation(), then where's the actual translation? You read the translation, subtract the origin, do a nop if everything is within the bounds, add origin again, clear the translation and translate again to the unchanged translation vector. If everything works now, all is well...i would just like to understand how you translate things with something that appears to be a large nop to me...what am i missing?

Oh, that's what you're talking about, yeah, I write the code I need first, make sure it works, then optimize after it's working as expected. It will be in the final method.

56
Support / Re: Fresh Veiw
« on: November 06, 2012, 09:25:10 pm »
I'm still not sure what this is supposed to do. I mean if everything is within the bounds, what this does is:

  • store the transformed center in tempvector
  • subtract origin
  • assign tempvector's attributes to themselves (i.e. a nop)
  • add origin
  • clear the translation
  • translate to tempvector

This can be simplified to

  • store the transformed center in tempvector
  • clear the translation
  • translate to tempvector

Which basically translates it along the direction vector from it's current translation to the position of its center in world space...or did i miss something (most likely...)?

I fail to see the point in that operation...

It's not just assigning, it's comparing to the bounds as if they are minimum and maximum values. So it's like clipping or constraints.

I think I discovered the problem, it's in the object's transformed center and the point it translates from, they are not the same point in the object. I was looking at the incorrect point, I needed to change getTransformedCenter with getTranslation.

57
Support / Re: Fresh Veiw
« on: November 06, 2012, 08:56:51 pm »
And origin is null or filled in this case? And if it's filled, with which value?

Personally, i would get rid of all these ternary ifs and use "real" ifs instead to ease debugging by adding some log output of inbetween states (or use a debugger, if you are weak... ;) ).

I'm not totally sure what this code is supposed to do, which is mainly caused by the fact that i'm not sure what "origin" exactly is.

I'm not that great at explaining things so no surprise. ;)

Origin is like the center point of the bounds, but the odd part is that it should work just fine, I can't think of why it's behaving so oddly, like somehow it's increasing the y translation. I tend to use System.out for debugging, debuggers really drain resources and my computer isn't that impressive. I have traced all the calls prior to it, and there is nothing moving the object "up." This is the only location the problem could be. I was thinking it may be a precision error, but then the others would be effected as well. I'm really just banging my head right now. lol

58
Support / Fresh Veiw
« on: November 06, 2012, 07:17:50 pm »
Alright, I am literally stumped on this and would like some alternative ideas as to why it happens. Here's the code first:

Code: [Select]
public void moveInBounds() {
this.tempvector = this.object.getTransformedCenter(this.tempvector);
if(this.origin != null) this.tempvector.sub(this.origin);

if(this.bounds.x > 0.0f) this.tempvector.x = (this.tempvector.x < -this.bounds.x) ? -this.bounds.x :
((this.tempvector.x > this.bounds.x) ? this.bounds.x : this.tempvector.x);

if(this.bounds.y > 0.0f) this.tempvector.y = (this.tempvector.y < -this.bounds.y) ? -this.bounds.y :
((this.tempvector.y > this.bounds.y) ? this.bounds.y : this.tempvector.y);

if(this.bounds.z > 0.0f) this.tempvector.z = (this.tempvector.z < -this.bounds.z) ? -this.bounds.z :
((this.tempvector.z > this.bounds.z) ? this.bounds.z : this.tempvector.z);

if(this.origin != null) this.tempvector.add(this.origin);

this.object.clearTranslation();
this.object.translate(this.tempvector);
}

Now the problem is that when moving the object, then checking for if it's in bounds, the x and z directions work as expected, the object stops at the edge like there's an invisible wall. However the y acts funny, moving down(+) there's a bounce, and moving up(-) it takes a large value to pull it back down from the edge. I seriously have no idea why it's doing this, if anyone has an idea let me know.

The bounds are how far the object can move from it's origin, not the jPCT origin but the origin set for the actor.

59
Projects / Re: New Library And Game
« on: November 06, 2012, 11:52:50 am »
Figured I should show what the test app looks like so you can get an idea of how it's done a bit.

Code: [Select]
package app;

import java.awt.Color;
import java.awt.Container;
import java.awt.HeadlessException;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

import kitt.com.jpct.WorldManager;
import kitt.com.jpct.XMLLoader;
import kitt.com.jpct.actor.Actor;
import kitt.com.jpct.actor.ActorCameraFocal;
import kitt.com.jpct.anim.Animator;
import kitt.com.jpct.anim.AnimatorCallback;
import kitt.com.jpct.anim.AnimatorCharacter;
import kitt.com.jpct.anim.AnimatorStayWith;
import kitt.com.jpct.ext.AmbientFull;
import kitt.com.jpct.ext.LightFlicker;
import kitt.com.jpct.ext.Object3DEx;
import kitt.com.jpct.ext.RadialCamera;
import kitt.com.jpct.game.ControllerData;
import kitt.com.jpct.game.GamePads;
import kitt.com.jpct.gui.world.CanvasEventHandler;
import kitt.com.jpct.gui.world.GUIWorldEx;
import kitt.com.jpct.gui.world.WorldEventHandler;
import kitt.com.jpct.gui.world.WorldSelector;
import kitt.com.jpct.gui.world.anim.GUIAnimator;
import kitt.com.jpct.gui.world.event.Controller2ButtonBinding;
import kitt.com.jpct.gui.world.event.ControllerAxisBinding;
import kitt.com.jpct.gui.world.event.ControllerBinding;
import kitt.com.jpct.gui.world.event.ControllerButtonBinding;
import kitt.com.jpct.gui.world.event.KeyBinding;
import kitt.com.jpct.gui.world.event.KeyDualBinding;
import kitt.com.jpct.gui.world.event.KeyQuadBinding;
import kitt.com.jpct.gui.world.event.MouseBinding;
import kitt.com.jpct.gui.world.event.bind.ActorBinding;
import kitt.com.jpct.gui.world.event.bind.CanvasBinding;
import kitt.com.jpct.gui.world.event.bind.EventBinding;
import kitt.com.jpct.gui.world.event.bind.EventBindingCallback;
import kitt.com.jpct.gui.world.event.bind.GUISelectionBinding;
import kitt.com.jpct.gui.world.event.bind.GUISelectorBinding;
import kitt.com.jpct.gui.world.event.bind.GUIToggleBinding;
import kitt.com.jpct.gui.world.event.bind.RadialCameraBinding;
import kitt.com.jpct.gui.world.event.bind.WorldSelectionBinding;
import kitt.com.jpct.gui.world.event.bind.data.ToggleData;
import kitt.com.jpct.gui.world.kits.ElementKits;
import kitt.com.jpct.gui.world.kits.SelectorKit;
import kitt.com.jpct.hud.AnimatedBackground;
import kitt.com.jpct.hud.HUDBarVerUp;
import kitt.com.jpct.hud.HUDManager;
import kitt.com.jpct.hud.HUDTextLayer;
import kitt.com.jpct.hud.HUDTextureElement;
import kitt.com.jpct.swing.GLPanel;
import kitt.com.jpct.tex.LinkedTextureImage;
import kitt.com.jpct.tex.TextureImage;
import kitt.com.jpct.tex.TextureManagerEx;
import kitt.com.jpct.tex.TexturePack;
import kitt.com.jpct.tex.TextureSequence;
import kitt.com.math.ColorFloat;
import kitt.com.math.Coordinate;
import kitt.com.math.Dimension;
import kitt.com.swing.Util;
import kitt.com.swing.canvas.CanvasButton;
import kitt.com.swing.canvas.CanvasGUI;
import kitt.com.swing.canvas.CanvasLabel;
import kitt.com.swing.canvas.CanvasPointer;
import kitt.com.swing.canvas.data.CanvasImageFont;
import kitt.com.swing.canvas.kits.MenuKit;
import kitt.com.swing.canvas.kits.ToggleMenuKit;
import kitt.com.swing.canvas.kits.WidgetKits;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;

public class HUDTest extends JFrame implements EventBindingCallback, AnimatorCallback {
private static final long serialVersionUID = 1L;

private static final String modelsdir = "res/models/";
private static final String texdir = "res/tex/";

private GLPanel mainpanel = null;
private HUDManager hud = null;
private TextureImage guitexture = null;
private TextureImage barstexture = null;
private RadialCamera camera = null;
private ControllerData controller = null;
private GUIWorldEx gui3d = null;
private ActorBinding mover = null;
// private File ping = null;

private Object3DEx box = null;
private WorldEventHandler eventhandler = null;
private CanvasEventHandler canvashandler = null;
private GUIToggleBinding hextoggle = null;
private HUDTextLayer textlayer = null;
private ActorCameraFocal mainactor = null;
private AnimatorCharacter mainanimator = null;

private CanvasGUI basecanvas = null;

public HUDTest() throws HeadlessException {
this.setup();
}

private void setup() {
this.setTitle("HUD Test");
this.setBounds(0, 0, 256, 256);
this.setLocationRelativeTo(null);

this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
this.setResizable(false);
Container cpane = this.getContentPane();
cpane.setLayout(null);

this.setVisible(true);
Dimension dim = Util.getRealSize(this, 1024, 768);
Coordinate loc = Util.centerScreen(dim.width, dim.height);
this.setBounds(loc.x, loc.y, dim.width, dim.height);

Config.isIndoor = true;
Config.glFullscreen = false;
Config.glAvoidTextureCopies = true;
Config.glColorDepth = 24;
// Config.farPlane = 4000;
Config.glShadowZBias = 0.8f;
Config.lightMul = 1;
Config.collideOffset = 500;
Config.glTrilinear = true;

this.mainpanel = new GLPanel(1024, 768);
this.mainpanel.setRenderGL(false);

// AudioManager.playLoop("res/audio/music/danosongs.com-bitbybits.ogg", -5.0f);
// this.ping = new File("res/audio/effects/ping.wav");

this.basecanvas = new CanvasGUI();
this.mainpanel.setBaseCanvas(this.basecanvas);
this.basecanvas.setBackground(new Color(0,128,128,128));
this.basecanvas.setForeground(new Color(64,255,255));
this.basecanvas.setName("Main Menu");
this.basecanvas.setFont(CanvasGUI.FONTLARGE);
this.basecanvas.setTextColor(Color.WHITE);

CanvasGUI.DEFAULT_DISABLED = new Color(255,0,0,128);
CanvasGUI.DEFAULT_HOVER = new Color(0,255,0,128);
CanvasGUI.DEFAULT_PRESSED = new Color(0,0,255,128);
CanvasGUI.DEFAULT_FOREGROUND = new Color(0,255,0);
CanvasGUI.DEFAULT_BACKGROUND = CanvasGUI.HALFBLACK;;

this.canvashandler = new CanvasEventHandler(this.basecanvas);
this.canvashandler.addTo(this.basecanvas);
this.mainpanel.setCurrentEventHandler(this.canvashandler);

this.basecanvas.setFlags(CanvasGUI.ROUNDED | CanvasGUI.BORDER);

this.guitexture = TextureManagerEx.loadImageTexture("res/tex/gui/base.png", "gui", true, true);
this.barstexture = TextureManagerEx.loadImageTexture("res/tex/gui/bars-ver.png", "bars", true, true);
TextureImage timage = TextureManagerEx.loadImageTexture("res/tex/font-base.png", "font", true, true);
CanvasGUI.IMAGEFONT = new CanvasImageFont(timage.getImage(), 32, 32);
CanvasGUI.IMAGEFONT.setBaseline(8);
CanvasGUI.IMAGEFONT.setAsciiOffset(32);
CanvasGUI.IMAGEFONT.setScale(0.5f);
TexturePack icons = XMLLoader.loadPackFromXML("res/xml/texpack-icons.xml", HUDTest.texdir, this.gui3d);

TextureImage image = TextureManagerEx.loadImageTexture("res/tex/icons/icon-logo-full.png", "icon-logo", true, true);
CanvasLabel label = new CanvasLabel(null, "Hacker's\nHaven", 100, 50, 100, 100);
label.setFlags(CanvasGUI.ROUNDED | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
CanvasGUI.TEXT_LEFT | CanvasGUI.TEXT_TOP | CanvasGUI.IMAGE_STRETCH);
label.setImage(image.getImage());
this.basecanvas.addWidget(label);

CanvasButton button = new CanvasButton(null, "Pause", 0, 0, 100, 100);
button.setID("Pause");
this.basecanvas.addWidget(button);

String[][] options = {
{"GameStart", "Start"},
{"GameLoad", "Load"},
{"GameConfigure", "Settings"},
{"GameDelete", "Delete"},
{"GameExit", "Exit"}
};
MenuKit menu = WidgetKits.makeMenu(this.basecanvas, "Main Menu",
null, 150, 40,
options, 3, -1);
menu.parent.setLocation(200, 250);
menu.parent.setEnabled(false);

CanvasGUI.DEFAULT_FOREGROUND = new Color(0,255,255);

String[][] toptions = {
{"GameFun", "Fun"},
{"GameWicked", "Wicked"},
{"GameCool", "Cool"},
{"GameRun", "Run"}
};
ToggleMenuKit togglemenu = WidgetKits.makeToggleMenu(this.basecanvas, "Sub Menu",
null, 150, 40,
toptions, 2, CanvasGUI.HEXAGONAL | CanvasGUI.BORDER | CanvasGUI.SHOWTEXT |
CanvasGUI.TEXT_RIGHT | CanvasGUI.TEXT_BOTTOM | CanvasGUI.FILL  | CanvasGUI.IMAGE_STRETCH);
togglemenu.parent.setLocation(400, 50);
togglemenu.parent.setSingleToggle(true);
for (int i = 0; i < togglemenu.options.length; i++) {
togglemenu.options[i].setImage(icons.getTextureImage(i).getImage());
}

CanvasPointer pointer = new CanvasPointer(this.guitexture.getImage());
pointer.setImageOffset(new Coordinate(0, 200));
pointer.setImagePart(new Dimension(64,64));
pointer.setSize(64, 64);
pointer.setLocation(-8, -20);
this.basecanvas.setPointer(pointer);

this.basecanvas.setBackImage(new BufferedImage(this.mainpanel.getWidth(), this.mainpanel.getHeight(),
BufferedImage.TYPE_INT_RGB));

this.guitexture.makeTexture();
this.barstexture.makeTexture();

this.mainpanel.setLocation(0, 0);
cpane.add(this.mainpanel);
this.mainpanel.alignBaseCanvas();

this.gui3d = WorldManager.createGUIWorld("GUI");

this.hud = new HUDManager();
this.eventhandler = new WorldEventHandler(this.mainpanel.getBuffer());
this.eventhandler.installFixer();

this.mainpanel.addEventHandler(this.eventhandler);
this.mainpanel.setCurrentEventHandlerGL(this.eventhandler);
this.mainpanel.setGUIWorld(this.gui3d);
this.mainpanel.setHUD(this.hud);

this.camera = new RadialCamera();
this.mainpanel.getWorld().setCameraTo(this.camera);
this.camera.setDistance(0.05f);
Camera linked = new Camera();
linked.setFOV(1.5f);
this.camera.setLinked(linked);
this.mainpanel.enableTopWorld(linked);

this.eventhandler.addWorld(this.gui3d);
this.eventhandler.addWorld(this.mainpanel.getWorld());

HUDTextureElement element = new HUDTextureElement("text", 0, 512, 1024, 256);
element.setTexture(this.guitexture, 0, 0, 1024, 200);
this.hud.add(element);

element = new HUDTextureElement("text2", 10, 548, 100, 200);
element.setTexture(this.guitexture, 0, 0, 1024, 200);
element.setZOrder(0);
element.setVisible(false);
this.hud.add(element);

HUDBarVerUp elementbar = new HUDBarVerUp("bars", 10, 680, 5, 100);
elementbar.setTexture(this.barstexture, 0, 0, 100, 512);
elementbar.setZOrder(5);
elementbar.setValue(1.0f);
this.hud.add(elementbar);

CanvasImageFont font = new CanvasImageFont(CanvasGUI.IMAGEFONT, 0.8f);

this.textlayer = new HUDTextLayer("text-layer", 0, 512, 1024, 256);
this.textlayer.setZOrder(1);
this.textlayer.setFont(font);
this.textlayer.setBorder(32);
this.hud.add(this.textlayer);

this.hud.zSort();

TextureSequence tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-dissolve.xml", HUDTest.texdir, null);
tseq.makeTexture();
tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-appear.xml", HUDTest.texdir, null);
tseq.makeTexture();
tseq = XMLLoader.loadSequenceFromXML("res/xml/texseq-grid-shine.xml", HUDTest.texdir, null);
tseq.makeTexture();

if(tseq != null) {
AnimatedBackground background = new AnimatedBackground("background", this.mainpanel.getCanvas());
background.setTexture(tseq);
background.setFullImage();
this.mainpanel.setBackgroundElement(background);
}

this.controller = GamePads.getController(0);
if (this.controller != null) {
this.controller.setEnabled(true);
System.out.println("Controller Enabled");
this.eventhandler.addController(this.controller);
this.canvashandler.addController(this.controller);
}

TextureImage concrete = TextureManagerEx.loadImageTexture("res/tex/concrete.jpg", "concrete", false, false);
concrete.makeTexture();
Object3DEx tobject = XMLLoader.loadObject("res/models/scene.obj", 1.75f);
if(tobject != null) {
tobject.setName("scene");
System.out.println("Got Scene");
tobject.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
tobject.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
tobject.rotateX((float)Math.toRadians(180.0));
tobject.setTexture("concrete");
tobject.build();
tobject.setSelectable(false);
this.mainpanel.getWorld().addObjectEx(tobject);
}


XMLLoader.loadXMLObjectCollection("res/xml/obj-hexes.xml", HUDTest.modelsdir, HUDTest.texdir, true, this.gui3d);
Object3DEx object = WorldManager.findObject(null, "hex-hor");
if(object != null) {
SelectorKit selectorkit = ElementKits.makeSelector(ElementKits.HEXAGONAL |
ElementKits.HORIZONTAL | ElementKits.OFFSETUP | ElementKits.EVENODD,
"Hex Menu", null, object, "Hex", 0.5f, 0.5f, 0.0f,
3, 3, this.gui3d, this.eventhandler);
if(selectorkit != null) {
GUIAnimator animator = new GUIAnimator();
animator.setRotationVectorY();
animator.setSpeed(0.025f);
animator.setRotationAngle((float)Math.toRadians(180.0f));

this.hextoggle = new GUIToggleBinding(null);
this.hextoggle.setAnimator(animator);
this.hextoggle.setElementArray(selectorkit.elements);
this.eventhandler.addEvent(this.hextoggle);

selectorkit.parent.translate(1.4f, -0.5f, 1.0f);
selectorkit.parent.rotateY((float)Math.toRadians(75.0));
selectorkit.parent.scale(0.125f);

TextureImage hex = TextureManagerEx.getImage(null, "hex-blank-hor");

TextureImage icon = icons.getTextureImage("icon-buffer");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-buffer-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[0].setTexture(tex.getName());
selectorkit.elements[0].flipUVVert();
tex.setOwner(selectorkit.elements[0]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-clone");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-clone-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[1].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[1]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-crash-bomb");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-crash-bomb-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[2].setTexture(tex.getName());
selectorkit.elements[2].flipUVVert();
tex.setOwner(selectorkit.elements[2]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-decode");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-decode-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[3].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[3]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-deflector");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-deflector-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[4].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[4]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-firewall");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-firewall-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[5].setTexture(tex.getName());
selectorkit.elements[5].flipUVVert();
tex.setOwner(selectorkit.elements[5]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-mask");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-mask-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[6].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[6]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-slicer");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-slicer-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[7].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[7]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-spy-bot");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-spy-bot-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[8].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[8]);
TextureManagerEx.addImage(tex);
}
icon = icons.getTextureImage("icon-torrent");
if(icon != null && hex != null) {
TextureImage tex = new TextureImage(hex, "hex-torrent-hor", false, true);
tex.paintOnto(icon, 132, 139, 120, 110, false, false);
tex.paintOnto(icon, 132, 7, 120, 110, false, true);
tex.makeTexture();
selectorkit.elements[9].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[9]);
TextureManagerEx.addImage(tex);
}
}
}

GUIAnimator inanim = new GUIAnimator();
inanim.setTranslation(0.0f, 0.0f, -0.5f);
inanim.setSpeed(0.08f);

object = WorldManager.findObject(null, "panel-hex");
if(object != null) {
object.setRelativeRotationPivot(-1.0f, 0.0f, 0.0f);
SelectorKit selectorkit = ElementKits.makeMenuSelector("Panel Menu",
inanim, object, "Panel", 0.5f, 0.5f, 0.0f,
7, this.gui3d, this.eventhandler);
if(selectorkit != null) {
ToggleData toggledata = new ToggleData("Panel-0", this.hextoggle.getElementArray());
toggledata.states[0] = true;
toggledata.states[7] = true;
toggledata.states[8] = true;
this.hextoggle.setToggleSet(toggledata);

toggledata = new ToggleData("Panel-1", this.hextoggle.getElementArray());
toggledata.states[1] = true;
toggledata.states[4] = true;
toggledata.states[9] = true;
this.hextoggle.setToggleSet(toggledata);

GUISelectorBinding sevent = new GUISelectorBinding(null, selectorkit.selector);
sevent.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.DIRECTIONAL, ControllerBinding.YDIRECTION));
sevent.setController(this.controller);
sevent.setWorld(this.gui3d);
this.eventhandler.addEvent(sevent);

GUIAnimator animator = new GUIAnimator();
animator.setTranslation(0.075f, 0.0f, 0.0f);
animator.setSpeed(0.08f);
animator.setBounce(true);

GUISelectionBinding event = new GUISelectionBinding(null, selectorkit.selector);
event.setAnimator(animator);
event.setMouseEvent(new MouseBinding(EventBinding.MOUSE_CLICK, 1, 0, 1, 0));
event.setControllerEvent(new ControllerButtonBinding(false, 1));
event.setController(this.controller);
event.setKeyEvent(new KeyBinding('c', 0, EventBinding.KEY_TYPED));
event.setWorld(this.gui3d);
event.setHitCheck(true);
this.eventhandler.addEvent(event);

selectorkit.parent.translate(-1.8f, -0.3f, 1.0f);
selectorkit.parent.rotateY(-(float)Math.toRadians(75.0));
selectorkit.parent.scale(0.25f);

TextureImage hex = TextureManagerEx.getImage(null, "panel-hex-blank");
if(hex != null) {
LinkedTextureImage tex = new LinkedTextureImage(hex, "panel-hex-attack", true, true);
tex.printOnto(font, "Attack", 26, 210, false, false);
tex.printOnto(font, "Attack", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[0].setTexture(tex.getName());
selectorkit.elements[0].flipUVVert();
tex.setOwner(selectorkit.elements[0]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-defend", true, true);
tex.printOnto(font, "Defend", 26, 210, false, false);
tex.printOnto(font, "Defend", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[1].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[1]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-killer", true, true);
tex.printOnto(font, "Killer", 26, 210, false, false);
tex.printOnto(font, "Killer", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[2].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[2]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-slash", true, true);
tex.printOnto(font, "Slash", 26, 210, false, false);
tex.printOnto(font, "Slash", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[3].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[3]);
TextureManagerEx.addImage(tex);

tex = new LinkedTextureImage(hex, "panel-hex-drain", true, true);
tex.printOnto(font, "Drain", 26, 210, false, false);
tex.printOnto(font, "Drain", 26, 12, false, true);
tex.makeTexture();

selectorkit.elements[4].setTexture(tex.getName());
tex.setOwner(selectorkit.elements[4]);
TextureManagerEx.addImage(tex);
}
}
}

this.box = XMLLoader.loadObjectXML("res/xml/avat-shiva.xml", HUDTest.modelsdir, HUDTest.texdir);
this.box.averageCollisionXZ();
this.box.setCollisionMode(Object3D.COLLISION_CHECK_SELF);
this.box.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
this.mainpanel.getWorld().addObjectEx(this.box);

this.camera.setObject(this.box);
this.camera.setPullIn(false);
this.camera.setDistance(0.5f);
this.camera.cameraChangeAngle(0, 0, this.mainpanel.getWorld());

tobject = XMLLoader.loadObjectXML("res/xml/obj-pointer.xml", "res/models/", "res/tex/");
if(tobject != null) {
tobject.setSelectable(false);
this.mainpanel.getTopWorld().addObjectEx(tobject);

AnimatorStayWith animator = new AnimatorStayWith(tobject);
animator.offsetAboveTarget();
animator.setSpeed(1.0f);
animator.setCamera(this.camera);
animator.setMaxDistance(20.0f);
animator.setVisibility(false);
this.mainpanel.getWorld().addActor(new Actor("Pointer", tobject, animator, this.mainpanel.getWorld(), false));

WorldSelector selector = new WorldSelector(this.mainpanel.getWorld(), this.box, animator, 10.0f);
selector.setClickOnly(true);
selector.setMaxRange(20.0f);
this.eventhandler.addWorldSelector(selector);

WorldSelectionBinding event = new WorldSelectionBinding("Object-Click", selector);
event.setMouseWheel(true);
event.setKeyEvent(new KeyDualBinding('q', 'e', 0, EventBinding.KEY_TYPED));
event.setWorld(this.mainpanel.getWorld());
event.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.DIRECTIONAL, ControllerBinding.XDIRECTION));
event.setController(this.controller);
event.setHitCheck(true);
this.eventhandler.addEvent(event);
}


this.mainanimator = new AnimatorCharacter(this.box);
this.mainanimator.setCurrentMeshAnimation("stand", false);
this.mainanimator.setCallback(this);

this.mainactor = new ActorCameraFocal("Actor", this.camera, this.mainanimator, this.mainpanel.getWorld(), true);
this.mainactor.setTeam(0);
this.mainactor.setCollision(true);
this.mainactor.setBounds(new SimpleVector(30.0f, 150.0f, 20.0f));
this.mainactor.setChangeAnimation(true);
this.mainactor.setScale(0.5f);
this.mainactor.setPickable(true);
this.mainactor.setPausable(true);
this.camera.setLinkedActor(this.mainactor);
this.mainpanel.getWorld().addActor(this.mainactor);

this.mover = new ActorBinding(null, this.mainactor);
this.mover.setController(this.controller);
this.mover.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.LEFT));
this.mover.getControllerEvent().scale = 1.0f;
this.mover.setKeyEvent(new KeyQuadBinding(KeyEvent.VK_A, KeyEvent.VK_S, KeyEvent.VK_W, KeyEvent.VK_Z,
0, EventBinding.KEY_HOLD));
this.mover.getKeyEvent().scale = 0.5f;
this.mover.getKeyEvent().continual = false;
this.eventhandler.addEvent(this.mover);

ActorBinding abind = new ActorBinding(null, this.mainactor);
abind.setEffectLift(true);
abind.setController(this.controller);
abind.setControllerEvent(new Controller2ButtonBinding(true, 4, 5));
abind.getControllerEvent().scale = 0.2f;
abind.setMouseEvent(new MouseBinding(EventBinding.MOUSE_FULL_DRAG, 2, 0, 1, EventBinding.AXIS_Y));
abind.getMouseEvent().scale = -0.5f;
this.eventhandler.addEvent(abind);

RadialCameraBinding cevent = new RadialCameraBinding(null, this.camera);
cevent.setWorld(this.mainpanel.getWorld());
cevent.setController(this.controller);
cevent.setControllerEvent(new ControllerAxisBinding(true, ControllerBinding.RIGHT));
cevent.getControllerEvent().scale = 0.025f;
cevent.setMouseEvent(new MouseBinding(EventBinding.MOUSE_FULL_DRAG, 3, 0, 1, EventBinding.AXIS_BOTH));
cevent.getMouseEvent().scale = 0.05f;
this.eventhandler.addEvent(cevent);

EventBinding gevent = new EventBinding("Pause");
gevent.setController(this.controller);
gevent.setControllerEvent(new ControllerButtonBinding(false, 9));
gevent.setKeyEvent(new KeyBinding(KeyEvent.VK_P, 0, EventBinding.KEY_PRESSED));
gevent.setCallback(this);
this.eventhandler.addEvent(gevent);
this.canvashandler.addEvent(gevent);

gevent = new EventBinding("Canvas");
gevent.setController(this.controller);
gevent.setControllerEvent(new ControllerButtonBinding(false, 3));
gevent.setKeyEvent(new KeyBinding(KeyEvent.VK_ESCAPE, 0,
EventBinding.KEY_PRESSED));
gevent.setCallback(this);
this.eventhandler.addEvent(gevent);

CanvasBinding canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new ControllerAxisBinding(false, ControllerBinding.DIRECTIONAL, ControllerBinding.BOTH));
canevent.setEffectPointer(true);
this.canvashandler.addEvent(canevent);

canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new Controller2ButtonBinding(false, 4, 5));
canevent.setNavigateWidgets(true);
this.canvashandler.addEvent(canevent);

canevent = new CanvasBinding(null, this.basecanvas);
canevent.setController(this.controller);
canevent.setControllerEvent(new ControllerButtonBinding(false, 1));
canevent.setSimulateClick(true);
this.canvashandler.addEvent(canevent);

AmbientFull fogger = new AmbientFull(this.mainpanel.getWorld());
this.mainpanel.getWorld().setAmbient(fogger);
fogger.setLight(new ColorFloat(128,128,128), new ColorFloat(200,64,64), 0.001f);
fogger.setFogging(true);
fogger.setFogger(new ColorFloat(-255.0f,128.0f,-255.0f), new ColorFloat(-255.0f,-255.0f,-255.0f));
fogger.setFogRange1(20.0f, 40.0f);
fogger.setFogRange2(50.0f, 70.0f);

LightFlicker light = new LightFlicker(this.mainpanel.getWorld(), "red");
light.set(-3, -3, -3, 255, 0, 0, 30.0f, 5.0f);
light.setFlicker(new ColorFloat(255,0,0), new ColorFloat(255,255,0), 0.01f);

light = new LightFlicker(this.mainpanel.getWorld(), "blue");
light.set(-3, -3, 3, 255, 0, 0, 30.0f, 5.0f);
light.setFlicker(new ColorFloat(0,0,255), null, 0.025f);

this.mainpanel.getWorld().addLight("main", 0, -3, 0, 255, 255, 255, 30.0f, 5.0f);
// this.mainpanel.getWorld().createTriangleStrips();
// this.gui3d.createTriangleStrips();
// this.mainpanel.getTopWorld().createTriangleStrips();
}

public static void main(String[] args) {
HUDTest app = new HUDTest();
try {
app.loop();
} catch (Exception e) {
e.printStackTrace();
}
}

private void loop() throws Exception {
System.out.println("Looping");
if(!GamePads.isInitialized()) GamePads.initialize();
this.mainpanel.setRenderGL(true);
this.textlayer.addLine("Environment simulation loaded.");
this.textlayer.addLine("Avatar Shiva loaded.");
this.textlayer.addLine("Interface initiated.");
this.textlayer.addLine("Login in progress ...");
this.mainpanel.clearTimer();

while (this.isShowing()) {
while(this.eventhandler.hasCommands() || this.canvashandler.hasCommands()) {
String tcomm = "";
if(this.eventhandler.hasCommands()) tcomm = this.eventhandler.popCommand();
else if(this.canvashandler.hasCommands()) tcomm = this.canvashandler.popCommand();
System.out.println(tcomm);
this.textlayer.addLine(tcomm);

this.hextoggle.toggleCommand(tcomm);
if(tcomm.compareTo("Panel-2") == 0) {
this.mainanimator.setCurrentMeshAnimation("access", true);
}
if(tcomm.compareTo("Panel-3") == 0) {
this.mainanimator.setCurrentMeshAnimation("delete", true);
// AudioManager.pauseLoop(true);
}
if(tcomm.compareTo("Panel-4") == 0) {
TextureSequence seq = TextureManagerEx.getSequence("dissolve");
this.mainanimator.setTextureSequence(seq);
this.mainanimator.setCurrentMeshAnimation("dissolve", false);
// AudioManager.pauseLoop(false);
}
if(tcomm.compareTo("Panel-5") == 0) {
TextureSequence seq = TextureManagerEx.getSequence("appear");
this.mainanimator.setTextureSequence(seq);
this.mainanimator.setAnimateMesh(false);
this.mainanimator.setCurrentMeshAnimation("appear", true);
// AudioManager.playEffect(this.ping);
}
if(tcomm.compareTo("Panel-6") == 0) {
this.mainanimator.setCurrentMeshAnimation("failb", true);
}
if(tcomm.compareTo("Pause") == 0) {
if(this.mainpanel.isRenderGL()) {
this.mainpanel.setPaused(!this.mainpanel.isPaused());
this.mover.setEnabled(!this.mainpanel.isPaused());
} else {
this.mainpanel.setPaused(true);
this.mover.setEnabled(false);
this.mainpanel.setRenderGL(true);
}
}
if(tcomm.compareTo("Canvas") == 0) {
if(this.mainpanel.isRenderGL()) {
this.mainpanel.snapshot(this.basecanvas.getBackImage());
this.mainpanel.setRenderGL(false);
}
}
}
this.mainpanel.renderScene();
Thread.sleep(30);
}

System.out.println("Exiting!");
this.mainpanel.dispose();
this.eventhandler.removeFixer();
System.exit(0);
}

@Override
public boolean eventCall(int event, EventBinding binding) {
System.out.println("Callback!");
return true;
}

@Override
public void animateCallback(Animator animator, int event) {
if(animator == this.mainanimator) {
if(event == AnimatorCallback.TEXTURE_DONE) {
this.mainanimator.setAnimateMesh(true);
}
if(event == AnimatorCallback.MESH_DONE) {

}
}
}

}

I really suck with comments, so I don't actually put many inside my code itself, so sorry about that. Anyhow, this is the mucky way of making an app with the library, but it demonstrates (tests) a lot of the core methods and objects so that's why it's mucky instead of well done. A real app would be written much cleaner, but this is the one used for the screenshots.

An example XML file used, the avat-shiva.xml
Code: [Select]
<?xml version="1.0"?>
<base>
    <type>md2</type>
    <filename>avatars/shiva.md2</filename>
    <scale>1.0</scale>
    <object>
        <model name="Shiva-0_Shiva">
            <name>avatar-shiva</name>
            <setting name="EnvMap">false</setting>
            <setting name="Culling">true</setting>
            <setting name="Compile">true</setting>
            <setting name="Specular">true</setting>
            <setting name="Transparency">128</setting>
            <setting name="CollisionEllipse">1.0</setting>
            <setting name="Color">128,128,128</setting>
        </model>
        <animations>
            <sequence name="faila" cyclic="false">0.01</sequence>
            <sequence name="run" cyclic="true">0.01</sequence>
            <sequence name="appear" cyclic="false">0.01</sequence>
            <sequence name="scan" cyclic="true">0.005</sequence>
            <sequence name="walk" cyclic="true">0.005</sequence>
            <sequence name="access" cyclic="false">0.0075</sequence>
            <sequence name="failb" cyclic="false">0.01</sequence>
            <sequence name="stand" cyclic="true">0.005</sequence>
            <sequence name="dissolve" cyclic="false">0.02</sequence>
            <sequence name="delete" cyclic="false">0.02</sequence>
        </animations>
        <textures speed="0.05" usealpha="true">
            <sequence>shiva-ice</sequence>
            <texture index="0" maintain="false">
                <name>shiva-1</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00000.png</filename>
            </texture>
            <texture index="1" maintain="false">
                <name>shiva-2</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00001.png</filename>
            </texture>
            <texture index="2" maintain="false">
                <name>shiva-3</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00002.png</filename>
            </texture>
            <texture index="3" maintain="false">
                <name>shiva-4</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00003.png</filename>
            </texture>
            <texture index="4" maintain="false">
                <name>shiva-5</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00004.png</filename>
            </texture>
            <texture index="5" maintain="false">
                <name>shiva-6</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00005.png</filename>
            </texture>
            <texture index="6" maintain="false">
                <name>shiva-7</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00006.png</filename>
            </texture>
            <texture index="7" maintain="false">
                <name>shiva-8</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00007.png</filename>
            </texture>
            <texture index="8" maintain="false">
                <name>shiva-9</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00008.png</filename>
            </texture>
            <texture index="9" maintain="false">
                <name>shiva-10</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
                <filename layer="1">avatars/ice-ripple/00009.png</filename>
            </texture>
            <texture index="10" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="11" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="12" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="13" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="14" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="15" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="16" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="17" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="18" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="19" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="20" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="21" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
            <texture index="22" maintain="false">
                <name>shiva-0</name>
                <filename layer="0">avatars/shiva-outer.png</filename>
            </texture>
        </textures>
    </object>
</base>

60
Projects / Re: New Library And Game
« on: November 06, 2012, 06:05:54 am »
Nice. I like the 3d effect. Does it render the labels by itself or are they part of a texture?

They are rendered onto the texture. There is a method in the Image/Texture class that allows you to make it dynamic using an texture effect interface, which is actually an alternate class to conserve memory. The image font class I wrote for the Canvas widgets is used for the printing onto the texture. If you use the dynamic interface then you can call a method in the image/texture object to update the texture easily. The text display at the bottom uses the same method, instead of blitting every letter.

Basically, it takes a BufferedImage, keeps the image in memory, and when you change the image you call the update method and that change is made to the texture using jPCT's texture effect interface. There is also a loader, which I need to work on a bit more as it's highly inefficient yet, that will combine two images to produce the texture, using BufferedImage of course. The green icons on that screen shot uses that specific technique as well. The icons and blank model texture are loaded as buffered images, then the you duplicate the blank one, paint the icon onto it, and it creates the texture. Though those I did not use dynamic texture images since they only needed to do that once. The model texture for the widgets I used a half texture for each of the color sets, so one texture has two color sets, and just flipped the U or V based on the orientation. Still working on how to simplify that process, it may not be something that can be simplified, but I extended the Object3D to include two methods, one for flipping the U the other for flipping the V, to make that part easier.

Pages: 1 2 3 [4] 5