Initial commit

This commit is contained in:
Antonio Niño Díaz 2022-10-10 19:06:21 +01:00
commit cf298c29e9
47 changed files with 7272 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
*.swp
__pycache__/
*.bin
*.dsa
*.dsm
build/
*.nds
*.elf

View File

@ -0,0 +1,220 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files embedded using bin2o
# GRAPHICS is a list of directories containing image files to be converted with grit
# AUDIO is a list of directories containing audio to be converted by maxmod
# ICON is the image used to create the game icon, leave blank to use default rule
# NITRO is a directory that will be accessible via NitroFS
#---------------------------------------------------------------------------------
TARGET := $(shell basename $(CURDIR))
BUILD := build
SOURCES := source source/dsma
INCLUDES := include
DATA := data
GRAPHICS :=
AUDIO :=
ICON :=
# specify a directory which contains the nitro filesystem
# this is relative to the Makefile
NITRO :=
# These set the information text in the nds file
GAME_TITLE := DSMA Example
GAME_SUBTITLE1 := built with devkitARM
GAME_SUBTITLE2 := http://devitpro.org
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s
CFLAGS := -g -Wall -O3\
$(ARCH) $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS := -lnds9
# automatigically add libraries for NitroFS
ifneq ($(strip $(NITRO)),)
LIBS := -lfilesystem -lfat $(LIBS)
endif
# automagically add maxmod library
ifneq ($(strip $(AUDIO)),)
LIBS := -lmm9 $(LIBS)
endif
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS) $(PORTLIBS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(CURDIR)/$(subst /,,$(dir $(ICON)))\
$(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
$(foreach dir,$(DATA),$(CURDIR)/$(dir))\
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
# prepare NitroFS directory
ifneq ($(strip $(NITRO)),)
export NITRO_FILES := $(CURDIR)/$(NITRO)
endif
# get audio list for maxmod
ifneq ($(strip $(AUDIO)),)
export MODFILES := $(foreach dir,$(notdir $(wildcard $(AUDIO)/*.*)),$(CURDIR)/$(AUDIO)/$(dir))
# place the soundbank file in NitroFS if using it
ifneq ($(strip $(NITRO)),)
export SOUNDBANK := $(NITRO_FILES)/soundbank.bin
# otherwise, needs to be loaded from memory
else
export SOUNDBANK := soundbank.bin
BINFILES += $(SOUNDBANK)
endif
endif
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.bmp)
ifneq (,$(findstring $(TARGET).bmp,$(icons)))
export GAME_ICON := $(CURDIR)/$(TARGET).bmp
else
ifneq (,$(findstring icon.bmp,$(icons)))
export GAME_ICON := $(CURDIR)/icon.bmp
endif
endif
else
ifeq ($(suffix $(ICON)), .grf)
export GAME_ICON := $(CURDIR)/$(ICON)
else
export GAME_ICON := $(CURDIR)/$(BUILD)/$(notdir $(basename $(ICON))).grf
endif
endif
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(SOUNDBANK)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds: $(OUTPUT).elf $(GAME_ICON)
$(OUTPUT).elf: $(OFILES)
# source files depend on generated headers
$(OFILES_SOURCES) : $(HFILES)
# need to build soundbank first
$(OFILES): $(SOUNDBANK)
#---------------------------------------------------------------------------------
# rule to build solution from music files
#---------------------------------------------------------------------------------
$(SOUNDBANK) : $(MODFILES)
#---------------------------------------------------------------------------------
mmutil $^ -d -o$@ -hsoundbank.h
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
# This rule creates assembly source files using grit
# grit takes an image file and a .grit describing how the file is to be processed
# add additional rules like this for each image extension
# you use in the graphics folders
#---------------------------------------------------------------------------------
%.s %.h: %.png %.grit
#---------------------------------------------------------------------------------
grit $< -fts -o$*
#---------------------------------------------------------------------------------
# Convert non-GRF game icon to GRF if needed
#---------------------------------------------------------------------------------
$(GAME_ICON): $(notdir $(ICON))
#---------------------------------------------------------------------------------
@echo convert $(notdir $<)
@grit $< -g -gt -gB4 -gT FF00FF -m! -p -pe 16 -fh! -ftr
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,14 @@
#!/bin/sh
TOOLS=../../tools
ROBOT=../../models/robot
python3 $TOOLS/md5_to_dsma.py \
--model $ROBOT/Robot.md5mesh \
--name robot \
--output data \
--texture 128 128 \
--anim $ROBOT/Walk.md5anim \
--skip-frames 1 \
--bin \
--blender-fix

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1 @@
../../../library

View File

@ -0,0 +1,145 @@
// SPDX-License-Identifier: CC0-1.0
//
// SPDX-FileContributor: Antonio Niño Díaz, 2022
#include <stdio.h>
#include <nds.h>
#include "dsma/dsma.h"
// Animated models
#include "robot_dsm_bin.h"
// Animations
#include "robot_walk_dsa_bin.h"
// Textures
#include "texture128_bin.h"
void setup_video(void)
{
videoSetMode(MODE_0_3D);
vramSetBankA(VRAM_A_TEXTURE);
consoleDemoInit();
glInit();
glEnable(GL_ANTIALIAS);
glEnable(GL_TEXTURE_2D);
// Setup the rear plane
glClearColor(2, 2, 2, 31); // BG must be opaque for AA to work
glClearPolyID(63); // BG must have a unique polygon ID for AA to work
glClearDepth(0x7FFF);
glViewport(0, 0, 255, 191);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
glLight(0, RGB15(0, 31, 0), 0, floattov10(0.8), floattov10(-0.2));
glLight(1, RGB15(31, 0, 0), 0, floattov10(-0.8), floattov10(-0.2));
glLight(2, RGB15(31, 31, 0), floattov10(0.7), 0, floattov10(-0.7));
glLight(3, RGB15(0, 0, 31), floattov10(-0.7), 0, floattov10(-0.7));
glMaterialf(GL_AMBIENT, RGB15(0, 0, 0));
glMaterialf(GL_DIFFUSE, RGB15(31, 31, 31));
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(0, 0, 0));
glMaterialf(GL_EMISSION, RGB15(0, 0, 0));
glMaterialShinyness();
glMatrixMode(GL_MODELVIEW);
//glMatrixMode(GL_POSITION); // This rotates lights with the model
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 |
POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3);
}
int main(void)
{
// Basic 3D setup, mostly from libnds examples
setup_video();
// Load texture
int textureID;
glGenTextures(1, &textureID);
glBindTexture(0, textureID);
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128, TEXTURE_SIZE_128, 0,
TEXGEN_TEXCOORD, (u8*)texture128_bin);
// Get pointers to the animated model files
const void *dsa_file = robot_walk_dsa_bin;
const void *dsm_file = robot_dsm_bin;
// Obtain number of frames in the animation
const uint32_t num_frames = DSMA_GetNumFrames(dsa_file);
printf("\x1b[1;0HAnimate model: L/R");
printf("\x1b[2;0HRotate model: Direction pad");
printf("\x1b[3;0HExit demo: START");
int32_t frame = 0;
float rotateY = 0.0;
float rotateZ = 0.0;
while(1)
{
glLoadIdentity();
gluLookAt(8.0, 3.0, 0.0, // camera possition
0.0, 3.0, 0.0, // look at
0.0, 1.0, 0.0); // up
// Draw animated model
glPushMatrix();
{
glRotateY(rotateY);
glRotateZ(rotateZ);
glBindTexture(0, textureID);
DSMA_DrawModel(dsm_file, dsa_file, frame);
}
glPopMatrix(1);
scanKeys();
u16 keys_held = keysHeld();
if (keys_held & KEY_UP)
rotateZ += 3;
if (keys_held & KEY_DOWN)
rotateZ -= 3;
if (keys_held & KEY_LEFT)
rotateY -= 3;
if (keys_held & KEY_RIGHT)
rotateY += 3;
printf("\x1b[11;0HCurrent frame: %.2f ", f32tofloat(frame));
if (keys_held & KEY_R)
{
frame += 1 << 9;
if (frame >= (num_frames << 12))
frame -= num_frames << 12;
}
if (keys_held & KEY_L)
{
frame -= 1 << 9;
if (frame < 0)
frame += num_frames << 12;
}
glFlush(0);
swiWaitForVBlank();
if (keys_held & KEY_START)
break;
}
return 0;
}

View File

@ -0,0 +1,220 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files embedded using bin2o
# GRAPHICS is a list of directories containing image files to be converted with grit
# AUDIO is a list of directories containing audio to be converted by maxmod
# ICON is the image used to create the game icon, leave blank to use default rule
# NITRO is a directory that will be accessible via NitroFS
#---------------------------------------------------------------------------------
TARGET := $(shell basename $(CURDIR))
BUILD := build
SOURCES := source source/dsma
INCLUDES := include
DATA :=
GRAPHICS :=
AUDIO :=
ICON :=
# specify a directory which contains the nitro filesystem
# this is relative to the Makefile
NITRO := nitrofiles
# These set the information text in the nds file
GAME_TITLE := DSMA Example
GAME_SUBTITLE1 := built with devkitARM
GAME_SUBTITLE2 := http://devitpro.org
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s
CFLAGS := -g -Wall -O3\
$(ARCH) $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS := -lnds9
# automatigically add libraries for NitroFS
ifneq ($(strip $(NITRO)),)
LIBS := -lfilesystem -lfat $(LIBS)
endif
# automagically add maxmod library
ifneq ($(strip $(AUDIO)),)
LIBS := -lmm9 $(LIBS)
endif
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS) $(PORTLIBS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(CURDIR)/$(subst /,,$(dir $(ICON)))\
$(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
$(foreach dir,$(DATA),$(CURDIR)/$(dir))\
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
# prepare NitroFS directory
ifneq ($(strip $(NITRO)),)
export NITRO_FILES := $(CURDIR)/$(NITRO)
endif
# get audio list for maxmod
ifneq ($(strip $(AUDIO)),)
export MODFILES := $(foreach dir,$(notdir $(wildcard $(AUDIO)/*.*)),$(CURDIR)/$(AUDIO)/$(dir))
# place the soundbank file in NitroFS if using it
ifneq ($(strip $(NITRO)),)
export SOUNDBANK := $(NITRO_FILES)/soundbank.bin
# otherwise, needs to be loaded from memory
else
export SOUNDBANK := soundbank.bin
BINFILES += $(SOUNDBANK)
endif
endif
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.bmp)
ifneq (,$(findstring $(TARGET).bmp,$(icons)))
export GAME_ICON := $(CURDIR)/$(TARGET).bmp
else
ifneq (,$(findstring icon.bmp,$(icons)))
export GAME_ICON := $(CURDIR)/icon.bmp
endif
endif
else
ifeq ($(suffix $(ICON)), .grf)
export GAME_ICON := $(CURDIR)/$(ICON)
else
export GAME_ICON := $(CURDIR)/$(BUILD)/$(notdir $(basename $(ICON))).grf
endif
endif
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(SOUNDBANK)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds: $(OUTPUT).elf $(GAME_ICON)
$(OUTPUT).elf: $(OFILES)
# source files depend on generated headers
$(OFILES_SOURCES) : $(HFILES)
# need to build soundbank first
$(OFILES): $(SOUNDBANK)
#---------------------------------------------------------------------------------
# rule to build solution from music files
#---------------------------------------------------------------------------------
$(SOUNDBANK) : $(MODFILES)
#---------------------------------------------------------------------------------
mmutil $^ -d -o$@ -hsoundbank.h
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
# This rule creates assembly source files using grit
# grit takes an image file and a .grit describing how the file is to be processed
# add additional rules like this for each image extension
# you use in the graphics folders
#---------------------------------------------------------------------------------
%.s %.h: %.png %.grit
#---------------------------------------------------------------------------------
grit $< -fts -o$*
#---------------------------------------------------------------------------------
# Convert non-GRF game icon to GRF if needed
#---------------------------------------------------------------------------------
$(GAME_ICON): $(notdir $(ICON))
#---------------------------------------------------------------------------------
@echo convert $(notdir $<)
@grit $< -g -gt -gB4 -gT FF00FF -m! -p -pe 16 -fh! -ftr
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,13 @@
#!/bin/sh
TOOLS=../../tools
ROBOT=../../models/robot
python3 $TOOLS/md5_to_dsma.py \
--model $ROBOT/Robot.md5mesh \
--name robot \
--output nitrofiles \
--texture 128 128 \
--anim $ROBOT/Walk.md5anim \
--skip-frames 1 \
--blender-fix

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -0,0 +1 @@
../../../library

View File

@ -0,0 +1,220 @@
// SPDX-License-Identifier: CC0-1.0
//
// SPDX-FileContributor: Antonio Niño Díaz, 2022
#include <stdbool.h>
#include <stdio.h>
#include <filesystem.h>
#include <nds.h>
#include "dsma/dsma.h"
int file_load(const char *filename, void **buffer, size_t *size_)
{
FILE *f = fopen(filename, "rb");
size_t size;
*buffer = NULL;
if (size_)
*size_ = 0;
if (f == NULL)
{
iprintf("%s couldn't be opened!\n", filename);
return -1;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
if (size_)
*size_ = size;
if (size == 0)
{
iprintf("Size of %s is 0!\n", filename);
fclose(f);
return -1;
}
rewind(f);
*buffer = malloc(size);
if (*buffer == NULL)
{
iprintf("Not enought memory to load %s!\n", filename);
fclose(f);
return -1;
}
if (fread(*buffer, size, 1, f) != 1)
{
iprintf("Error while reading: %s\n", filename);
fclose(f);
free(*buffer);
return -1;
}
fclose(f);
return 0;
}
void setup_video(void)
{
videoSetMode(MODE_0_3D);
vramSetBankA(VRAM_A_TEXTURE);
consoleDemoInit();
glInit();
glEnable(GL_ANTIALIAS);
glEnable(GL_TEXTURE_2D);
// Setup the rear plane
glClearColor(2, 2, 2, 31); // BG must be opaque for AA to work
glClearPolyID(63); // BG must have a unique polygon ID for AA to work
glClearDepth(0x7FFF);
glViewport(0, 0, 255, 191);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
glLight(0, RGB15(0, 31, 0), 0, floattov10(0.8), floattov10(-0.2));
glLight(1, RGB15(31, 0, 0), 0, floattov10(-0.8), floattov10(-0.2));
glLight(2, RGB15(31, 31, 0), floattov10(0.7), 0, floattov10(-0.7));
glLight(3, RGB15(0, 0, 31), floattov10(-0.7), 0, floattov10(-0.7));
glMaterialf(GL_AMBIENT, RGB15(0, 0, 0));
glMaterialf(GL_DIFFUSE, RGB15(31, 31, 31));
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(0, 0, 0));
glMaterialf(GL_EMISSION, RGB15(0, 0, 0));
glMaterialShinyness();
glMatrixMode(GL_MODELVIEW);
//glMatrixMode(GL_POSITION); // This rotates lights with the model
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 |
POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3);
}
int main(void)
{
// Basic 3D setup, mostly from libnds examples
setup_video();
if (!nitroFSInit(NULL))
{
iprintf("nitroFSInit failed.\nPress START to exit");
while(1)
{
swiWaitForVBlank();
scanKeys();
if (keysHeld()&KEY_START)
return 0;
}
}
// Load files from the filesystem
void *texture128, *dsa_file, *dsm_file;
size_t texture128_size, dsa_file_size, dsm_file_size;
int ret = 0;
ret |= file_load("robot.dsm", &dsm_file, &dsm_file_size);
ret |= file_load("robot_walk.dsa", &dsa_file, &dsa_file_size);
ret |= file_load("texture128.bin", &texture128, &texture128_size);
if (ret)
{
iprintf("Press START to exit");
while(1)
{
swiWaitForVBlank();
scanKeys();
if (keysHeld()&KEY_START)
return 0;
}
}
printf("\x1b[20;0HLoaded files:");
printf("\x1b[21;0HDSM: %8zu bytes", dsm_file_size);
printf("\x1b[22;0HDSA: %8zu bytes", dsa_file_size);
printf("\x1b[23;0HTexture: %8zu bytes", texture128_size);
// Load texture
int textureID;
glGenTextures(1, &textureID);
glBindTexture(0, textureID);
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128, TEXTURE_SIZE_128, 0,
TEXGEN_TEXCOORD, texture128);
// Obtain number of frames in the animation
const uint32_t num_frames = DSMA_GetNumFrames(dsa_file);
printf("\x1b[1;0HAnimate model: L/R");
printf("\x1b[2;0HRotate model: Direction pad");
printf("\x1b[3;0HExit demo: START");
int32_t frame = 0;
float rotateY = 0.0;
float rotateZ = 0.0;
while(1)
{
glLoadIdentity();
gluLookAt(8.0, 3.0, 0.0, // camera possition
0.0, 3.0, 0.0, // look at
0.0, 1.0, 0.0); // up
// Draw animated model
glPushMatrix();
{
glRotateY(rotateY);
glRotateZ(rotateZ);
glBindTexture(0, textureID);
DSMA_DrawModel(dsm_file, dsa_file, frame);
}
glPopMatrix(1);
scanKeys();
u16 keys_held = keysHeld();
if (keys_held & KEY_UP)
rotateZ += 3;
if (keys_held & KEY_DOWN)
rotateZ -= 3;
if (keys_held & KEY_LEFT)
rotateY -= 3;
if (keys_held & KEY_RIGHT)
rotateY += 3;
printf("\x1b[11;0HCurrent frame: %.2f ", f32tofloat(frame));
if (keys_held & KEY_R)
{
frame += 1 << 9;
if (frame >= (num_frames << 12))
frame -= num_frames << 12;
}
if (keys_held & KEY_L)
{
frame -= 1 << 9;
if (frame < 0)
frame += num_frames << 12;
}
glFlush(0);
swiWaitForVBlank();
if (keys_held & KEY_START)
break;
}
return 0;
}

View File

@ -0,0 +1,220 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files embedded using bin2o
# GRAPHICS is a list of directories containing image files to be converted with grit
# AUDIO is a list of directories containing audio to be converted by maxmod
# ICON is the image used to create the game icon, leave blank to use default rule
# NITRO is a directory that will be accessible via NitroFS
#---------------------------------------------------------------------------------
TARGET := $(shell basename $(CURDIR))
BUILD := build
SOURCES := source source/dsma
INCLUDES := include
DATA := data
GRAPHICS :=
AUDIO :=
ICON :=
# specify a directory which contains the nitro filesystem
# this is relative to the Makefile
NITRO :=
# These set the information text in the nds file
GAME_TITLE := DSMA Example
GAME_SUBTITLE1 := built with devkitARM
GAME_SUBTITLE2 := http://devitpro.org
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s
CFLAGS := -g -Wall -O3\
$(ARCH) $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS := -lnds9
# automatigically add libraries for NitroFS
ifneq ($(strip $(NITRO)),)
LIBS := -lfilesystem -lfat $(LIBS)
endif
# automagically add maxmod library
ifneq ($(strip $(AUDIO)),)
LIBS := -lmm9 $(LIBS)
endif
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS) $(PORTLIBS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(CURDIR)/$(subst /,,$(dir $(ICON)))\
$(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
$(foreach dir,$(DATA),$(CURDIR)/$(dir))\
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
# prepare NitroFS directory
ifneq ($(strip $(NITRO)),)
export NITRO_FILES := $(CURDIR)/$(NITRO)
endif
# get audio list for maxmod
ifneq ($(strip $(AUDIO)),)
export MODFILES := $(foreach dir,$(notdir $(wildcard $(AUDIO)/*.*)),$(CURDIR)/$(AUDIO)/$(dir))
# place the soundbank file in NitroFS if using it
ifneq ($(strip $(NITRO)),)
export SOUNDBANK := $(NITRO_FILES)/soundbank.bin
# otherwise, needs to be loaded from memory
else
export SOUNDBANK := soundbank.bin
BINFILES += $(SOUNDBANK)
endif
endif
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.bmp)
ifneq (,$(findstring $(TARGET).bmp,$(icons)))
export GAME_ICON := $(CURDIR)/$(TARGET).bmp
else
ifneq (,$(findstring icon.bmp,$(icons)))
export GAME_ICON := $(CURDIR)/icon.bmp
endif
endif
else
ifeq ($(suffix $(ICON)), .grf)
export GAME_ICON := $(CURDIR)/$(ICON)
else
export GAME_ICON := $(CURDIR)/$(BUILD)/$(notdir $(basename $(ICON))).grf
endif
endif
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(SOUNDBANK)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds: $(OUTPUT).elf $(GAME_ICON)
$(OUTPUT).elf: $(OFILES)
# source files depend on generated headers
$(OFILES_SOURCES) : $(HFILES)
# need to build soundbank first
$(OFILES): $(SOUNDBANK)
#---------------------------------------------------------------------------------
# rule to build solution from music files
#---------------------------------------------------------------------------------
$(SOUNDBANK) : $(MODFILES)
#---------------------------------------------------------------------------------
mmutil $^ -d -o$@ -hsoundbank.h
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
# This rule creates assembly source files using grit
# grit takes an image file and a .grit describing how the file is to be processed
# add additional rules like this for each image extension
# you use in the graphics folders
#---------------------------------------------------------------------------------
%.s %.h: %.png %.grit
#---------------------------------------------------------------------------------
grit $< -fts -o$*
#---------------------------------------------------------------------------------
# Convert non-GRF game icon to GRF if needed
#---------------------------------------------------------------------------------
$(GAME_ICON): $(notdir $(ICON))
#---------------------------------------------------------------------------------
@echo convert $(notdir $<)
@grit $< -g -gt -gB4 -gT FF00FF -m! -p -pe 16 -fh! -ftr
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,15 @@
#!/bin/sh
TOOLS=../../tools
ROBOT=../../models/robot
python3 $TOOLS/md5_to_dsma.py \
--model $ROBOT/Robot.md5mesh \
--name robot \
--output data \
--texture 128 128 \
--anim $ROBOT/Bow.md5anim $ROBOT/Walk.md5anim $ROBOT/Wave.md5anim \
--skip-frames 1 \
--bin \
--blender-fix \
--export-base-pose

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1 @@
../../../library

View File

@ -0,0 +1,234 @@
#include <stdio.h>
#include <nds.h>
#include "dsma/dsma.h"
// Animated models
#include "robot_dsm_bin.h"
// Animations
#include "robot_dsa_bin.h"
#include "robot_bow_dsa_bin.h"
#include "robot_walk_dsa_bin.h"
#include "robot_wave_dsa_bin.h"
// Textures
#include "texture128_bin.h"
// Static models
#include "ball_bin.h"
void setup_video(void)
{
videoSetMode(MODE_0_3D);
vramSetBankA(VRAM_A_TEXTURE);
consoleDemoInit();
glInit();
glEnable(GL_ANTIALIAS);
glEnable(GL_TEXTURE_2D);
// Setup the rear plane
glClearColor(2, 2, 2, 31); // BG must be opaque for AA to work
glClearPolyID(63); // BG must have a unique polygon ID for AA to work
glClearDepth(0x7FFF);
glViewport(0, 0, 255, 191);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
glLight(0, RGB15(0, 31, 0), 0, floattov10(0.8), floattov10(-0.2));
glLight(1, RGB15(31, 0, 0), 0, floattov10(-0.8), floattov10(-0.2));
glLight(2, RGB15(31, 31, 0), floattov10(0.7), 0, floattov10(-0.7));
glLight(3, RGB15(0, 0, 31), floattov10(-0.7), 0, floattov10(-0.7));
glMaterialf(GL_AMBIENT, RGB15(0, 0, 0));
glMaterialf(GL_DIFFUSE, RGB15(31, 31, 31));
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(0, 0, 0));
glMaterialf(GL_EMISSION, RGB15(0, 0, 0));
glMaterialShinyness();
glMatrixMode(GL_MODELVIEW);
//glMatrixMode(GL_POSITION); // This rotates lights with the model
}
int main(void)
{
float rotateY = 0.0;
float rotateZ = 0.0;
setup_video();
int textureID;
glGenTextures(1, &textureID);
glBindTexture(0, textureID);
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128, TEXTURE_SIZE_128, 0,
TEXGEN_TEXCOORD, (u8*)texture128_bin);
const void *animations[] = {
robot_wave_dsa_bin,
robot_bow_dsa_bin,
robot_walk_dsa_bin,
robot_dsa_bin,
};
const char *names[] = {
"Wave ",
"Bow ",
"Walk ",
"Base Pose"
};
const size_t num_animations = sizeof(animations) / sizeof(animations[0]);
int curr_animation = 0;
const void *dsa_file = NULL;
const void *dsm_file = robot_dsm_bin;
int32_t frame = 0;
printf("\x1b[0;0HSwitch animation: X/Y");
printf("\x1b[1;0HAnimate model: L/R");
printf("\x1b[2;0HRotate model: Direction pad");
printf("\x1b[3;0HExit demo: START");
while(1)
{
dsa_file = animations[curr_animation];
uint32_t num_frames = DSMA_GetNumFrames(dsa_file);
printf("\x1b[10;0HAnimation: %s ", names[curr_animation]);
printf("\x1b[11;0HCurrent frame: %.2f ", f32tofloat(frame));
glLoadIdentity();
gluLookAt(8.0, 3.0, 0.0, // camera possition
0.0, 3.0, 0.0, // look at
0.0, 1.0, 0.0); // up
glPushMatrix();
{
glRotateY(rotateY);
glRotateZ(rotateZ);
glBindTexture(0, textureID);
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 |
POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3);
cpuStartTiming(0);
DSMA_DrawModel(dsm_file, dsa_file, frame);
uint32_t end_time = cpuEndTiming();
const float us_per_frame = 1000000.0 / 60.0;
printf("\x1b[19;0HTime Ticks us CPU%%");
printf("\x1b[20;0HTotal: %6lu %4lu %.3f%% ",
end_time, timerTicks2usec(end_time),
100.0 * timerTicks2usec(end_time) / us_per_frame);
// Wait for geometry engine operations to end
while (GFX_STATUS & BIT(27));
printf("\x1b[23;0HPolys: %4d Vertices: %4d",
GFX_POLYGON_RAM_USAGE, GFX_VERTEX_RAM_USAGE);
// Draw axes of coordinates of the model
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
glBindTexture(0, 0);
glColor3f(1, 0, 0);
glVertex3f(0, 0.2, 0);
glVertex3f(0., -0.2, 0);
glVertex3f(5, 0, 0);
glVertex3f(0, 0, 0.2);
glVertex3f(0., 0, -0.2);
glVertex3f(5, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0.2);
glVertex3f(0, 0, -0.2);
glVertex3f(0, 5, 0);
glVertex3f(0.2, 0, 0);
glVertex3f(-0.2, 0, 0);
glVertex3f(0, 5, 0);
glColor3f(0, 0, 1);
glVertex3f(0.2, 0, 0);
glVertex3f(-0.2, 0, 0);
glVertex3f(0, 0, 5);
glVertex3f(0, 0.2, 0);
glVertex3f(0, -0.2, 0);
glVertex3f(0, 0, 5);
}
glPopMatrix(1);
// Draw a ball to use as reference for the lights
glPushMatrix();
{
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 |
POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3);
glTranslatef(0, 3, 5);
glCallList((uint32_t *)ball_bin);
}
glPopMatrix(1);
scanKeys();
u16 keys_held = keysHeld();
u16 keys_down = keysDown();
if (keys_down & KEY_X)
{
curr_animation++;
if (curr_animation >= num_animations)
curr_animation = 0;
frame = 0;
}
if (keys_down & KEY_Y)
{
curr_animation--;
if (curr_animation < 0)
curr_animation = num_animations - 1;
frame = 0;
}
if (keys_held & KEY_UP)
rotateZ += 3;
if (keys_held & KEY_DOWN)
rotateZ -= 3;
if (keys_held & KEY_LEFT)
rotateY -= 3;
if (keys_held & KEY_RIGHT)
rotateY += 3;
if (keys_held & KEY_R)
{
frame += 1 << 9;
if (frame >= (num_frames << 12))
frame -= num_frames << 12;
}
if (keys_held & KEY_L)
{
frame -= 1 << 9;
if (frame < 0)
frame += num_frames << 12;
}
glFlush(0);
swiWaitForVBlank();
if (keys_held & KEY_START)
break;
}
return 0;
}

View File

@ -0,0 +1,220 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files embedded using bin2o
# GRAPHICS is a list of directories containing image files to be converted with grit
# AUDIO is a list of directories containing audio to be converted by maxmod
# ICON is the image used to create the game icon, leave blank to use default rule
# NITRO is a directory that will be accessible via NitroFS
#---------------------------------------------------------------------------------
TARGET := $(shell basename $(CURDIR))
BUILD := build
SOURCES := source source/dsma
INCLUDES := include
DATA := data
GRAPHICS :=
AUDIO :=
ICON :=
# specify a directory which contains the nitro filesystem
# this is relative to the Makefile
NITRO :=
# These set the information text in the nds file
GAME_TITLE := DSMA Example
GAME_SUBTITLE1 := built with devkitARM
GAME_SUBTITLE2 := http://devitpro.org
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s
CFLAGS := -g -Wall -O3\
$(ARCH) $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS := -lnds9
# automatigically add libraries for NitroFS
ifneq ($(strip $(NITRO)),)
LIBS := -lfilesystem -lfat $(LIBS)
endif
# automagically add maxmod library
ifneq ($(strip $(AUDIO)),)
LIBS := -lmm9 $(LIBS)
endif
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS) $(PORTLIBS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(CURDIR)/$(subst /,,$(dir $(ICON)))\
$(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
$(foreach dir,$(DATA),$(CURDIR)/$(dir))\
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
# prepare NitroFS directory
ifneq ($(strip $(NITRO)),)
export NITRO_FILES := $(CURDIR)/$(NITRO)
endif
# get audio list for maxmod
ifneq ($(strip $(AUDIO)),)
export MODFILES := $(foreach dir,$(notdir $(wildcard $(AUDIO)/*.*)),$(CURDIR)/$(AUDIO)/$(dir))
# place the soundbank file in NitroFS if using it
ifneq ($(strip $(NITRO)),)
export SOUNDBANK := $(NITRO_FILES)/soundbank.bin
# otherwise, needs to be loaded from memory
else
export SOUNDBANK := soundbank.bin
BINFILES += $(SOUNDBANK)
endif
endif
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.bmp)
ifneq (,$(findstring $(TARGET).bmp,$(icons)))
export GAME_ICON := $(CURDIR)/$(TARGET).bmp
else
ifneq (,$(findstring icon.bmp,$(icons)))
export GAME_ICON := $(CURDIR)/icon.bmp
endif
endif
else
ifeq ($(suffix $(ICON)), .grf)
export GAME_ICON := $(CURDIR)/$(ICON)
else
export GAME_ICON := $(CURDIR)/$(BUILD)/$(notdir $(basename $(ICON))).grf
endif
endif
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(SOUNDBANK)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds: $(OUTPUT).elf $(GAME_ICON)
$(OUTPUT).elf: $(OFILES)
# source files depend on generated headers
$(OFILES_SOURCES) : $(HFILES)
# need to build soundbank first
$(OFILES): $(SOUNDBANK)
#---------------------------------------------------------------------------------
# rule to build solution from music files
#---------------------------------------------------------------------------------
$(SOUNDBANK) : $(MODFILES)
#---------------------------------------------------------------------------------
mmutil $^ -d -o$@ -hsoundbank.h
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
# This rule creates assembly source files using grit
# grit takes an image file and a .grit describing how the file is to be processed
# add additional rules like this for each image extension
# you use in the graphics folders
#---------------------------------------------------------------------------------
%.s %.h: %.png %.grit
#---------------------------------------------------------------------------------
grit $< -fts -o$*
#---------------------------------------------------------------------------------
# Convert non-GRF game icon to GRF if needed
#---------------------------------------------------------------------------------
$(GAME_ICON): $(notdir $(ICON))
#---------------------------------------------------------------------------------
@echo convert $(notdir $<)
@grit $< -g -gt -gB4 -gT FF00FF -m! -p -pe 16 -fh! -ftr
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,25 @@
#!/bin/sh
TOOLS=../../tools
QUAD=../../models/one_quad
ROBOT=../../models/robot
python3 $TOOLS/md5_to_dsma.py \
--model $QUAD/Quad.md5mesh \
--name one_quad \
--output data \
--texture 128 128 \
--anim $QUAD/Wiggle.md5anim \
--skip-frames 1 \
--bin \
--blender-fix
python3 $TOOLS/md5_to_dsma.py \
--model $ROBOT/Robot.md5mesh \
--name robot \
--output data \
--texture 128 128 \
--anim $ROBOT/Walk.md5anim \
--skip-frames 1 \
--bin \
--blender-fix

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1 @@
../../../library

View File

@ -0,0 +1,171 @@
#include <stdio.h>
#include <nds.h>
#include "dsma/dsma.h"
// Animated models
#include "one_quad_dsm_bin.h"
#include "robot_dsm_bin.h"
// Animations
#include "one_quad_wiggle_dsa_bin.h"
#include "robot_walk_dsa_bin.h"
// Textures
#include "texture128_bin.h"
void setup_video(void)
{
videoSetMode(MODE_0_3D);
vramSetBankA(VRAM_A_TEXTURE);
consoleDemoInit();
glInit();
glEnable(GL_ANTIALIAS);
glEnable(GL_TEXTURE_2D);
// Setup the rear plane
glClearColor(2, 2, 2, 31); // BG must be opaque for AA to work
glClearPolyID(63); // BG must have a unique polygon ID for AA to work
glClearDepth(0x7FFF);
glViewport(0, 0, 255, 191);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
glLight(0, RGB15(0, 31, 0), 0, floattov10(0.8), floattov10(-0.2));
glLight(1, RGB15(31, 0, 0), 0, floattov10(-0.8), floattov10(-0.2));
glLight(2, RGB15(31, 31, 0), floattov10(0.7), 0, floattov10(-0.7));
glLight(3, RGB15(0, 0, 31), floattov10(-0.7), 0, floattov10(-0.7));
glMaterialf(GL_AMBIENT, RGB15(0, 0, 0));
glMaterialf(GL_DIFFUSE, RGB15(31, 31, 31));
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(0, 0, 0));
glMaterialf(GL_EMISSION, RGB15(0, 0, 0));
glMaterialShinyness();
glMatrixMode(GL_MODELVIEW);
//glMatrixMode(GL_POSITION); // This rotates lights with the model
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE | POLY_FORMAT_LIGHT0 |
POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3);
}
int main(void)
{
setup_video();
int textureID;
glGenTextures(1, &textureID);
glBindTexture(0, textureID);
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128, TEXTURE_SIZE_128, 0,
TEXGEN_TEXCOORD, (u8*)texture128_bin);
const void *robot_dsa_file = robot_walk_dsa_bin;
const void *robot_dsm_file = robot_dsm_bin;
const uint32_t robot_num_frames = DSMA_GetNumFrames(robot_dsa_file);
int32_t robot_frame = 0;
const void *quad_dsa_file = one_quad_wiggle_dsa_bin;
const void *quad_dsm_file = one_quad_dsm_bin;
const uint32_t quad_num_frames = DSMA_GetNumFrames(quad_dsa_file);
int32_t quad_frame = 0;
iprintf("\x1b[0;0HExit demo: START");
iprintf("\x1b[4;0H"
"This sample shows two models\n"
"side by side.\n"
"\n"
"The robot has aprox. 550 polys\n"
"and 16 bones. It's an example\n"
"of a regular model\n."
"\n"
"The quad has 2 polys and 7\n"
"bones. It's an example of how\n"
"much CPU time the skeleton\n"
"calculations take.\n");
iprintf("\x1b[19;0HTime Ticks us CPU%%");
while(1)
{
glLoadIdentity();
gluLookAt(8.0, 3.0, 0.0, // camera possition
0.0, 3.0, 0.0, // look at
0.0, 1.0, 0.0); // up
glPushMatrix();
{
glTranslatef(0, 0, -3);
glBindTexture(0, textureID);
cpuStartTiming(0);
DSMA_DrawModel(robot_dsm_file, robot_dsa_file, robot_frame);
uint32_t end_time = cpuEndTiming();
const float us_per_frame = 1000000.0 / 60.0;
printf("\x1b[20;0HRobot: %6lu %4lu %.3f%% ",
end_time, timerTicks2usec(end_time),
100.0 * timerTicks2usec(end_time) / us_per_frame);
}
glPopMatrix(1);
glPushMatrix();
{
glTranslatef(0, 0, 3);
glRotateY(-90);
glBindTexture(0, 0);
cpuStartTiming(0);
DSMA_DrawModel(quad_dsm_file, quad_dsa_file, quad_frame);
uint32_t end_time = cpuEndTiming();
const float us_per_frame = 1000000.0 / 60.0;
printf("\x1b[21;0HQuad: %6lu %4lu %.3f%% ",
end_time, timerTicks2usec(end_time),
100.0 * timerTicks2usec(end_time) / us_per_frame);
}
glPopMatrix(1);
// Wait for geometry engine operations to end
while (GFX_STATUS & BIT(27));
printf("\x1b[23;0HPolys: %4d Vertices: %4d",
GFX_POLYGON_RAM_USAGE, GFX_VERTEX_RAM_USAGE);
scanKeys();
u16 keys_held = keysHeld();
robot_frame += 1 << 9;
if (robot_frame >= inttof32(robot_num_frames))
robot_frame -= inttof32(robot_num_frames);
quad_frame += 1 << 9;
if (quad_frame >= inttof32(quad_num_frames))
quad_frame -= inttof32(quad_num_frames);
glFlush(0);
swiWaitForVBlank();
if (keys_held & KEY_START)
break;
}
return 0;
}

View File

@ -0,0 +1,220 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files embedded using bin2o
# GRAPHICS is a list of directories containing image files to be converted with grit
# AUDIO is a list of directories containing audio to be converted by maxmod
# ICON is the image used to create the game icon, leave blank to use default rule
# NITRO is a directory that will be accessible via NitroFS
#---------------------------------------------------------------------------------
TARGET := $(shell basename $(CURDIR))
BUILD := build
SOURCES := source source/dsma
INCLUDES := include
DATA := data
GRAPHICS :=
AUDIO :=
ICON :=
# specify a directory which contains the nitro filesystem
# this is relative to the Makefile
NITRO :=
# These set the information text in the nds file
GAME_TITLE := DSMA Example
GAME_SUBTITLE1 := built with devkitARM
GAME_SUBTITLE2 := http://devitpro.org
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s
CFLAGS := -g -Wall -O3\
$(ARCH) $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS := -lnds9
# automatigically add libraries for NitroFS
ifneq ($(strip $(NITRO)),)
LIBS := -lfilesystem -lfat $(LIBS)
endif
# automagically add maxmod library
ifneq ($(strip $(AUDIO)),)
LIBS := -lmm9 $(LIBS)
endif
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS) $(PORTLIBS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(CURDIR)/$(subst /,,$(dir $(ICON)))\
$(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
$(foreach dir,$(DATA),$(CURDIR)/$(dir))\
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
# prepare NitroFS directory
ifneq ($(strip $(NITRO)),)
export NITRO_FILES := $(CURDIR)/$(NITRO)
endif
# get audio list for maxmod
ifneq ($(strip $(AUDIO)),)
export MODFILES := $(foreach dir,$(notdir $(wildcard $(AUDIO)/*.*)),$(CURDIR)/$(AUDIO)/$(dir))
# place the soundbank file in NitroFS if using it
ifneq ($(strip $(NITRO)),)
export SOUNDBANK := $(NITRO_FILES)/soundbank.bin
# otherwise, needs to be loaded from memory
else
export SOUNDBANK := soundbank.bin
BINFILES += $(SOUNDBANK)
endif
endif
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.bmp)
ifneq (,$(findstring $(TARGET).bmp,$(icons)))
export GAME_ICON := $(CURDIR)/$(TARGET).bmp
else
ifneq (,$(findstring icon.bmp,$(icons)))
export GAME_ICON := $(CURDIR)/icon.bmp
endif
endif
else
ifeq ($(suffix $(ICON)), .grf)
export GAME_ICON := $(CURDIR)/$(ICON)
else
export GAME_ICON := $(CURDIR)/$(BUILD)/$(notdir $(basename $(ICON))).grf
endif
endif
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(SOUNDBANK)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds: $(OUTPUT).elf $(GAME_ICON)
$(OUTPUT).elf: $(OFILES)
# source files depend on generated headers
$(OFILES_SOURCES) : $(HFILES)
# need to build soundbank first
$(OFILES): $(SOUNDBANK)
#---------------------------------------------------------------------------------
# rule to build solution from music files
#---------------------------------------------------------------------------------
$(SOUNDBANK) : $(MODFILES)
#---------------------------------------------------------------------------------
mmutil $^ -d -o$@ -hsoundbank.h
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
# This rule creates assembly source files using grit
# grit takes an image file and a .grit describing how the file is to be processed
# add additional rules like this for each image extension
# you use in the graphics folders
#---------------------------------------------------------------------------------
%.s %.h: %.png %.grit
#---------------------------------------------------------------------------------
grit $< -fts -o$*
#---------------------------------------------------------------------------------
# Convert non-GRF game icon to GRF if needed
#---------------------------------------------------------------------------------
$(GAME_ICON): $(notdir $(ICON))
#---------------------------------------------------------------------------------
@echo convert $(notdir $<)
@grit $< -g -gt -gB4 -gT FF00FF -m! -p -pe 16 -fh! -ftr
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@ -0,0 +1,36 @@
#!/bin/sh
TOOLS=../../tools
QUAD=../../models/one_quad
ROBOT=../../models/robot
WIGGLE=../../models/wiggle
python3 $TOOLS/md5_to_dsma.py \
--model $QUAD/Quad.md5mesh \
--name one_quad \
--output data \
--texture 128 128 \
--anim $QUAD/Wiggle.md5anim \
--skip-frames 1 \
--bin \
--blender-fix
python3 $TOOLS/md5_to_dsma.py \
--model $ROBOT/Robot.md5mesh \
--name robot \
--output data \
--texture 128 128 \
--anim $ROBOT/Bow.md5anim $ROBOT/Walk.md5anim $ROBOT/Wave.md5anim \
--skip-frames 1 \
--bin \
--blender-fix
python3 $TOOLS/md5_to_dsma.py \
--model $WIGGLE/Wiggle.md5mesh \
--name wiggle \
--output data \
--texture 128 128 \
--anim $WIGGLE/Shake.md5anim \
--skip-frames 1 \
--bin \
--blender-fix

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1 @@
../../../library

View File

@ -0,0 +1,243 @@
#include <stdio.h>
#include <nds.h>
#include "dsma/dsma.h"
// Animated models
#include "one_quad_dsm_bin.h"
#include "robot_dsm_bin.h"
#include "wiggle_dsm_bin.h"
// Animations
#include "one_quad_wiggle_dsa_bin.h"
#include "robot_bow_dsa_bin.h"
#include "robot_walk_dsa_bin.h"
#include "robot_wave_dsa_bin.h"
#include "wiggle_shake_dsa_bin.h"
// Textures
#include "texture128_bin.h"
void setup_video(void)
{
videoSetMode(MODE_0_3D);
vramSetBankA(VRAM_A_TEXTURE);
consoleDemoInit();
glInit();
glEnable(GL_ANTIALIAS);
glEnable(GL_TEXTURE_2D);
// Setup the rear plane
glClearColor(2, 2, 2, 31); // BG must be opaque for AA to work
glClearPolyID(63); // BG must have a unique polygon ID for AA to work
glClearDepth(0x7FFF);
glViewport(0, 0, 255, 191);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, 256.0 / 192.0, 0.1, 40);
glLight(0, RGB15(0, 31, 0), 0, floattov10(0.8), floattov10(-0.2));
glLight(1, RGB15(31, 0, 0), 0, floattov10(-0.8), floattov10(-0.2));
glLight(2, RGB15(31, 31, 0), floattov10(0.7), 0, floattov10(-0.7));
glLight(3, RGB15(0, 0, 31), floattov10(-0.7), 0, floattov10(-0.7));
glMaterialf(GL_AMBIENT, RGB15(0, 0, 0));
glMaterialf(GL_DIFFUSE, RGB15(31, 31, 31));
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(0, 0, 0));
glMaterialf(GL_EMISSION, RGB15(0, 0, 0));
glMaterialShinyness();
glMatrixMode(GL_MODELVIEW);
//glMatrixMode(GL_POSITION); // This rotates lights with the model
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 |
POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3);
}
#define NUM_ROBOTS 7
#define NUM_QUADS 5
#define NUM_WIGGLES 13
#define NUM_MODELS (NUM_ROBOTS + NUM_QUADS + NUM_WIGGLES)
struct {
int32_t x, y, z;
uint32_t num_frames;
uint32_t curr_frame_interp;
uint32_t animation_speed;
int animation_index;
} model[NUM_MODELS];
const void *robot_dsa_file[] = {
robot_bow_dsa_bin,
robot_walk_dsa_bin,
robot_wave_dsa_bin
};
const size_t robot_dsa_num = sizeof(robot_dsa_file) / sizeof(robot_dsa_file[0]);
void initialize_models(void)
{
for (int i = 0; i < NUM_MODELS; i++)
{
model[i].x = ((i % 5) * inttof32(5)) - inttof32(10);
model[i].y = 0;
model[i].z = ((i / 5) * inttof32(5)) - inttof32(10);
model[i].curr_frame_interp = 0;
model[i].animation_speed = (((i * 7) % 10) + 8) << 6;
}
int index = 0;
for (int i = 0; i < NUM_ROBOTS; i++)
{
int anim_index = i % robot_dsa_num;
model[index].animation_index = anim_index;
model[index].num_frames = DSMA_GetNumFrames(robot_dsa_file[anim_index]);
index++;
}
for (int i = 0; i < NUM_QUADS; i++)
{
model[index].animation_index = 0;
model[index].num_frames = DSMA_GetNumFrames(one_quad_wiggle_dsa_bin);
index++;
}
for (int i = 0; i < NUM_WIGGLES; i++)
{
model[index].animation_index = 0;
model[index].num_frames = DSMA_GetNumFrames(wiggle_shake_dsa_bin);
index++;
}
}
void draw_and_update_models(void)
{
int index = 0;
for (int i = 0; i < NUM_ROBOTS; i++)
{
const void *dsm = robot_dsm_bin;
const void *dsa = robot_dsa_file[model[index].animation_index];
uint32_t frame = model[index].curr_frame_interp;
glPushMatrix();
glTranslatef32(model[index].x, model[index].y, model[index].z);
DSMA_DrawModel(dsm, dsa, frame);
glPopMatrix(1);
index++;
}
for (int i = 0; i < NUM_QUADS; i++)
{
const void *dsm = one_quad_dsm_bin;
const void *dsa = one_quad_wiggle_dsa_bin;
uint32_t frame = model[index].curr_frame_interp;
glPushMatrix();
glTranslatef32(model[index].x, model[index].y, model[index].z);
DSMA_DrawModel(dsm, dsa, frame);
glPopMatrix(1);
index++;
}
for (int i = 0; i < NUM_WIGGLES; i++)
{
const void *dsm = wiggle_dsm_bin;
const void *dsa = wiggle_shake_dsa_bin;
uint32_t frame = model[index].curr_frame_interp;
glPushMatrix();
glTranslatef32(model[index].x, model[index].y, model[index].z);
DSMA_DrawModel(dsm, dsa, frame);
glPopMatrix(1);
index++;
}
for (int i = 0; i < NUM_MODELS; i++)
{
model[i].curr_frame_interp += model[i].animation_speed;
if (model[i].curr_frame_interp >= inttof32(model[i].num_frames))
model[i].curr_frame_interp -= inttof32(model[i].num_frames);
}
}
int main(void)
{
setup_video();
int textureID;
glGenTextures(1, &textureID);
glBindTexture(0, textureID);
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128, TEXTURE_SIZE_128, 0,
TEXGEN_TEXCOORD, (u8*)texture128_bin);
initialize_models();
iprintf("\x1b[0;0HRotate: Left/Right");
iprintf("\x1b[1;0HExit demo: START");
iprintf("\x1b[19;0HTime Ticks us CPU%%");
float rotationY = 0.0f;
while(1)
{
cpuStartTiming(0);
glLoadIdentity();
gluLookAt(10.0, 6.0, 10.0, // camera possition
0.0, -6.0, 0.0, // look at
0.0, 1.0, 0.0); // up
glBindTexture(0, textureID);
glRotateY(rotationY);
draw_and_update_models();
uint32_t end_time = cpuEndTiming();
const float us_per_frame = 1000000.0 / 60.0;
printf("\x1b[20;0H %6lu %4lu %.3f%% ",
end_time, timerTicks2usec(end_time),
100.0 * timerTicks2usec(end_time) / us_per_frame);
// Wait for geometry engine operations to end
while (GFX_STATUS & BIT(27));
printf("\x1b[23;0HPolys: %4d Vertices: %4d",
GFX_POLYGON_RAM_USAGE, GFX_VERTEX_RAM_USAGE);
scanKeys();
u16 keys_held = keysHeld();
if (keys_held & KEY_RIGHT)
rotationY += 3;
if (keys_held & KEY_LEFT)
rotationY -= 3;
glFlush(0);
swiWaitForVBlank();
if (keys_held & KEY_START)
break;
}
return 0;
}

211
library/dsma.c Normal file
View File

@ -0,0 +1,211 @@
// SPDX-License-Identifier: MIT
//
// Copyright (c) 2022 Antonio Niño Díaz <antonio_nd@outlook.com>
// DS Model Animation Library v0.1.0
#include <nds.h>
#include "dsma.h"
// Format of a joint in a DSA file.
typedef struct {
int32_t pos[3]; // Translation (x, y, z)
int32_t orient[4]; // Orientation (w, x, y, z)
} dsa_joint_t;
#define DSA_VERSION_NUMBER 1
// Format of a DSA file.
typedef struct {
uint32_t version; // Version number
uint32_t num_frames; // Frames in the file
uint32_t num_joints; // Joints per frame
dsa_joint_t joints[0]; // Array of joints
} dsa_t;
// Private functions
// =================
// Helper that multiplies two fixed point values in 20.12 format and multiplies
// the result again by 2.
ITCM_CODE ARM_CODE static inline
int32_t mulf32_by_2(int32_t a, int32_t b)
{
return (a * b) >> (12 - 1);
}
// Generates a 4x3 matrix from the orientation in the provided quaternion and
// the translation in the provided vector. Then, it multiplies the matrix that
// is currently active in the geometry engine by the generated matrix.
ITCM_CODE ARM_CODE static inline
void matrix_mult_by_joint(const int32_t *v, const int32_t *q)
{
int32_t wx = mulf32_by_2(q[0], q[1]);
int32_t wy = mulf32_by_2(q[0], q[2]);
int32_t wz = mulf32_by_2(q[0], q[3]);
int32_t x2 = mulf32_by_2(q[1], q[1]);
int32_t xy = mulf32_by_2(q[1], q[2]);
int32_t xz = mulf32_by_2(q[1], q[3]);
int32_t y2 = mulf32_by_2(q[2], q[2]);
int32_t yz = mulf32_by_2(q[2], q[3]);
int32_t z2 = mulf32_by_2(q[3], q[3]);
MATRIX_MULT4x3 = inttof32(1) - y2 - z2;
MATRIX_MULT4x3 = xy + wz;
MATRIX_MULT4x3 = xz - wy;
MATRIX_MULT4x3 = xy - wz;
MATRIX_MULT4x3 = inttof32(1) - x2 - z2;
MATRIX_MULT4x3 = yz + wx;
MATRIX_MULT4x3 = xz + wy;
MATRIX_MULT4x3 = yz - wx;
MATRIX_MULT4x3 = inttof32(1) - x2 - y2;
MATRIX_MULT4x3 = v[0];
MATRIX_MULT4x3 = v[1];
MATRIX_MULT4x3 = v[2];
}
// Gets a pointer to the list of joints of the specified frame.
ITCM_CODE ARM_CODE static inline
const dsa_joint_t *dsa_get_frame(const dsa_t *dsa, uint32_t frame)
{
return &dsa->joints[frame * dsa->num_joints];
}
// Interpolates linearly between 'start' and 'end'. The position is a floating
// point number in 20.12 format, and it should be between 0.0 and 1.0 (the
// function doesn't check bounds).
ITCM_CODE ARM_CODE static inline
int32_t lerp(int32_t start, int32_t end, int32_t pos)
{
int32_t diff = end - start;
return start + ((diff * pos) >> 12);
}
// Interpolates between quaternions 'q1' and 'q2. The position is a floating
// point number in 20.12 format, and it should be between 0.0 and 1.0 (the
// function doesn't check bounds). It stores the result in 'qdest'.
ITCM_CODE ARM_CODE static inline
void q_nlerp(const int32_t *q1, const int32_t *q2, int32_t pos, int32_t *qdest)
{
qdest[0] = lerp(q1[0], q2[0], pos);
qdest[1] = lerp(q1[1], q2[1], pos);
qdest[2] = lerp(q1[2], q2[2], pos);
qdest[3] = lerp(q1[3], q2[3], pos);
// TODO: Normalize? It needs way too much CPU time (at least we need one
// square root and one division), but it may be needed in the future if the
// animations look bad. Maybe it can be optional.
}
// Public functions
// ================
uint32_t DSMA_GetNumFrames(const void *dsa_file)
{
const dsa_t *dsa = dsa_file;
return dsa->num_frames;
}
ITCM_CODE ARM_CODE
int DSMA_DrawModel(const void *dsm_file, const void *dsa_file, uint32_t frame_interp)
{
const dsa_t *dsa = dsa_file;
if (dsa->version != DSA_VERSION_NUMBER)
return DSMA_INVALID_VERSION;
uint32_t num_joints = dsa->num_joints;
uint32_t num_frames = dsa->num_frames;
uint32_t frame = frame_interp >> 12;
uint32_t interp = frame_interp & 0xFFF;
if (frame >= num_frames)
return DSMA_INVALID_FRAME;
// Make sure that there is enough space in the matrix stack
// --------------------------------------------------------
uint32_t base_matrix = 30 - num_joints + 1;
// Wait for matrix push/pop operations to end
while (GFX_STATUS & BIT(14));
uint32_t curr_stack_level = (GFX_STATUS >> 8) & 0x1F;
if (curr_stack_level >= base_matrix)
return DSMA_MATRIX_STACK_FULL;
MATRIX_PUSH = 0;
// Generate matrices with bone transformations
// -------------------------------------------
if (interp != 0)
{
uint32_t next_frame = frame + 1;
if (next_frame == num_frames)
next_frame = 0;
const dsa_joint_t *frame_ptr_1 = dsa_get_frame(dsa, frame);
const dsa_joint_t *frame_ptr_2 = dsa_get_frame(dsa, next_frame);
for (uint32_t i = 0; i < num_joints; i++)
{
// Interpolate transformations
const int32_t *v_pos_1 = frame_ptr_1->pos;
const int32_t *q_orient_1 = frame_ptr_1->orient;
frame_ptr_1++;
const int32_t *v_pos_2 = frame_ptr_2->pos;
const int32_t *q_orient_2 = frame_ptr_2->orient;
frame_ptr_2++;
int32_t v_pos[3];
v_pos[0] = lerp(v_pos_1[0], v_pos_2[0], interp);
v_pos[1] = lerp(v_pos_1[1], v_pos_2[1], interp);
v_pos[2] = lerp(v_pos_1[2], v_pos_2[2], interp);
int32_t q_orient[4];
q_nlerp(q_orient_1, q_orient_2, interp, &q_orient[0]);
// Generate new matrix
MATRIX_RESTORE = curr_stack_level;
matrix_mult_by_joint(v_pos, q_orient);
// Store it in the right position in the stack
MATRIX_STORE = base_matrix + i;
}
}
else
{
const dsa_joint_t *frame_ptr = dsa_get_frame(dsa, frame);
for (uint32_t i = 0; i < num_joints; i++)
{
// Get transformation
const int32_t *v_pos = frame_ptr->pos;
const int32_t *q_orient = frame_ptr->orient;
frame_ptr++;
// Generate new matrix
MATRIX_RESTORE = curr_stack_level;
matrix_mult_by_joint(v_pos, q_orient);
// Store it in the right position in the stack
MATRIX_STORE = base_matrix + i;
}
}
// Draw model
// ----------
glCallList((uint32_t *)dsm_file);
MATRIX_POP = 1;
return DSMA_SUCCESS;
}

36
library/dsma.h Normal file
View File

@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT
//
// Copyright (c) 2022 Antonio Niño Díaz <antonio_nd@outlook.com>
// DS Model Animation Library v0.1.0
#ifndef DSMA_H__
#define DSMA_H__
#include <nds.h>
#ifndef ARM_CODE
# define ARM_CODE __attribute__((target("arm")))
#endif
// Returns the number of frames stored in the specified DSA file.
uint32_t DSMA_GetNumFrames(const void *dsa_file);
// Draws the model in the DSM file animated with the data in the specified DSA
// file, at the requested frame.
//
// The frame is a fixed point value in 20.12 format (e.g. if you pass 3 << 12 as
// value it corresponds to frame 3). Any value that isn't an exact frame number
// will draw the model by interpolating the two closest frames. It wraps around:
// when going over the max frame, it interpolates with frame 0.
//
// It returns a DSMA_* code (0 for success).
ITCM_CODE ARM_CODE
int DSMA_DrawModel(const void *dsm_file, const void *dsa_file, uint32_t frame_interp);
#define DSMA_SUCCESS 0
#define DSMA_INVALID_VERSION -1
#define DSMA_INVALID_FRAME -2
#define DSMA_MATRIX_STACK_FULL -3
#endif // DSMA_H__

125
licenses/cc0-1.0.txt Normal file
View File

@ -0,0 +1,125 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS.
CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE
INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES
RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of authorship
and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific works
("Commons") that the public can reliably and without fear of later claims of
infringement build upon, modify, incorporate in other works, reuse and
redistribute as freely as possible in any form whatsoever and for any purposes,
including without limitation commercial purposes. These owners may contribute to
the Commons to promote the ideal of a free culture and the further production of
creative, cultural and scientific works, or to gain reputation or greater
distribution for their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any expectation of
additional consideration or compensation, the person associating CC0 with a Work
(the "Affirmer"), to the extent that he or she is an owner of Copyright and
Related Rights in the Work, voluntarily elects to apply CC0 to the Work and
publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of
data in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of
the European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer
makes the Waiver for the benefit of each member of the public at large and
to the detriment of Affirmer's heirs and successors, fully intending that
such Waiver shall not be subject to revocation, rescission, cancellation,
termination, or any other legal or equitable action to disrupt the quiet
enjoyment of the Work by the public as contemplated by Affirmer's express
Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the
Waiver is so judged Affirmer hereby grants to each affected person a
royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "License"). The License
shall be deemed effective as of the date CC0 was applied by Affirmer to the
Work. Should any part of the License for any reason be judged legally
invalid or ineffective under applicable law, such partial invalidity or
ineffectiveness shall not invalidate the remainder of the License, and in
such case Affirmer hereby affirms that he or she will not (i) exercise any
of his or her remaining Copyright and Related Rights in the Work or (ii)
assert any associated claims and causes of action with respect to the Work,
in either case contrary to Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied, statutory
or otherwise, including without limitation warranties of title,
merchantability, fitness for a particular purpose, non infringement, or
the absence of latent or other defects, accuracy, or the present or
absence of errors, whether or not discoverable, all to the greatest
extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other
persons that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

19
licenses/mit.txt Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2011-2015, 2019-2020 Antonio Niño Díaz <antonio_nd@outlook.com>
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.

View File

@ -0,0 +1,33 @@
MD5Version 10 // Parameters used during export: Reorient: False; Scale: 1.0
commandline ""
numJoints 7
numMeshes 1
joints {
"Base.Bone" -1 ( 0.0000000000 0.0000000000 -1.0000000000 ) ( -0.7071068287 -0.0000000000 -0.0000000000 )
"Low.Bone" 0 ( -0.0000000000 0.0000000000 0.0000000000 ) ( -0.7071068287 0.0000000000 0.0000000000 )
"Low.Bone.002" 1 ( -0.0000000000 -0.0000000000 0.6666666269 ) ( -0.7071068287 -0.0000000000 0.0000000000 )
"Low.Bone.001" 2 ( -0.0000000000 -0.0000000000 1.3333332539 ) ( -0.7071068287 -0.0000000000 0.0000000000 )
"Top.Bone" 3 ( -0.0000000000 -0.0000000000 2.0000000000 ) ( -0.7071068287 -0.0000000843 -0.0000000843 )
"Top.Bone.002" 4 ( -0.0000000000 -0.0000000000 2.6666665077 ) ( -0.7071068287 -0.0000000843 -0.0000000843 )
"Top.Bone.001" 5 ( -0.0000000000 -0.0000000000 3.3333332539 ) ( -0.7071068287 -0.0000000843 -0.0000000843 )
}
mesh {
shader "default"
numverts 4
vert 0 ( 0.6666666269 1.0000000000 ) 0 1
vert 1 ( 0.6666666269 0.6666667461 ) 1 1
vert 2 ( 0.9999999404 1.0000000000 ) 2 1
vert 3 ( 0.9999998808 0.6666666865 ) 3 1
numtris 2
tri 0 1 3 2
tri 1 0 1 2
numweights 4
weight 0 6 1.0000000000 ( 1.0000002384 0.6666667461 -0.9999997616 )
weight 1 6 1.0000000000 ( 0.9999997616 0.6666667461 1.0000002384 )
weight 2 6 1.0000000000 ( -0.9999997616 0.6666667461 -1.0000002384 )
weight 3 6 1.0000000000 ( -1.0000002384 0.6666667461 0.9999997616 )
}

View File

@ -0,0 +1,207 @@
MD5Version 10 // Parameters used during export: Reorient: False; Scale: 1.0
commandline ""
numFrames 16
numJoints 7
frameRate 24
numAnimatedComponents 42
hierarchy {
"Base.Bone" -1 63 0 //
"Low.Bone" 0 63 6 //
"Low.Bone.002" 1 63 12 //
"Low.Bone.001" 2 63 18 //
"Top.Bone" 3 63 24 //
"Top.Bone.002" 4 63 30 //
"Top.Bone.001" 5 63 36 //
}
bounds {
( -1.1738224030 1.0665168762 2.2167446613 ) ( 1.3852889538 2.3654732704 4.4517188072 )
( -1.1974251270 0.9135962725 2.3582348824 ) ( 1.3421490192 2.3425629139 4.4758663177 )
( -1.2280571461 0.5148179531 2.7303419113 ) ( 1.2294948101 2.2266480923 4.4956712723 )
( -1.2037864923 -0.0179642439 3.2294156551 ) ( 1.0817462206 1.9335290194 4.4223871231 )
( -1.1044335365 -0.5500087738 3.7133867741 ) ( 0.9496709108 1.4467972517 4.2173156738 )
( -1.1151463985 -1.1134409904 3.8469870090 ) ( 1.0218517780 1.0055301189 4.1374788284 )
( -1.1095138788 -1.5366383791 3.5425364971 ) ( 1.1327804327 0.5670977831 4.3192501068 )
( -1.0622029305 -1.8320026398 3.2503187656 ) ( 1.2254084349 0.1582469940 4.3907909393 )
( -1.0005173683 -2.0214548111 3.0114312172 ) ( 1.2896996737 -0.1706309319 4.3894791603 )
( -0.9492129683 -2.1238713264 2.8562550545 ) ( 1.3191082478 -0.3895092010 4.3587012291 )
( -0.9275929332 -2.1472666264 2.8063197136 ) ( 1.3080608845 -0.4809949398 4.3366413116 )
( -0.9528194070 -2.0453400612 2.9792265892 ) ( 1.2309739590 -0.3237236738 4.3440742493 )
( -0.9871699214 -1.7603619099 3.3522408009 ) ( 1.0910770893 0.0796232820 4.3227691650 )
( -1.0629014969 -1.4075473547 3.7247467041 ) ( 1.0157089233 0.6331740618 4.2060527802 )
( -1.1698390245 -1.0961670876 3.9306871891 ) ( 1.0420696735 1.1169285774 4.0655479431 )
( -1.2073229551 -0.9429736137 3.8068437576 ) ( 1.0583875179 1.2988523245 4.1755452156 )
}
baseframe {
( 0.0000000000 0.0000000000 -1.0000000000 ) ( -0.7071068287 -0.0000000000 -0.0000000000 )
( 0.0000000000 1.0000000000 0.0000000000 ) ( -0.0000000000 0.0000000000 0.0000000000 )
( 0.0000000000 0.6666666269 -0.0000000000 ) ( 0.0000000000 -0.0000000000 0.0000000000 )
( 0.0000000000 0.6666666269 -0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( -0.0000000000 0.6666667461 0.0000000000 ) ( 0.0000000000 -0.0000001192 -0.0000000000 )
( 0.0000000000 0.6666665077 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( 0.0000000000 0.6666667461 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
}
frame 0 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0245840959 0.0087798676 -0.0018916141
0.0000000002 0.6666666269 0.0000000003 0.0671774447 0.0239914842 -0.0051689432
0.0000000019 0.6666666865 0.0000000219 0.0633576289 0.0226272848 -0.0048750276
0.0000000084 0.6666667461 -0.0000000236 0.0978382975 0.0349414572 -0.0075281197
0.0000000065 0.6666666269 0.0000001036 0.1112276092 0.0397233926 -0.0085583413
0.0000000466 0.6666663885 -0.0000000214 0.1896742284 0.0677395016 -0.0145943630
}
frame 1 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0214723274 0.0076685399 -0.0016521799
0.0000000000 0.6666666269 0.0000000010 0.0669916943 0.0239251461 -0.0051546502
-0.0000000009 0.6666666865 -0.0000000359 0.0574350543 0.0205121227 -0.0044193184
0.0000000019 0.6666665673 -0.0000000416 0.0895750970 0.0274379160 -0.0075139720
0.0000000019 0.6666664481 -0.0000000391 0.1042957008 0.0374107771 -0.0085364673
0.0000000042 0.6666668057 0.0000000115 0.1735152453 0.0625853166 -0.0143034393
}
frame 2 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0140501307 0.0050178058 -0.0010810816
0.0000000001 0.6666665673 0.0000000001 0.0657371059 0.0234770887 -0.0050581163
0.0000000014 0.6666666269 -0.0000000059 0.0420398787 0.0150139481 -0.0032347415
-0.0000000009 0.6666665673 -0.0000000233 0.0678831935 0.0095066112 -0.0073921843
-0.0000000037 0.6666664481 0.0000001367 0.0858467221 0.0312517695 -0.0083785551
-0.0000000149 0.6666663289 -0.0000001551 0.1320067495 0.0493452586 -0.0134057831
}
frame 3 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0051896223 0.0018533992 -0.0003993133
-0.0000000000 0.6666666865 0.0000000003 0.0623674691 0.0222736690 -0.0047988407
-0.0000000009 0.6666665673 0.0000000139 0.0207405295 0.0074071940 -0.0015958719
0.0000000019 0.6666669250 -0.0000000318 0.0374634303 -0.0119314156 -0.0070436420
0.0000000000 0.6666665673 0.0000000102 0.0593977310 0.0224132184 -0.0079451483
0.0000000186 0.6666669846 0.0000000054 0.0758249611 0.0314235389 -0.0118661132
}
frame 4 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 -0.0022338924 -0.0007978060 0.0001718863
-0.0000000000 0.6666666865 0.0000000003 0.0558325760 0.0199398231 -0.0042960159
0.0000000012 0.6666667461 0.0000000135 -0.0028576909 -0.0010205804 0.0002198839
0.0000000000 0.6666669250 0.0000000061 0.0031699056 -0.0298735313 -0.0063556950
0.0000000033 0.6666665077 0.0000000047 0.0285013076 0.0120742489 -0.0070982529
0.0000000099 0.6666665673 0.0000000440 0.0163138732 0.0124489786 -0.0096831042
}
frame 5 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 -0.0053465767 -0.0019094577 0.0004113906
-0.0000000001 0.6666666269 -0.0000000002 0.0450707935 0.0160964057 -0.0034679554
0.0000000007 0.6666665673 0.0000000142 -0.0251339749 -0.0089762416 0.0019339240
0.0000000001 0.6666667461 -0.0000000013 -0.0301087890 -0.0373587273 -0.0052241012
0.0000000019 0.6666665077 0.0000000073 -0.0032691036 0.0014218829 -0.0057031694
-0.0000000055 0.6666663289 0.0000000156 -0.0350614712 -0.0038914913 -0.0068903505
}
frame 6 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 -0.0027248035 -0.0009731275 0.0002096593
-0.0000000001 0.6666666269 -0.0000000000 0.0263766125 0.0094200410 -0.0020295393
0.0000000003 0.6666666269 0.0000000059 -0.0431516394 -0.0154109998 0.0033202870
0.0000000002 0.6666668653 -0.0000000058 -0.0583655871 -0.0351227820 -0.0031935819
0.0000000026 0.6666668653 -0.0000000191 -0.0327265263 -0.0084820436 -0.0030121100
-0.0000000044 0.6666668653 0.0000000129 -0.0704994798 -0.0151302945 -0.0035872757
}
frame 7 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0035277156 0.0012598736 -0.0002714386
-0.0000000000 0.6666666865 -0.0000000001 0.0009092589 0.0003247335 -0.0000699637
-0.0000000001 0.6666666269 -0.0000000002 -0.0566048995 -0.0202156436 0.0043554427
-0.0000000012 0.6666668057 -0.0000000029 -0.0806912705 -0.0290392637 -0.0003574895
0.0000000000 0.6666666269 -0.0000000539 -0.0581060089 -0.0170366969 0.0009273000
-0.0000000149 0.6666670442 -0.0000000042 -0.0919787437 -0.0219397116 -0.0001734107
}
frame 8 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0109905582 0.0039251256 -0.0008456645
0.0000000000 0.6666666269 -0.0000000014 -0.0250420310 -0.0089434031 0.0019268477
-0.0000000001 0.6666665077 0.0000000057 -0.0658267289 -0.0235090945 0.0050650146
0.0000000023 0.6666666269 -0.0000000036 -0.0969109982 -0.0199304409 0.0025642249
0.0000000019 0.6666665077 0.0000001835 -0.0779891387 -0.0237527099 0.0050543845
-0.0000000042 0.6666670442 0.0000000820 -0.1030752957 -0.0254523233 0.0028709413
}
frame 9 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0172423702 0.0061578737 -0.0013267080
-0.0000000002 0.6666666865 -0.0000000012 -0.0451746471 -0.0161334816 0.0034759452
0.0000000009 0.6666664481 -0.0000000025 -0.0711352676 -0.0254049581 0.0054734773
-0.0000000037 0.6666668057 0.0000000204 -0.1068152562 -0.0086155701 0.0048496970
-0.0000000093 0.6666664481 0.0000000112 -0.0909607410 -0.0281416867 0.0083086500
0.0000000091 0.6666665673 0.0000000447 -0.1072441339 -0.0267667510 0.0050611543
}
frame 10 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0198636483 0.0070940284 -0.0015284014
0.0000000000 0.6666666269 -0.0000000013 -0.0532605946 -0.0190212652 0.0040981136
0.0000000006 0.6666667461 0.0000000135 -0.0728375167 -0.0260128975 0.0056044557
-0.0000000009 0.6666666269 0.0000000655 -0.1101678014 0.0040770099 0.0057730614
0.0000000037 0.6666663885 -0.0000000619 -0.0956024379 -0.0297142603 0.0096294070
-0.0000000410 0.6666668057 -0.0000002366 -0.1078807116 -0.0269648265 0.0059022107
}
frame 11 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0180646852 0.0064515541 -0.0013899810
-0.0000000000 0.6666665673 0.0000000003 -0.0460178368 -0.0164346173 0.0035408230
0.0000000004 0.6666665077 -0.0000000045 -0.0673106983 -0.0240390692 0.0051791966
0.0000000009 0.6666667461 -0.0000000006 -0.0966836065 0.0172496345 0.0041441321
-0.0000000084 0.6666666865 -0.0000000047 -0.0844516158 -0.0259527173 0.0077744839
-0.0000000112 0.6666666865 -0.0000001346 -0.0942250490 -0.0226345919 0.0034972231
}
frame 12 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0137744080 0.0049193408 -0.0010598671
-0.0000000001 0.6666666269 0.0000000007 -0.0287246816 -0.0102586113 0.0022102082
-0.0000000001 0.6666666865 -0.0000000045 -0.0541170686 -0.0193271488 0.0041640168
0.0000000023 0.6666666269 -0.0000000185 -0.0643965304 0.0297273714 0.0002491280
0.0000000019 0.6666663289 0.0000000591 -0.0577719025 -0.0169542655 0.0033400028
0.0000000037 0.6666669250 -0.0000000952 -0.0615062900 -0.0122657036 -0.0022537401
}
frame 13 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0086532608 0.0030903954 -0.0006658223
-0.0000000000 0.6666666865 -0.0000000008 -0.0080640092 -0.0028799404 0.0006204802
0.0000000000 0.6666668057 -0.0000000009 -0.0383523405 -0.0136970002 0.0029510066
-0.0000000008 0.6666667461 -0.0000000162 -0.0257236511 0.0401919186 -0.0044056252
-0.0000000024 0.6666665077 0.0000000082 -0.0258379001 -0.0061863754 -0.0019610974
0.0000000005 0.6666668057 -0.0000000653 -0.0223042369 0.0001462511 -0.0091233896
}
frame 14 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0043624686 0.0015579978 -0.0003356689
0.0000000000 0.6666666269 -0.0000000000 0.0092428485 0.0033009606 -0.0007111894
0.0000000000 0.6666667461 0.0000000052 -0.0251385942 -0.0089778956 0.0019342795
0.0000000004 0.6666667461 0.0000000052 0.0066702506 0.0473427363 -0.0082958061
0.0000000001 0.6666665077 -0.0000000020 0.0009167867 0.0028328344 -0.0063968198
0.0000000006 0.6666669250 0.0000000015 0.0105266301 0.0105313538 -0.0148591353
}
frame 15 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0025631466 0.0009153964 -0.0001972209
-0.0000000000 0.6666666269 0.0000000001 0.0164950527 0.0058909860 -0.0012692078
0.0000000005 0.6666666269 0.0000000018 -0.0195979048 -0.0069991187 0.0015079532
0.0000000002 0.6666665077 -0.0000000001 0.0202257894 0.0499825403 -0.0099213310
-0.0000000023 0.6666666269 0.0000000048 0.0121192681 0.0066086617 -0.0082525900
-0.0000000112 0.6666665077 0.0000000116 0.0242594946 0.0148727493 -0.0172536466
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

269
models/robot/Bow.md5anim Normal file
View File

@ -0,0 +1,269 @@
MD5Version 10 // Parameters used during export: Reorient: False; Scale: 1.0
commandline ""
numFrames 11
numJoints 16
frameRate 24
numAnimatedComponents 96
hierarchy {
"Base.Bone" -1 63 0 //
"Spine.Low" 0 63 6 //
"Spine.High" 1 63 12 //
"Head" 2 63 18 //
"Chest.Left" 1 63 24 //
"Arm.Upper.Left" 4 63 30 //
"Arm.End.Left" 5 63 36 //
"Chest.Right" 1 63 42 //
"Arm.Upper.Right" 7 63 48 //
"Arm.End..Right" 8 63 54 //
"Pelvis.Left" 0 63 60 //
"Leg-Upper.Left" 10 63 66 //
"Leg-Lower.Left" 11 63 72 //
"Pelvis.Right" 0 63 78 //
"Leg-Upper.Right" 13 63 84 //
"Leg-Lower.Right" 14 63 90 //
}
bounds {
( -0.7288464904 -4.2145261765 -0.1051818728 ) ( 0.7288464904 4.2140474319 6.9405498505 )
( -0.7285697460 -4.2145261765 -0.1051818728 ) ( 0.7357667685 4.2140474319 6.9425845146 )
( -0.7276327014 -4.2145261765 -0.1051818728 ) ( 0.7581696510 4.2140479088 6.9487514496 )
( -0.7257894278 -4.2145261765 -0.1051818728 ) ( 0.7984296083 4.2140479088 6.9582033157 )
( -0.7226391435 -4.2145261765 -0.1051818728 ) ( 0.8587396145 4.2140479088 6.9683656693 )
( -0.7175707817 -4.2145261765 -0.1051818728 ) ( 0.9409875870 4.2140474319 6.9742531776 )
( -0.7099610567 -4.2145261765 -0.1051818728 ) ( 1.1161646843 4.2140474319 6.9681591988 )
( -0.7003120780 -4.2145261765 -0.1051818728 ) ( 1.3341093063 4.2140474319 6.9447398186 )
( -0.6902095079 -4.2145261765 -0.1051818728 ) ( 1.5253562927 4.2140474319 6.9082584381 )
( -0.6820794940 -4.2145261765 -0.1051818728 ) ( 1.6597368717 4.2140474319 6.8727006912 )
( -0.6787633300 -4.2145261765 -0.1051818728 ) ( 1.7105250359 4.2140479088 6.8569402695 )
}
baseframe {
( 0.0000000000 0.0000000000 0.0000000000 ) ( -0.7071068287 -0.0000000000 -0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( -0.0001522740 -0.0000001192 -0.0000000000 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( 0.0004014244 -0.0000001192 0.0000000001 )
( -0.0000000000 1.0282182693 0.0000000000 ) ( -0.0002491503 0.0000001192 -0.0000000001 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( 0.7072144151 0.0000000000 0.0000001686 )
( 0.0000000000 1.0038089752 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( 0.0000000000 1.6051955223 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( -0.7069991827 0.0000000309 -0.0000001377 )
( -0.0000000000 1.0172638893 0.0000000000 ) ( -0.0000000000 -0.0000000000 0.0000000000 )
( 0.0000000000 1.6867997646 0.0000000000 ) ( -0.0000000000 -0.0000000000 0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( 0.7113879919 -0.0000000000 -0.0000000000 )
( 0.0000000000 0.4849954247 0.0000000428 ) ( 0.7027994990 -0.0000000848 0.0000000838 )
( 0.0000000000 1.3662177324 0.0000000284 ) ( -0.0000000005 0.0000001192 -0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( -0.7112751007 0.0000003352 0.0000003392 )
( 0.0000000000 0.5501293540 -0.0000000224 ) ( -0.7029137611 0.0000000000 0.0000006704 )
( 0.0000000000 1.3662178516 0.0000000000 ) ( 0.0000000000 0.0000000000 0.0000000000 )
}
frame 0 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522740 -0.0000001192 -0.0000000000
0.0000000000 1.6823664904 0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 -0.0000000001 -0.0002490849 -0.0229121577 -0.0000057087
0.0000000000 1.6823664904 0.0000000000 0.7072144151 0.0000000000 0.0000001686
0.0000000000 1.0038089752 -0.0000001216 -0.0000000000 -0.0000000000 -0.0000000000
0.0000000000 1.6051954031 -0.0000003162 -0.0000000000 -0.0000000000 0.0000000000
0.0000000000 1.6823664904 0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
-0.0000000000 1.0172638893 0.0000001437 -0.0010274349 -0.0000000000 -0.0000000002
0.0000000000 1.6867997646 0.0000000624 -0.0003698472 -0.0000000000 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 1 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522737 0.0000000946 0.0014037968
-0.0000000006 1.6823662519 -0.0000000000 0.0004014245 -0.0000001192 0.0000000002
-0.0000000023 1.0282181501 -0.0000000002 -0.0002812493 -0.0229124855 0.0013977200
-0.0000000006 1.6823662519 -0.0000000000 0.7072144151 0.0000000001 0.0000001684
0.0000000004 1.0038089752 -0.0000002099 0.0000000000 0.0000000000 0.0000000000
0.0000000012 1.6051954031 -0.0000004034 0.0000000000 0.0000000000 0.0000000000
-0.0000000006 1.6823662519 -0.0000000000 -0.7069992423 0.0000000309 -0.0000001379
-0.0000000001 1.0172638893 0.0000002352 -0.0010274349 -0.0000000002 -0.0000000002
0.0000000008 1.6867996454 0.0000001833 -0.0003698470 -0.0000000000 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 2 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522706 0.0000007878 0.0059563941
0.0000000017 1.6823663712 -0.0000000000 0.0004014244 -0.0000001192 0.0000000003
0.0000000037 1.0282181501 0.0000000001 -0.0003855572 -0.0229132306 0.0059491261
0.0000000017 1.6823663712 -0.0000000000 0.7072145343 0.0000000000 0.0000001686
-0.0000000021 1.0038088560 0.0000003804 -0.0000000000 0.0000000000 -0.0000000000
-0.0000000033 1.6051952839 0.0000004610 -0.0000000000 0.0000000000 -0.0000000000
0.0000000017 1.6823663712 -0.0000000000 -0.7069992423 0.0000000318 -0.0000001374
0.0000000026 1.0172638893 0.0000003013 -0.0010274349 -0.0000000000 -0.0000000002
0.0000000074 1.6867998838 0.0000002411 -0.0003698471 0.0000000002 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 3 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522571 0.0000020385 0.0141700255
0.0000000111 1.6823663712 0.0000000001 0.0004014244 -0.0000001192 0.0000000019
-0.0000000000 1.0282181501 -0.0000000004 -0.0005737321 -0.0229133684 0.0141605921
0.0000000111 1.6823663712 0.0000000001 0.7072145343 0.0000000000 0.0000001686
-0.0000000111 1.0038089752 0.0000001210 -0.0000000000 0.0000000000 -0.0000000000
-0.0000000125 1.6051955223 0.0000002076 -0.0000000000 0.0000000000 -0.0000000000
0.0000000111 1.6823663712 0.0000000001 -0.7069992423 0.0000000309 -0.0000001376
0.0000000072 1.0172638893 0.0000001025 -0.0010274349 -0.0000000000 -0.0000000002
0.0000000092 1.6867998838 0.0000004353 -0.0003698470 0.0000000009 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 4 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522172 0.0000039246 0.0265560318
0.0000000073 1.6823663712 0.0000000000 0.0004014244 -0.0000001192 0.0000000038
-0.0000000149 1.0282182693 0.0000000003 -0.0008574653 -0.0229106862 0.0265433639
0.0000000073 1.6823663712 0.0000000000 0.7072145343 -0.0000000026 0.0000001712
-0.0000000080 1.0038088560 0.0000003616 -0.0000000000 -0.0000000028 0.0000000000
-0.0000000119 1.6051951647 0.0000004577 -0.0000000000 -0.0000000019 0.0000000000
0.0000000073 1.6823663712 0.0000000000 -0.7069992423 0.0000000355 -0.0000001330
0.0000000302 1.0172638893 0.0000003672 -0.0010274349 0.0000000019 -0.0000000002
0.0000000046 1.6867997646 0.0000000759 -0.0003698470 -0.0000000009 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 5 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001521343 0.0000065230 0.0436193980
0.0000000148 1.6823662519 -0.0000000000 0.0004014244 -0.0000001192 0.0000000019
-0.0000000149 1.0282179117 -0.0000000004 -0.0012482816 -0.0229011979 0.0436022244
0.0000000148 1.6823662519 -0.0000000000 0.7072145343 -0.0000000039 0.0000001673
0.0000000155 1.0038089752 -0.0000001634 -0.0000000000 -0.0000000075 -0.0000000000
-0.0000000194 1.6051954031 -0.0000000875 -0.0000000000 -0.0000000075 -0.0000000000
0.0000000148 1.6823662519 -0.0000000000 -0.7069992423 0.0000000316 -0.0000001370
0.0000000030 1.0172638893 -0.0000000644 -0.0010274349 0.0000000019 -0.0000000002
-0.0000000007 1.6867996454 0.0000004666 -0.0003698469 -0.0000000037 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 6 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001519528 0.0000098073 0.0651869699
-0.0000000001 1.6823664904 -0.0000000001 0.0004014244 -0.0000001192 0.0000000150
0.0000000298 1.0282177925 -0.0000000001 -0.0017421592 -0.0228796508 0.0651641712
-0.0000000001 1.6823664904 -0.0000000001 0.7072144151 -0.0000000079 0.0000001660
0.0000000094 1.0038089752 -0.0000001028 -0.0000000000 0.0000000000 0.0000000000
0.0000000334 1.6051954031 -0.0000002810 -0.0000000000 0.0000000000 0.0000000000
-0.0000000001 1.6823664904 -0.0000000001 -0.7069992423 0.0000000421 -0.0000001264
0.0000000425 1.0172638893 0.0000007104 -0.0010274349 -0.0000000000 -0.0000000002
-0.0000000891 1.6867998838 -0.0000002249 -0.0003698470 -0.0000000000 0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 7 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001516789 0.0000133300 0.0883191153
0.0000000297 1.6823666096 -0.0000000001 0.0004014244 -0.0000001192 0.0000000038
-0.0000000596 1.0282179117 0.0000000003 -0.0022717328 -0.0228446033 0.0882901847
0.0000000297 1.6823666096 -0.0000000001 0.7072144151 -0.0000000078 0.0000001660
-0.0000000006 1.0038089752 0.0000000767 -0.0000000000 0.0000000000 -0.0000000000
0.0000000162 1.6051954031 -0.0000000844 -0.0000000000 0.0000000000 -0.0000000000
0.0000000297 1.6823666096 -0.0000000001 -0.7069992423 0.0000000316 -0.0000001317
-0.0000000816 1.0172638893 0.0000001152 -0.0010274349 -0.0000000149 -0.0000000002
0.0000000917 1.6867998838 0.0000002231 -0.0003698471 0.0000000074 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 8 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001513583 0.0000165327 0.1093500480
-0.0000000001 1.6823667288 -0.0000000001 0.0004014244 -0.0000001192 0.0000000150
-0.0000001192 1.0282183886 -0.0000000000 -0.0027530887 -0.0228019804 0.1093157083
-0.0000000001 1.6823667288 -0.0000000001 0.7072144747 -0.0000000026 0.0000001765
-0.0000000115 1.0038089752 0.0000000021 0.0000000000 0.0000000000 -0.0000000000
0.0000000179 1.6051954031 -0.0000001375 0.0000000000 0.0000000000 -0.0000000000
-0.0000000001 1.6823667288 -0.0000000001 -0.7069992423 0.0000000210 -0.0000001475
0.0000001227 1.0172638893 0.0000002605 -0.0010274349 0.0000000037 -0.0000000002
-0.0000002179 1.6868000031 0.0000001932 -0.0003698469 -0.0000000112 0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 9 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001510824 0.0000188593 0.1246279478
-0.0000000895 1.6823668480 0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282180309 -0.0000000003 -0.0031026960 -0.0227645524 0.1245895997
-0.0000000895 1.6823668480 0.0000000000 0.7072144747 -0.0000000105 0.0000001792
-0.0000000312 1.0038089752 0.0000000901 -0.0000000000 0.0000000000 -0.0000000000
-0.0000000751 1.6051955223 0.0000002119 -0.0000000000 0.0000000000 -0.0000000000
-0.0000000895 1.6823668480 0.0000000000 -0.7069992423 0.0000000316 -0.0000001370
0.0000000903 1.0172638893 0.0000003583 -0.0010274349 -0.0000000000 -0.0000000002
0.0000000731 1.6867996454 -0.0000000750 -0.0003698471 0.0000000074 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 10 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001509869 0.0000197576 0.1305261850
0.0000000893 1.6823668480 -0.0000000001 0.0004014244 -0.0000001192 0.0000000075
-0.0000000596 1.0282181501 0.0000000001 -0.0032376507 -0.0227486361 0.1304862797
0.0000000893 1.6823668480 -0.0000000001 0.7072145343 -0.0000000052 0.0000001739
0.0000000347 1.0038089752 0.0000001936 -0.0000000000 -0.0000000298 -0.0000000000
0.0000000604 1.6051954031 0.0000002693 -0.0000000000 -0.0000000224 -0.0000000000
0.0000000893 1.6823668480 -0.0000000001 -0.7069992423 0.0000000474 -0.0000001264
-0.0000000651 1.0172638893 0.0000001706 -0.0010274349 -0.0000000000 -0.0000000001
-0.0000001531 1.6867997646 -0.0000006258 -0.0003698471 -0.0000000149 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}

1730
models/robot/Robot.md5mesh Normal file

File diff suppressed because it is too large Load Diff

369
models/robot/Walk.md5anim Normal file
View File

@ -0,0 +1,369 @@
MD5Version 10 // Parameters used during export: Reorient: False; Scale: 1.0
commandline ""
numFrames 16
numJoints 16
frameRate 24
numAnimatedComponents 96
hierarchy {
"Base.Bone" -1 63 0 //
"Spine.Low" 0 63 6 //
"Spine.High" 1 63 12 //
"Head" 2 63 18 //
"Chest.Left" 1 63 24 //
"Arm.Upper.Left" 4 63 30 //
"Arm.End.Left" 5 63 36 //
"Chest.Right" 1 63 42 //
"Arm.Upper.Right" 7 63 48 //
"Arm.End..Right" 8 63 54 //
"Pelvis.Left" 0 63 60 //
"Leg-Upper.Left" 10 63 66 //
"Leg-Lower.Left" 11 63 72 //
"Pelvis.Right" 0 63 78 //
"Leg-Upper.Right" 13 63 84 //
"Leg-Lower.Right" 14 63 90 //
}
bounds {
( -0.9293234944 -4.2354345322 -0.0544311851 ) ( 0.8719264269 4.2148847580 6.9405498505 )
( -1.0458128452 -4.2354345322 -0.0236645192 ) ( 1.0388165712 4.2148847580 6.9405498505 )
( -1.3107413054 -4.2354345322 0.0775131434 ) ( 1.4243863821 4.2148847580 6.9405498505 )
( -1.5972797871 -4.2354345322 0.2472080886 ) ( 1.8471746445 4.2148847580 6.9405498505 )
( -1.8157382011 -4.2354345322 0.4185062945 ) ( 2.1569662094 4.2148847580 6.9405498505 )
( -1.9043009281 -4.2354345322 0.4947580099 ) ( 2.2725346088 4.2148847580 6.9405498505 )
( -1.7948114872 -4.2354345322 0.4196288884 ) ( 2.0962657928 4.2148847580 6.9405498505 )
( -1.4885433912 -4.2354345322 0.2174991071 ) ( 1.5707708597 4.2148847580 6.9405498505 )
( -1.0223510265 -4.2354345322 -0.0271632373 ) ( 0.7556711435 4.2148847580 6.9405498505 )
( -0.7313704491 -4.2354345322 -0.0812678784 ) ( 0.7313704491 4.2148847580 6.9405498505 )
( -1.2197206020 -4.2354345322 0.0028566271 ) ( 0.8424327374 4.2148847580 6.9405498505 )
( -1.5773223639 -4.2354345322 0.1206776351 ) ( 1.1125847101 4.2148847580 6.9405498505 )
( -1.7957235575 -4.2354345322 0.2621092200 ) ( 1.5031591654 4.2148847580 6.9405498505 )
( -1.9242287874 -4.2354345322 0.4173001647 ) ( 1.7879552841 4.2148847580 6.9405498505 )
( -1.9862020016 -4.2354345322 0.5110104084 ) ( 1.9640272856 4.2148847580 6.9405498505 )
( -2.0022869110 -4.2354345322 0.5263599157 ) ( 2.0253751278 4.2148847580 6.9405498505 )
}
baseframe {
( 0.0000000000 0.0000000000 0.0000000000 ) ( -0.7071068287 -0.0000000000 -0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( -0.0001522740 -0.0000001192 -0.0000000000 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( 0.0004014244 -0.0000001192 0.0000000001 )
( -0.0000000000 1.0282182693 0.0000000000 ) ( -0.0002491503 0.0000001192 -0.0000000001 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( 0.7072144151 0.0000000000 0.0000001686 )
( 0.0000000000 1.0038089752 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( 0.0000000000 1.6051955223 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( -0.7069991827 0.0000000309 -0.0000001377 )
( -0.0000000000 1.0172638893 0.0000000000 ) ( -0.0000000000 -0.0000000000 0.0000000000 )
( 0.0000000000 1.6867997646 0.0000000000 ) ( -0.0000000000 -0.0000000000 0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( 0.7113879919 -0.0000000000 -0.0000000000 )
( 0.0000000000 0.4849954247 0.0000000428 ) ( 0.7027994990 -0.0000000848 0.0000000838 )
( 0.0000000000 1.3662177324 0.0000000284 ) ( -0.0000000005 0.0000001192 -0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( -0.7112751007 0.0000003352 0.0000003392 )
( 0.0000000000 0.5501293540 -0.0000000224 ) ( -0.7029137611 0.0000000000 0.0000006704 )
( 0.0000000000 1.3662178516 0.0000000000 ) ( 0.0000000000 0.0000000000 0.0000000000 )
}
frame 0 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6896103024 0.1355167776 0.1371729970
0.0000001413 1.3662177324 0.0000000187 0.0000000249 0.0000001072 -0.1588750184
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7005396485 0.0577241890 -0.0584101677
-0.0000000067 1.3662179708 -0.0000000321 -0.0000000664 -0.0000000018 -0.0709197745
}
frame 1 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6852083206 0.1562582403 0.1581679285
0.0000001923 1.3662178516 0.0000000334 0.0000000249 0.0000001072 -0.1589818746
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6998441815 0.0656199306 -0.0663998425
0.0000000114 1.3662179708 -0.0000000826 -0.0000000847 -0.0000000018 -0.0906898752
}
frame 2 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6720466018 0.2056226581 0.2081356496
0.0000000655 1.3662179708 0.0000000203 0.0000000249 0.0000001072 -0.1592366844
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6978245974 0.0844313428 -0.0854349956
-0.0000000109 1.3662178516 0.0000000094 -0.0000001283 -0.0000000018 -0.1378868669
}
frame 3 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6515526772 0.2634504139 0.2666700780
0.0000000105 1.3662178516 -0.0000000096 0.0000000250 0.0000001072 -0.1595407277
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6947497129 0.1068205833 -0.1080905795
-0.0000000076 1.3662182093 0.0000000382 -0.0000001800 -0.0000000018 -0.1939497739
}
frame 4 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6306926608 0.3100867867 0.3138763011
0.0000000920 1.3662182093 0.0000000255 0.0000000250 0.0000001072 -0.1597955972
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6916148067 0.1255260855 -0.1270185858
-0.0000000109 1.3662178516 -0.0000000162 -0.0000002229 -0.0000000018 -0.2403239459
}
frame 5 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6210514307 0.3289715052 0.3329917490
0.0000001049 1.3662180901 0.0000000182 0.0000000317 0.0000001165 -0.1599022895
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6901251674 0.1334736049 -0.1350606233
-0.0000000369 1.3662176132 -0.0000000686 -0.0000002406 -0.0000000037 -0.2595294714
}
frame 6 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6352671385 0.3006039858 0.3042775989
-0.0000001130 1.3662179708 0.0000000147 0.0000000317 0.0000001165 -0.1599023789
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6932111979 0.1163877100 -0.1177715063
0.0000000140 1.3662178516 0.0000000263 -0.0000002406 -0.0000000037 -0.2595294118
}
frame 7 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6657053828 0.2253073305 0.2280608118
0.0000000754 1.3662177324 0.0000000502 0.0000000317 0.0000001165 -0.1599022895
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6993994713 0.0702017918 -0.0710362121
-0.0000000361 1.3662178516 -0.0000000057 -0.0000002406 -0.0000000037 -0.2595295012
}
frame 8 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6922708154 0.1211950257 0.1226761565
0.0000000730 1.3662177324 -0.0000000340 0.0000000317 0.0000001165 -0.1599022895
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029032707 0.0038304022 -0.0038752994
-0.0000000007 1.3662179708 -0.0000000166 -0.0000002406 -0.0000000037 -0.2595294118
}
frame 9 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7026294470 0.0154647175 0.0156537984
-0.0000000087 1.3662178516 -0.0000000053 0.0000000317 0.0000001165 -0.1599023044
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6992585063 -0.0715904832 0.0724427402
0.0000000392 1.3662177324 0.0000000118 -0.0000002406 -0.0000000037 -0.2595294714
}
frame 10 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6998309493 -0.0645274892 -0.0653158873
0.0000000488 1.3662180901 0.0000000221 0.0000000317 0.0000001165 -0.1599023193
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6880680323 -0.1437002867 0.1454102993
0.0000000852 1.3662179708 -0.0000000192 -0.0000002406 -0.0000000037 -0.2595294118
}
frame 11 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6936322451 -0.1131437421 -0.1145262718
-0.0000000254 1.3662177324 0.0000000144 0.0000000322 0.0000001165 -0.1644932330
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6724037528 -0.2048428059 0.2072800696
0.0000000730 1.3662179708 0.0000000549 -0.0000002406 -0.0000000037 -0.2595294714
}
frame 12 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6881783605 -0.1426108927 -0.1443535239
0.0000000579 1.3662177324 0.0000000252 0.0000000335 0.0000001162 -0.1754287928
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6549473405 -0.2552087903 0.2582451999
0.0000000564 1.3662177324 0.0000000927 -0.0000002406 -0.0000000037 -0.2595294118
}
frame 13 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6847616434 -0.1582048237 -0.1601380259
0.0000000187 1.3662178516 0.0000000023 0.0000000351 0.0000001160 -0.1884543896
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6384723186 -0.2940076590 0.2975056171
-0.0000001045 1.3662178516 0.0000000140 -0.0000002406 -0.0000000037 -0.2595294118
}
frame 14 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6832824945 -0.1644753516 -0.1664851904
-0.0000000827 1.3662177324 0.0000000157 0.0000000364 0.0000001157 -0.1993409246
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6261911392 -0.3193308413 0.3231298923
0.0000000639 1.3662179708 0.0000000302 -0.0000002406 -0.0000000037 -0.2595294118
}
frame 15 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522739 0.0014036775 -0.0000002138
0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001194 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002490901 -0.0219670273 -0.0000054732
0.0000000000 1.6823660135 0.0000000000 0.7072144151 -0.0000000002 0.0000001686
-0.0000000000 1.0038089752 -0.0000001217 0.0000000000 0.0000000000 -0.0000000002
-0.0000000001 1.6051954031 -0.0000003165 0.0000000000 0.0000000000 -0.0000000002
0.0000000000 1.6823660135 0.0000000000 -0.7069991231 0.0000000308 -0.0000001377
-0.0000000003 1.0172637701 -0.0000001616 0.0110403588 0.0000000000 -0.0000000001
-0.0000000008 1.6867996454 0.0000001044 0.0173033401 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.6830017567 -0.1656379849 -0.1676620096
0.0000000580 1.3662179708 0.0000000307 0.0000000358 0.0000001140 -0.2038977891
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.6214444637 -0.3284724653 0.3323804140
0.0000001047 1.3662180901 0.0000000276 -0.0000002406 -0.0000000037 -0.2595293820
}

469
models/robot/Wave.md5anim Normal file
View File

@ -0,0 +1,469 @@
MD5Version 10 // Parameters used during export: Reorient: False; Scale: 1.0
commandline ""
numFrames 21
numJoints 16
frameRate 24
numAnimatedComponents 96
hierarchy {
"Base.Bone" -1 63 0 //
"Spine.Low" 0 63 6 //
"Spine.High" 1 63 12 //
"Head" 2 63 18 //
"Chest.Left" 1 63 24 //
"Arm.Upper.Left" 4 63 30 //
"Arm.End.Left" 5 63 36 //
"Chest.Right" 1 63 42 //
"Arm.Upper.Right" 7 63 48 //
"Arm.End..Right" 8 63 54 //
"Pelvis.Left" 0 63 60 //
"Leg-Upper.Left" 10 63 66 //
"Leg-Lower.Left" 11 63 72 //
"Pelvis.Right" 0 63 78 //
"Leg-Upper.Right" 13 63 84 //
"Leg-Lower.Right" 14 63 90 //
}
bounds {
( -0.7288464904 -4.2145261765 -0.1051818728 ) ( 0.7288464904 4.2140474319 6.9405498505 )
( -0.7302514911 -4.2225360870 -0.1051818728 ) ( 0.7302514911 4.2145175934 6.9405498505 )
( -0.7343894839 -4.2448711395 -0.1051818728 ) ( 0.7343894839 4.2158436775 6.9405498505 )
( -0.7411305904 -4.2661142349 -0.1051818728 ) ( 0.7411305904 4.2178220749 6.9405498505 )
( -0.7503278852 -4.2707734108 -0.1051818728 ) ( 0.7503278852 4.2201490402 6.9405498505 )
( -0.7618184090 -4.2458715439 -0.1051818728 ) ( 0.7618184090 4.2224359512 6.9405498505 )
( -0.7754249573 -4.1845750809 -0.1051818728 ) ( 0.7754249573 4.2242231369 6.9405498505 )
( -0.7909565568 -4.0881261826 -0.1051818728 ) ( 0.7909565568 4.2249913216 6.9405498505 )
( -0.8082096577 -3.9748272896 -0.1051818728 ) ( 0.8082096577 4.2241716385 6.9405498505 )
( -0.8316085339 -3.8554317951 -0.1051818728 ) ( 0.8716588616 4.2211618423 6.9405498505 )
( -0.9071020484 -3.7363846302 -0.1051818728 ) ( 0.9725581408 4.2153348923 6.9405498505 )
( -0.9845415950 -3.6244606972 -0.1051818728 ) ( 1.0805976391 4.2060980797 6.9405498505 )
( -1.0607581139 -3.5166521072 -0.1051818728 ) ( 1.1924948692 4.1931948662 6.9405498505 )
( -1.1330087185 -3.4139099121 -0.1051818728 ) ( 1.3043855429 4.1768159866 7.0152153969 )
( -1.1990523338 -3.3173723221 -0.1051818728 ) ( 1.4124979973 4.1575984955 7.1181468964 )
( -1.2571754456 -3.2286412716 -0.1051818728 ) ( 1.5131845474 4.1366162300 7.2063169479 )
( -1.3061861992 -3.1498517990 -0.1051818728 ) ( 1.6029434204 4.1153287888 7.2786159515 )
( -1.3453353643 -3.0836009979 -0.1051818728 ) ( 1.6784145832 4.0954933167 7.3345251083 )
( -1.3741520643 -3.0328018665 -0.1051818728 ) ( 1.7363419533 4.0790367126 7.3741292953 )
( -1.3921631575 -3.0004279613 -0.1051818728 ) ( 1.7735110521 4.0679025650 7.3978281021 )
( -1.3984949589 -2.9891591072 -0.1051818728 ) ( 1.7866519690 4.0638575554 7.4058084488 )
}
baseframe {
( 0.0000000000 0.0000000000 0.0000000000 ) ( -0.7071068287 -0.0000000000 -0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( -0.0001522740 -0.0000001192 -0.0000000000 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( 0.0004014244 -0.0000001192 0.0000000001 )
( -0.0000000000 1.0282182693 0.0000000000 ) ( -0.0002491503 0.0000001192 -0.0000000001 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( 0.7072144151 0.0000000000 0.0000001686 )
( 0.0000000000 1.0038089752 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( 0.0000000000 1.6051955223 0.0000000000 ) ( -0.0000000000 -0.0000000000 -0.0000000000 )
( -0.0000000000 1.6823664904 0.0000000001 ) ( -0.7069991827 0.0000000309 -0.0000001377 )
( -0.0000000000 1.0172638893 0.0000000000 ) ( -0.0000000000 -0.0000000000 0.0000000000 )
( 0.0000000000 1.6867997646 0.0000000000 ) ( -0.0000000000 -0.0000000000 0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( 0.7113879919 -0.0000000000 -0.0000000000 )
( 0.0000000000 0.4849954247 0.0000000428 ) ( 0.7027994990 -0.0000000848 0.0000000838 )
( 0.0000000000 1.3662177324 0.0000000284 ) ( -0.0000000005 0.0000001192 -0.0000000000 )
( 0.0000000000 2.9222633839 0.0000000000 ) ( -0.7112751007 0.0000003352 0.0000003392 )
( 0.0000000000 0.5501293540 -0.0000000224 ) ( -0.7029137611 0.0000000000 0.0000006704 )
( 0.0000000000 1.3662178516 0.0000000000 ) ( 0.0000000000 0.0000000000 0.0000000000 )
}
frame 0 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522740 -0.0000001192 -0.0000000000
0.0000000000 1.6823664904 0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 -0.0000000001 -0.0002490849 -0.0229121577 -0.0000057087
0.0000000000 1.6823664904 0.0000000000 0.7072144151 0.0000000000 0.0000001686
0.0000000000 1.0038089752 -0.0000001216 -0.0000000000 -0.0000000000 -0.0000000000
0.0000000000 1.6051954031 -0.0000003162 -0.0000000000 -0.0000000000 0.0000000000
0.0000000000 1.6823664904 0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
-0.0000000000 1.0172638893 0.0000001437 -0.0010274349 -0.0000000000 -0.0000000002
0.0000000000 1.6867997646 0.0000000624 -0.0003698472 -0.0000000000 -0.0000000001
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 1 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522740 0.0007809388 -0.0000001190
-0.0000000000 1.6823664904 -0.0000000002 0.0004014245 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 0.0000000002 -0.0002491252 -0.0141752968 -0.0000035319
-0.0000000000 1.6823664904 -0.0000000002 0.7072145343 0.0000000000 0.0000001686
0.0000000001 1.0038089752 0.0000000474 0.0000000000 0.0000000000 0.0000000000
-0.0000000000 1.6051954031 0.0000001233 0.0000000000 0.0000000000 0.0000000000
-0.0000000000 1.6823664904 -0.0000000002 -0.7069992423 0.0000000309 -0.0000001377
0.0000000000 1.0172638893 0.0000001436 0.0012860030 -0.0000000000 -0.0000000000
0.0000000002 1.6867997646 0.0000001346 0.0088065108 -0.0000000000 0.0000000000
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 2 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522733 0.0030870433 -0.0000004701
0.0000000000 1.6823667288 -0.0000000000 0.0004014244 -0.0000001192 0.0000000001
0.0000000000 1.0282177925 -0.0000000000 -0.0002491387 0.0096553192 0.0000024055
0.0000000000 1.6823667288 -0.0000000000 0.7072144151 0.0000000000 0.0000001686
-0.0000000001 1.0038089752 -0.0000001216 -0.0000000000 0.0000000000 0.0000000000
0.0000000019 1.6051951647 -0.0000003162 -0.0000000000 0.0000000000 0.0000000000
0.0000000000 1.6823667288 -0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
0.0000000008 1.0172638893 0.0000001437 0.0080480594 -0.0000000000 -0.0000000002
-0.0000000006 1.6867998838 -0.0000002356 0.0338387787 -0.0000000000 -0.0000000004
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 3 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522705 0.0068626930 -0.0000010450
-0.0000000000 1.6823660135 0.0000000000 0.0004014244 -0.0000001183 0.0000000001
-0.0000000000 1.0282182693 0.0000000002 -0.0002488978 0.0450159870 0.0000112156
-0.0000000000 1.6823660135 0.0000000000 0.7072145343 0.0000000000 0.0000001686
0.0000000007 1.0038088560 0.0000000474 -0.0000000000 0.0000000000 0.0000000000
0.0000000007 1.6051954031 0.0000001233 -0.0000000000 0.0000000000 0.0000000000
-0.0000000000 1.6823660135 0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
-0.0000000003 1.0172638893 0.0000001436 0.0189933572 0.0000000000 0.0000000000
-0.0000000040 1.6868000031 0.0000002628 0.0709822550 0.0000000000 -0.0000000010
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 4 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522630 0.0120524950 -0.0000018353
0.0000000000 1.6823664904 -0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282187462 -0.0000000003 -0.0002481799 0.0881715864 0.0000219679
0.0000000000 1.6823664904 -0.0000000000 0.7072145343 0.0000000000 0.0000001686
-0.0000000019 1.0038090944 0.0000005243 -0.0000000000 0.0000000000 -0.0000000014
-0.0000000027 1.6051955223 0.0000006002 -0.0000000000 0.0000000000 -0.0000000014
0.0000000000 1.6823664904 -0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
-0.0000000001 1.0172638893 0.0000001436 0.0338583253 0.0000000000 -0.0000000003
-0.0000000112 1.6867996454 -0.0000001846 0.1162938699 0.0000000003 -0.0000000018
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 5 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522477 0.0186010450 -0.0000028325
-0.0000000000 1.6823664904 0.0000000002 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 0.0000000002 -0.0002468648 0.1351395398 0.0000336699
-0.0000000000 1.6823664904 0.0000000002 0.7072145343 -0.0000000026 0.0000001712
-0.0000000006 1.0038089752 0.0000005244 -0.0000000000 0.0000000000 0.0000000009
-0.0000000014 1.6051952839 0.0000006005 -0.0000000000 0.0000000000 0.0000000009
-0.0000000000 1.6823664904 0.0000000002 -0.7069992423 0.0000000289 -0.0000001383
-0.0000000044 1.0172638893 0.0000001438 0.0523783863 -0.0000000001 0.0000000020
0.0000000097 1.6867998838 -0.0000005558 0.1655525118 -0.0000000004 -0.0000000013
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 6 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001522208 0.0264527462 -0.0000040281
-0.0000000000 1.6823664904 -0.0000000000 0.0004014244 -0.0000001155 0.0000000001
-0.0000000000 1.0282182693 0.0000000002 -0.0002449981 0.1818055809 0.0000452968
-0.0000000000 1.6823664904 -0.0000000000 0.7072145343 0.0000000000 0.0000001686
-0.0000000029 1.0038089752 0.0000005244 -0.0000000000 -0.0000000000 -0.0000000009
0.0000000132 1.6051951647 0.0000006005 -0.0000000000 -0.0000000000 -0.0000000009
-0.0000000000 1.6823664904 -0.0000000000 -0.7069992423 0.0000000316 -0.0000001410
-0.0000000029 1.0172637701 -0.0000003331 0.0742842183 -0.0000000001 -0.0000000011
0.0000000008 1.6867996454 -0.0000002992 0.2144013792 -0.0000000002 -0.0000000003
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 7 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001521778 0.0355514809 -0.0000054136
-0.0000000000 1.6823664904 0.0000000002 0.0004014244 -0.0000001136 0.0000000001
0.0000000000 1.0282182693 0.0000000001 -0.0002428102 0.2241564095 0.0000558485
-0.0000000000 1.6823664904 0.0000000002 0.7072145343 -0.0000000013 0.0000001725
-0.0000000067 1.0038089752 0.0000000478 -0.0000000000 -0.0000000000 0.0000000000
0.0000000111 1.6051954031 0.0000001242 -0.0000000000 -0.0000000000 0.0000000000
-0.0000000000 1.6823664904 0.0000000002 -0.7069992423 0.0000000296 -0.0000001416
-0.0000000067 1.0172638893 0.0000001440 0.0992979035 0.0000000001 -0.0000000059
-0.0000000166 1.6867995262 -0.0000000312 0.2586210966 0.0000000014 0.0000000046
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 8 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001521140 0.0458404459 -0.0000069803
-0.0000000000 1.6823667288 0.0000000000 0.0004014244 -0.0000001192 0.0000000001
0.0000000000 1.0282177925 -0.0000000005 -0.0002406830 0.2584845424 0.0000644014
-0.0000000000 1.6823667288 0.0000000000 0.7072145343 -0.0000000013 0.0000001725
0.0000000028 1.0038089752 -0.0000004288 -0.0000000000 0.0000000000 0.0000000056
0.0000000128 1.6051952839 -0.0000003520 -0.0000000000 0.0000000000 0.0000000056
-0.0000000000 1.6823667288 0.0000000000 -0.7069992423 0.0000000296 -0.0000001416
-0.0000000121 1.0172637701 0.0000006211 0.1271297634 -0.0000000002 -0.0000000003
-0.0000000402 1.6867995262 -0.0000000871 0.2943651974 -0.0000000016 0.0000000026
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 9 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001520242 0.0572618246 -0.0000087195
-0.0000000000 1.6823667288 -0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 0.0000000003 -0.0002390801 0.2814303637 0.0000701183
-0.0000000000 1.6823667288 -0.0000000000 0.7072145343 -0.0000000039 0.0000001699
-0.0000000038 1.0038089752 0.0000005252 -0.0000000000 -0.0000000000 0.0000000000
0.0000000214 1.6051952839 0.0000006025 -0.0000000000 -0.0000000000 0.0000000000
-0.0000000000 1.6823667288 -0.0000000000 -0.7069992423 0.0000000257 -0.0000001403
0.0000000037 1.0172638893 -0.0000003323 0.1574763954 -0.0000000000 -0.0000000038
-0.0000000724 1.6868000031 -0.0000001676 0.3181996644 0.0000000032 -0.0000000026
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 10 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001519031 0.0697563663 -0.0000106221
-0.0000000000 1.6823662519 -0.0000000001 0.0004014244 -0.0000001229 0.0000000001
0.0000000000 1.0282182693 0.0000000003 -0.0002384582 0.2898046970 0.0000722048
-0.0000000000 1.6823662519 -0.0000000001 0.7072144151 0.0000000000 0.0000001686
0.0000000032 1.0038089752 -0.0000001203 -0.0000000000 -0.0000000000 0.0000000000
0.0000000081 1.6051954031 -0.0000003129 -0.0000000000 0.0000000000 0.0000000000
-0.0000000000 1.6823662519 -0.0000000001 -0.7069991231 0.0000000309 -0.0000001377
0.0000000032 1.0172638893 -0.0000001603 0.1900207698 0.0000000002 0.0000000315
0.0000000743 1.6867997646 -0.0000004303 0.3268856704 0.0000000064 0.0000000426
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 11 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001517460 0.0832075551 -0.0000126704
-0.0000000000 1.6823662519 -0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 0.0000000001 -0.0002384582 0.2898046970 0.0000722048
-0.0000000000 1.6823662519 -0.0000000000 0.7072144151 0.0000000000 0.0000001686
0.0000000166 1.0038089752 -0.0000001198 -0.0000000000 0.0000000000 0.0000000037
-0.0000000082 1.6051956415 -0.0000003115 -0.0000000000 0.0000000000 0.0000000037
-0.0000000000 1.6823662519 -0.0000000000 -0.7069991231 0.0000000309 -0.0000001377
0.0000000166 1.0172640085 -0.0000001597 0.2244939208 0.0000000004 0.0000000297
-0.0000000525 1.6867994070 0.0000000428 0.3209972084 0.0000000034 0.0000000502
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 12 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001515526 0.0972274616 -0.0000148053
-0.0000000000 1.6823662519 0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 0.0000000002 -0.0002384582 0.2898047864 0.0000722048
-0.0000000000 1.6823662519 0.0000000000 0.7072144747 0.0000000000 0.0000001686
-0.0000000004 1.0038089752 -0.0000004268 -0.0000000000 0.0000000000 -0.0000000149
0.0000000198 1.6051956415 -0.0000003468 -0.0000000000 0.0000000000 -0.0000000149
-0.0000000000 1.6823662519 0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
0.0000000145 1.0172638893 0.0000006231 0.2600955665 -0.0000000006 0.0000000240
0.0000000242 1.6867995262 0.0000001453 0.3049138486 0.0000000036 0.0000000586
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 13 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001513271 0.1113469452 -0.0000169553
0.0000000000 1.6823667288 0.0000000000 0.0004014244 -0.0000001155 0.0000000001
-0.0000000001 1.0282182693 0.0000000001 -0.0002384582 0.2898046970 0.0000722048
0.0000000000 1.6823667288 0.0000000000 0.7072144151 0.0000000105 0.0000001791
-0.0000000027 1.0038089752 -0.0000005951 0.0000000000 -0.0000000000 0.0000000000
0.0000000023 1.6051954031 -0.0000007843 -0.0000000000 -0.0000000000 0.0000000000
0.0000000000 1.6823667288 0.0000000000 -0.7069992423 0.0000000415 -0.0000001482
-0.0000000027 1.0172638893 0.0000006240 0.2956701815 -0.0000000019 0.0000000218
-0.0000000373 1.6867995262 0.0000001416 0.2809669077 0.0000000075 0.0000000486
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 14 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001510779 0.1250958145 -0.0000190489
0.0000000000 1.6823664904 -0.0000000001 0.0004014244 -0.0000001118 0.0000000001
0.0000000000 1.0282182693 -0.0000000000 -0.0002384582 0.2898047566 0.0000722048
0.0000000000 1.6823664904 -0.0000000001 0.7072144747 0.0000000053 0.0000001686
-0.0000000045 1.0038089752 0.0000000516 -0.0000000000 0.0000000000 0.0000000000
0.0000000303 1.6051952839 0.0000001343 -0.0000000000 0.0000000000 0.0000000000
0.0000000000 1.6823664904 -0.0000000001 -0.7069992423 0.0000000282 -0.0000001403
-0.0000000343 1.0172638893 0.0000006247 0.3300409615 -0.0000000002 0.0000000325
-0.0000000204 1.6867997646 -0.0000000522 0.2515513599 -0.0000000046 0.0000000450
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 15 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001508170 0.1380039304 -0.0000210145
0.0000000000 1.6823664904 0.0000000000 0.0004014244 -0.0000001192 0.0000000001
0.0000000000 1.0282177925 0.0000000003 -0.0002384582 0.2898047268 0.0000722048
0.0000000000 1.6823664904 0.0000000000 0.7072144747 0.0000000000 0.0000001686
-0.0000000200 1.0038089752 0.0000000527 -0.0000000000 0.0000000000 0.0000000000
-0.0000000743 1.6051955223 0.0000001369 -0.0000000000 0.0000000000 0.0000000000
0.0000000000 1.6823664904 0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
-0.0000000200 1.0172640085 0.0000006258 0.3620411456 0.0000000009 0.0000000207
0.0000001122 1.6868000031 -0.0000000373 0.2192079574 -0.0000000036 0.0000000402
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 16 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001505604 0.1496035010 -0.0000227808
0.0000000000 1.6823662519 0.0000000001 0.0004014245 -0.0000001490 0.0000000001
-0.0000000000 1.0282177925 0.0000000002 -0.0002384583 0.2898046970 0.0000722048
0.0000000000 1.6823662519 0.0000000001 0.7072145343 -0.0000000158 0.0000001739
0.0000000257 1.0038089752 0.0000000534 -0.0000000000 -0.0000000000 0.0000000000
0.0000000214 1.6051954031 0.0000001389 -0.0000000000 -0.0000000000 0.0000000000
0.0000000000 1.6823662519 0.0000000001 -0.7069992423 0.0000000257 -0.0000001219
0.0000000257 1.0172638893 0.0000001497 0.3905433416 -0.0000000016 0.0000000269
-0.0000001459 1.6868002415 -0.0000002533 0.1866219640 0.0000000142 0.0000000415
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 17 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001503263 0.1594295800 -0.0000242770
0.0000000000 1.6823664904 -0.0000000000 0.0004014244 -0.0000001192 0.0000000001
-0.0000000000 1.0282182693 0.0000000003 -0.0002384582 0.2898047268 0.0000722048
0.0000000000 1.6823664904 -0.0000000000 0.7072144747 -0.0000000053 0.0000001739
0.0000000436 1.0038089752 0.0000000544 -0.0000000000 -0.0000000000 0.0000000075
-0.0000000206 1.6051952839 0.0000001415 -0.0000000000 -0.0000000000 0.0000000075
0.0000000000 1.6823664904 -0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
-0.0000000160 1.0172638893 0.0000001507 0.4144768417 -0.0000000065 0.0000000225
0.0000000429 1.6867992878 -0.0000002980 0.1565571874 -0.0000000064 0.0000000583
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 18 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001501351 0.1670198888 -0.0000254328
0.0000000000 1.6823664904 0.0000000000 0.0004014244 -0.0000001267 0.0000000001
-0.0000000000 1.0282182693 -0.0000000002 -0.0002384582 0.2898047268 0.0000722048
0.0000000000 1.6823664904 0.0000000000 0.7072145343 0.0000000000 0.0000001686
0.0000000047 1.0038089752 0.0000000550 -0.0000000000 -0.0000000000 0.0000000075
-0.0000000202 1.6051952839 0.0000001431 -0.0000000000 0.0000000000 0.0000000075
0.0000000000 1.6823664904 0.0000000000 -0.7069992423 0.0000000309 -0.0000001377
0.0000000048 1.0172638893 -0.0000003255 0.4328215122 -0.0000000056 0.0000000314
-0.0000000536 1.6868004799 -0.0000000745 0.1317730397 -0.0000000069 0.0000000533
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 19 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001500070 0.1719134748 -0.0000261780
-0.0000000000 1.6823664904 0.0000000002 0.0004014244 -0.0000001192 0.0000000001
0.0000000000 1.0282177925 -0.0000000001 -0.0002384582 0.2898046970 0.0000722048
-0.0000000000 1.6823664904 0.0000000002 0.7072145343 0.0000000000 0.0000001686
-0.0000000009 1.0038089752 0.0000000554 -0.0000000000 0.0000000000 0.0000000000
-0.0000000556 1.6051956415 0.0000001441 -0.0000000000 0.0000000000 0.0000000000
-0.0000000000 1.6823664904 0.0000000002 -0.7069992423 0.0000000309 -0.0000001377
-0.0000000009 1.0172638893 0.0000001517 0.4445825219 -0.0000000033 0.0000000193
-0.0000000521 1.6868000031 -0.0000003427 0.1149683520 -0.0000000006 0.0000000476
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}
frame 20 {
0.0000000000 0.0000000000 0.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.0001499606 0.1736480743 -0.0000264421
0.0000000000 1.6823662519 0.0000000001 0.0004014244 -0.0000001267 0.0000000001
-0.0000000001 1.0282177925 0.0000000002 -0.0002384583 0.2898046970 0.0000722048
0.0000000000 1.6823662519 0.0000000001 0.7072145343 0.0000000000 0.0000001686
-0.0000000031 1.0038089752 0.0000000557 -0.0000000000 0.0000000000 -0.0000000075
0.0000000017 1.6051952839 0.0000001449 -0.0000000000 0.0000000000 -0.0000000075
0.0000000000 1.6823662519 0.0000000001 -0.7069992423 0.0000000309 -0.0000001377
0.0000000267 1.0172640085 0.0000001520 0.4487406611 -0.0000000018 0.0000000778
-0.0000000491 1.6867994070 -0.0000004619 0.1087833345 -0.0000000035 0.0000000230
0.0000000000 2.9222633839 0.0000000000 0.7113879919 -0.0000000000 -0.0000000000
0.0000000000 0.4849954247 -0.0000000168 0.7027995586 -0.0000000848 0.0000000838
0.0000000000 1.3662177324 0.0000000481 -0.0000000005 0.0000001192 0.0000000000
0.0000000000 2.9222633839 0.0000000000 -0.7112751007 0.0000003352 0.0000003392
-0.0000000000 0.5501294136 -0.0000001211 -0.7029137611 0.0000000000 0.0000006704
-0.0000000000 1.3662177324 0.0000000257 0.0000000000 0.0000000000 -0.0000000000
}

BIN
models/robot/robot.blend Normal file

Binary file not shown.

BIN
models/robot/robot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

100
models/wiggle/Shake.md5anim Normal file
View File

@ -0,0 +1,100 @@
MD5Version 10 // Parameters used during export: Reorient: False; Scale: 1.0
commandline ""
numFrames 11
numJoints 3
frameRate 24
numAnimatedComponents 18
hierarchy {
"Base.Bone" -1 63 0 //
"Low.Bone" 0 63 6 //
"Top.Bone" 1 63 12 //
}
bounds {
( -1.0000000000 -1.0000000000 0.0000000000 ) ( 1.0000000000 1.0000000000 4.0000000000 )
( -1.0120840073 -1.0000000000 0.0000000000 ) ( 1.0003061295 1.1190146208 4.0462403297 )
( -1.0393997431 -1.0000000000 0.0000000000 ) ( 1.0029246807 1.3928407431 4.1396346092 )
( -1.0689740181 -1.0000000000 0.0000000000 ) ( 1.0095095634 1.6978781223 4.2185168266 )
( -1.0910409689 -1.0000000000 0.0000000000 ) ( 1.0178912878 1.9324455261 4.2562966347 )
( -1.0997276306 -1.0000000000 0.0000000000 ) ( 1.0222861767 2.0259232521 4.2644586563 )
( -1.0777884722 -1.0000000000 0.0000000000 ) ( 1.0124357939 1.7885386944 4.2360787392 )
( -1.0120604038 -1.0000000000 0.0000000000 ) ( 1.0003051758 1.1216876507 4.0468077660 )
( -1.0000000000 -1.7126641273 0.0000000000 ) ( 1.0838943720 1.0000000000 4.2086343765 )
( -1.0000000000 -2.2788333893 0.0000000000 ) ( 1.1701622009 1.0000000000 4.2129311562 )
( -1.0000000000 -2.4698538780 0.0000000000 ) ( 1.2063634396 1.0000000000 4.1580123901 )
}
baseframe {
( 0.0000000000 0.0000000000 -1.0000000000 ) ( -0.7071068287 -0.0000000000 -0.0000000000 )
( 0.0000000000 1.0000000000 0.0000000000 ) ( -0.0000000000 0.0000000000 0.0000000000 )
( 0.0000000000 2.0000000000 0.0000000000 ) ( 0.0000000000 -0.0000001192 -0.0000000000 )
}
frame 0 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 -0.0000000000 0.0000000000 0.0000000000
0.0000000000 2.0000000000 0.0000000000 0.0000000000 -0.0000001192 -0.0000000000
}
frame 1 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0058792681 0.0000000000 0.0000000000
-0.0000000000 2.0000000000 -0.0000000000 0.0167382173 0.0030841974 -0.0015240777
}
frame 2 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0198997837 0.0000000000 0.0000000000
0.0000000000 2.0000000000 -0.0000000000 0.0566667244 0.0104417428 -0.0051597194
}
frame 3 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0366287716 0.0000000000 0.0000000000
-0.0000000000 2.0000000000 -0.0000000000 0.1041958332 0.0191998351 -0.0094874240
}
frame 4 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0506385565 0.0000000000 0.0000000000
0.0000000000 2.0000000000 -0.0000000000 0.1438684016 0.0265102182 -0.0130997607
}
frame 5 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0565280803 0.0000000000 0.0000000000
0.0000000000 2.0000000000 -0.0000000000 0.1608683318 0.0296427645 -0.0146476682
}
frame 6 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0417185836 0.0000000000 0.0000000000
-0.0000000000 2.0000000000 -0.0000000000 0.1195185259 0.0220233202 -0.0108826142
}
frame 7 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 0.0062355879 0.0000000000 0.0000000000
0.0000000000 2.0000000000 -0.0000000000 0.0167051032 0.0030781047 -0.0015210635
}
frame 8 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 -0.0361813568 0.0000000000 0.0000000000
-0.0000000000 2.0000000000 -0.0000000000 -0.1076979935 -0.0198453981 0.0098063108
}
frame 9 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 -0.0716072023 0.0000000000 0.0000000000
0.0000000000 2.0000000000 -0.0000000000 -0.2089921087 -0.0385106616 0.0190295223
}
frame 10 {
0.0000000000 0.0000000000 -1.0000000000 -0.7071068287 -0.0000000000 -0.0000000000
0.0000000000 1.0000000000 0.0000000000 -0.0863967761 0.0000000000 0.0000000000
-0.0000000000 2.0000000000 -0.0000000000 -0.2498189807 -0.0460337400 0.0227469578
}

View File

@ -0,0 +1,103 @@
MD5Version 10 // Parameters used during export: Reorient: False; Scale: 1.0
commandline ""
numJoints 3
numMeshes 1
joints {
"Base.Bone" -1 ( 0.0000000000 0.0000000000 -1.0000000000 ) ( -0.7071068287 -0.0000000000 -0.0000000000 )
"Low.Bone" 0 ( -0.0000000000 0.0000000000 0.0000000000 ) ( -0.7071068287 -0.0000000000 0.0000000000 )
"Top.Bone" 1 ( -0.0000000000 -0.0000000000 2.0000000000 ) ( -0.7071068287 -0.0000000843 -0.0000000843 )
}
mesh {
shader "default"
numverts 32
vert 0 ( 0.3333333135 1.0000000000 ) 0 1
vert 1 ( 0.9999998808 0.6666666865 ) 1 1
vert 2 ( 0.0000000000 1.0000000000 ) 2 1
vert 3 ( 0.9999999404 1.0000000000 ) 3 1
vert 4 ( 0.3333333731 1.0000000000 ) 4 1
vert 5 ( 0.6666666269 0.6666667461 ) 5 1
vert 6 ( 0.0000000000 0.6666666269 ) 6 1
vert 7 ( 0.6666666269 1.0000000000 ) 7 1
vert 8 ( 0.3333333731 0.5000000000 ) 8 1
vert 9 ( 0.0000000000 0.8333333731 ) 9 1
vert 10 ( 0.0000000000 0.5000000000 ) 10 1
vert 11 ( 0.3333333731 0.8333333731 ) 11 1
vert 12 ( 0.0000000000 0.0000001192 ) 12 1
vert 13 ( 0.3333333731 0.6666666269 ) 13 1
vert 14 ( 0.3333332539 0.6666666865 ) 14 1
vert 15 ( 0.3333333731 0.3333333731 ) 15 1
vert 16 ( 0.0000000000 0.3333333731 ) 16 1
vert 17 ( 0.3333333135 0.6666666269 ) 17 1
vert 18 ( 0.0000000000 0.6666667461 ) 18 1
vert 19 ( 0.3333332539 0.3333333135 ) 19 1
vert 20 ( 0.3333332539 0.0000000596 ) 20 1
vert 21 ( 0.6666666865 0.6666666269 ) 21 1
vert 22 ( 0.3333333731 0.6666667461 ) 22 1
vert 23 ( 0.6666666269 0.3333333135 ) 23 1
vert 24 ( 0.3333333135 0.3333333731 ) 24 1
vert 25 ( 0.6666666865 1.0000000000 ) 25 1
vert 26 ( 0.0000000000 0.3333333731 ) 26 1
vert 27 ( 0.6666666269 0.6666666865 ) 27 1
vert 28 ( 0.3333332539 0.8333333135 ) 28 1
vert 29 ( 0.3333332539 0.4999999404 ) 29 1
vert 30 ( 0.6666666269 0.8333333135 ) 30 1
vert 31 ( 0.6666666269 0.4999999404 ) 31 1
numtris 20
tri 0 28 9 14
tri 1 29 10 19
tri 2 30 11 27
tri 3 31 8 23
tri 4 16 12 24
tri 5 7 5 3
tri 6 21 13 31
tri 7 25 4 30
tri 8 17 6 29
tri 9 0 2 28
tri 10 9 18 14
tri 11 10 26 19
tri 12 11 22 27
tri 13 8 15 23
tri 14 12 20 24
tri 15 5 1 3
tri 16 13 8 31
tri 17 4 11 30
tri 18 6 10 29
tri 19 2 9 28
numweights 32
weight 0 0 1.0000000000 ( -1.0000000000 1.0000000000 1.0000000000 )
weight 1 2 1.0000000000 ( -1.0000002384 2.0000000000 0.9999997616 )
weight 2 0 1.0000000000 ( -1.0000000000 1.0000000000 -1.0000000000 )
weight 3 2 1.0000000000 ( -0.9999997616 2.0000000000 -1.0000002384 )
weight 4 0 1.0000000000 ( 1.0000000000 1.0000000000 1.0000000000 )
weight 5 2 1.0000000000 ( 0.9999997616 2.0000000000 1.0000002384 )
weight 6 0 1.0000000000 ( 1.0000000000 1.0000000000 -1.0000000000 )
weight 7 2 1.0000000000 ( 1.0000002384 2.0000000000 -0.9999997616 )
weight 8 1 1.0000000000 ( -1.0000000000 2.0000000000 1.0000000000 )
weight 9 1 1.0000000000 ( -1.0000000000 2.0000000000 -1.0000000000 )
weight 10 1 1.0000000000 ( 1.0000000000 2.0000000000 -1.0000000000 )
weight 11 1 1.0000000000 ( 1.0000000000 2.0000000000 1.0000000000 )
weight 12 0 1.0000000000 ( -1.0000000000 1.0000000000 1.0000000000 )
weight 13 0 1.0000000000 ( -1.0000000000 1.0000000000 1.0000000000 )
weight 14 2 1.0000000000 ( -1.0000002384 2.0000000000 0.9999997616 )
weight 15 2 1.0000000000 ( -1.0000002384 2.0000000000 0.9999997616 )
weight 16 0 1.0000000000 ( -1.0000000000 1.0000000000 -1.0000000000 )
weight 17 0 1.0000000000 ( -1.0000000000 1.0000000000 -1.0000000000 )
weight 18 2 1.0000000000 ( -0.9999997616 2.0000000000 -1.0000002384 )
weight 19 2 1.0000000000 ( -0.9999997616 2.0000000000 -1.0000002384 )
weight 20 0 1.0000000000 ( 1.0000000000 1.0000000000 1.0000000000 )
weight 21 0 1.0000000000 ( 1.0000000000 1.0000000000 1.0000000000 )
weight 22 2 1.0000000000 ( 0.9999997616 2.0000000000 1.0000002384 )
weight 23 2 1.0000000000 ( 0.9999997616 2.0000000000 1.0000002384 )
weight 24 0 1.0000000000 ( 1.0000000000 1.0000000000 -1.0000000000 )
weight 25 0 1.0000000000 ( 1.0000000000 1.0000000000 -1.0000000000 )
weight 26 2 1.0000000000 ( 1.0000002384 2.0000000000 -0.9999997616 )
weight 27 2 1.0000000000 ( 1.0000002384 2.0000000000 -0.9999997616 )
weight 28 1 1.0000000000 ( -1.0000000000 2.0000000000 1.0000000000 )
weight 29 1 1.0000000000 ( -1.0000000000 2.0000000000 -1.0000000000 )
weight 30 1 1.0000000000 ( 1.0000000000 2.0000000000 -1.0000000000 )
weight 31 1 1.0000000000 ( 1.0000000000 2.0000000000 1.0000000000 )
}

BIN
models/wiggle/wiggle.blend Normal file

Binary file not shown.

BIN
models/wiggle/wiggle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

189
readme.rst Normal file
View File

@ -0,0 +1,189 @@
DSMA Library
============
Introduction
------------
**DSMA** (DS Model Animation) is a library that allows you to convert animated
models saved in MD5 format into a format that can be displayed in the Nintendo DS
in a very efficient way. This library depends on `libnds`, which comes with
`devkitPro`.
MD5 supports skeletal animation, which lets you reuse the same model with
multiple animations (a `md5mesh` file can be used with multiple `md5anim`
files). This library works in a similar way.
The converter used for this library is called `md5_to_dsma`, and it generates
the following files:
- **DSM** (DS Model): It contains a display list with the geometry of the model.
- **DSA** (DS Animation): It contains the position and orientation of all bones
in a specific animation sequence. You can have multiple `DSA` files for a
single `DSM` model if you have multiple animations for it.
The library supports interpolation between frames so that `DSA` can have a
smaller size by reducing the number of stored frames in it.
You are expected to load the files in some way (either including them as binary
data in your game, or loading them from the filesystem) and pass them to the
functions exposed by the library header.
There are multiple examples of how to use the library in this repository. They
all use `libnds`, and most of the 3D setup code is generic `libnds` 3D setup
code. You can test them with an emulator such as `DeSmuME` or `melonDS`, or in
real hardware with a flashcard.
- `basic_model`: Simply load an animated model embedded in the binary.
- `filesystem_loading`: Load models from the filesystem (with `nitroFS`).
- `multiple_animations`: Display one model with multiple animations.
- `performance`: Show how much CPU time it takes to draw an animated model.
- `stress_test`: Show multiple animated models with different animations.
This is an example of multiple models being displayed on the screen:
.. image:: examples/stress_test/screenshot.png
The library is under the MIT license, and the examples are licensed under the
CC0 license.
To get the latest version of this library, go to the repository:
https://github.com/AntonioND/ds-model-animation-library
Generating and converting MD5 models
------------------------------------
You can't use any MD5 model with this library. There is a limit in the number of
bones in the skeleton used in your model. Each bone transformation is stored as
one matrix in the DS matrix stack, which means that you have, at best, space for
29 bones. However, in most cases, the actual space will be smaller (because the
program also uses that space).
Also, it isn't possible to have multiple weights for the same vertex. The MD5
format mandates that all vertices are assigned at least one weight, but
`md5_to_dsma` will make sure that all vertices have assigned exactly one weight
with a value of 1.0.
You can use any 3D design tool to create your models, as long as you can export
them as MD5 later. Personally, I use blender to generate my models, and I use
this addon https://github.com/KozGit/Blender-2.8-MD5-import-export-addon to
export them as MD5 files. In short: Design your model as usual, making sure that
all your weights are 1.0. Then, clean up the weights of the model (to remove any
weight of 0.0, the exporter will fail if they aren't removed). Make sure that
all the bones have been moved to layer 5 (so that the exporter finds them) and
export the model and animations.
`md5_to_dsma` can be used to convert a `md5mesh` file, a list of `md5anim`
files, or both at the same time.
Convert all files in one run:
.. code::
md5_to_dsma.py --model Robot.md5mesh \
--name robot \
--output out_folder \
--texture 128 128 \
--anim Wave.md5anim Walk.md5anim Bow.md5anim
Convert the mesh only:
.. code::
md5_to_dsma.py --model Robot.md5mesh \
--name robot \
--output out_folder \
--texture 128 128
Convert the animations only:
.. code::
md5_to_dsma.py --anim Wave.md5anim Walk.md5anim Bow.md5anim \
--name robot \
--output out_folder
Converting textures
-------------------
In order to convert textures you can use some tool like
`nitro-texture-converter`, found here:
https://github.com/AntonioND/nitro-engine/tree/master/tools/nitro_texture_converter
`md5_to_dsma`
-------------
The options supported are:
- `--output`: Output folder. It will be created if it doesn't exist.
- `--model`: `md5mesh` file to convert. All MD5 models come with a base pose,
which is exported as a `DSA` file. The model itself is saved as a `DSM` file.
` `--texture`: Texture size of the model. This is required. The DS doesn't use
floating point values for texture coordinates, so you can only use textures of
the size specified when converting the model. For example, a 32x64 texture, do
`--texture 32 64`.
- `--anims`: List of `md5anim` files to convert. Each animation is saved as a
`DSA` file.
- `--name`: Base name used for the output files.
- `--blender-fix`: Blender uses Z as "up" axis, but the DS uses Y as "up". This
makes it very awkward to export models from Blender to DS. This option rotates
them by -90 degrees on the X axis so that they use the natural system of
coordinates of the DS instead of the one of Blender.
- `--bin`: When this is used, `.bin` is added to the end of all the names of the
files generated by the tool. This is useful if you want to copy the files to a
`data` folder of a `libnds` template and you don't want to modify the
`Makefile` to accept new file extensions. This option isn't required if you
are using `libfilesystem` or similar and you're loading files from a
filesystem.
- `--export-base-pose`: `md5mesh` files contain a base pose. This option will
export this base pose as a `DSA` file with one frame.
- `--skip-frames`: Number of animation frames to skip after exporting each
frame. For example, to skip half of the frames, do `--skip-frames 1`, and to
only export 25% of the frames, do `--skip-frames 3`.
- `--draw-normal-polygons`: This is only useful for debugging. It will export
additional polygons that represent the normals of the model in its base pose
(they won't move when you animate the model).
Displaying models on the NDS
----------------------------
The library only has two functions:
- ``uint32_t DSMA_GetNumFrames(const void *dsa_file)``
Returns the number of frames of the animation in a `DSA` file.
- ``int DSMA_DrawModel(const void *dsm_file, const void *dsa_file, uint32_t frame_interp)``
Draws the model in a `DSM` file with the animation in a `DSA` file.
The value of the frame to be drawn is a fixed point value (20.12, or `f32`).
If the frame is an integer value there is no interpolation between frames. If
the frame value is between frames the function will interpolate between them.
Future work
-----------
- Smooth shading (only flat shading is supported at the moment).
- Optimize normal commands (if multiple vertices belong to the same joint and
have the same normal).
- Container files to hold multiple `DSM` and `DSA` files.
Thanks to
---------
- devkitPro: https://devkitpro.org/
- Blender addon used to generate models: https://github.com/KozGit/Blender-2.8-MD5-import-export-addon
- MD5 format information: http://tfc.duke.free.fr/coding/md5-specs-en.html
- Quaternion to matrix conversion: http://www.songho.ca/opengl/gl_quaternion.html
- DeSmuME: http://desmume.org/
- melonDS: https://melonds.kuribo64.net/

324
tools/display_list.py Normal file
View File

@ -0,0 +1,324 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2022 Antonio Niño Díaz <antonio_nd@outlook.com>
def float_to_v16(val):
res = int(val * (1 << 12))
if res < -0x8000:
raise OverflowError(f"{val} too small for v16: {res:#04x}")
if res > 0x7FFF:
raise OverflowError(f"{val} too big for v16: {res:#04x}")
if res < 0:
res = 0x10000 + res
return res
def float_to_f32(val):
res = int(val * (1 << 12))
if res < -0x80000000:
raise OverflowError(f"{val} too small for f32: {res:#08x}")
if res > 0x7FFFFFFF:
raise OverflowError(f"{val} too big for f32: {res:#08x}")
if res < 0:
res = 0x100000000 + res
return res
def v16_to_float(val):
return val / (1 << 12)
def float_to_v10(val):
res = int(val * (1 << 6))
if res < -0x200:
raise OverflowError(f"{val} too small for v10: {res:#03x}")
if res > 0x1FF:
raise OverflowError(f"{val} too big for v10: {res:#03x}")
if res < 0:
res = 0x400 + res
return res
def v10_to_float(val):
return val / (1 << 6)
def float_to_diff10(val):
res = int(val * (1 << 9))
if res < -0x200:
raise OverflowError(f"{val} too small for diff10: {res:#03x}")
if res > 0x1FF:
raise OverflowError(f"{val} too big for diff10: {res:#03x}")
if res < 0:
res = 0x400 + res
return res
def diff10_to_float(val):
return val / (1 << 9)
def float_to_t16(val):
res = int(val * (1 << 4))
if res < -0x8000:
raise OverflowError(f"{val} too small for t16: {res:#04x}")
if res > 0x7FFF:
raise OverflowError(f"{val} too big for t16: {res:#04x}")
if res < 0:
res = 0x10000 + res
return res
def float_to_n10(val):
res = int(val * (1 << 9))
if res < -0x200:
#raise OverflowError(f"{val} too small for n10: {res:#03x}")
res = -0x200
if res > 0x1FF:
#raise OverflowError(f"{val} too big for n10: {res:#03x}")
res = 0x1FF
if res < 0:
res = 0x400 + res
return res
def command_name_to_id(name):
commands = {
"NOP": 0x00, # (0) No Operation (for padding packed GXFIFO commands)
"MTX_MODE": 0x10, # (1) Set Matrix Mode
"MTX_PUSH": 0x11, # (0) Push Current Matrix on Stack
"MTX_POP": 0x12, # (1) Pop Current Matrix from Stack
"MTX_STORE": 0x13, # (1) Store Current Matrix on Stack
"MTX_RESTORE": 0x14, # (1) Restore Current Matrix from Stack
"MTX_IDENTITY": 0x15, # (0) Load Unit Matrix to Current Matrix
"MTX_LOAD_4x4": 0x16, # (16) Load 4x4 Matrix to Current Matrix
"MTX_LOAD_4x3": 0x17, # (12) Load 4x3 Matrix to Current Matrix
"MTX_MULT_4x4": 0x18, # (16) Multiply Current Matrix by 4x4 Matrix
"MTX_MULT_4x3": 0x19, # (12) Multiply Current Matrix by 4x3 Matrix
"MTX_MULT_3x3": 0x1A, # (9) Multiply Current Matrix by 3x3 Matrix
"MTX_SCALE": 0x1B, # (3) Multiply Current Matrix by Scale Matrix
"MTX_TRANS": 0x1C, # (3) Mult. Curr. Matrix by Translation Matrix
"COLOR": 0x20, # (1) Directly Set Vertex Color
"NORMAL": 0x21, # (1) Set Normal Vector
"TEXCOORD": 0x22, # (1) Set Texture Coordinates
"VTX_16": 0x23, # (2) Set Vertex XYZ Coordinates
"VTX_10": 0x24, # (1) Set Vertex XYZ Coordinates
"VTX_XY": 0x25, # (1) Set Vertex XY Coordinates
"VTX_XZ": 0x26, # (1) Set Vertex XZ Coordinates
"VTX_YZ": 0x27, # (1) Set Vertex YZ Coordinates
"VTX_DIFF": 0x28, # (1) Set Relative Vertex Coordinates
"POLYGON_ATTR": 0x29, # (1) Set Polygon Attributes
"TEXIMAGE_PARAM": 0x2A, # (1) Set Texture Parameters
"PLTT_BASE": 0x2B, # (1) Set Texture Palette Base Address
"DIF_AMB": 0x30, # (1) MaterialColor0 # Diffuse/Ambient Reflect.
"SPE_EMI": 0x31, # (1) MaterialColor1 # Specular Ref. & Emission
"LIGHT_VECTOR": 0x32, # (1) Set Light's Directional Vector
"LIGHT_COLOR": 0x33, # (1) Set Light Color
"SHININESS": 0x34, # (32) Specular Reflection Shininess Table
"BEGIN_VTXS": 0x40, # (1) Start of Vertex List
"END_VTXS": 0x41, # (0) End of Vertex List
"SWAP_BUFFERS": 0x50, # (1) Swap Rendering Engine Buffer
"VIEWPORT": 0x60, # (1) Set Viewport
"BOX_TEST": 0x70, # (3) Test if Cuboid Sits inside View Volume
"POS_TEST": 0x71, # (2) Set Position Coordinates for Test
"VEC_TEST": 0x72, # (1) Set Directional Vector for Test
}
return commands[name]
def poly_type_to_id(name):
types = {
"triangles": 0,
"quads": 1,
"triangle_strip": 2,
"quad_strip": 3,
}
return types[name]
def error(x1, x2, y1, y2, z1, z2):
return (abs(x1 - x2) ** 2) + (abs(y1 - y2) ** 2) + (abs(z1 - z2) ** 2)
class DisplayList():
def __init__(self):
self.commands = []
self.parameters = []
self.vtx_last = None
self.texcoord_last = None
self.normal_last = None
self.begin_vtx_last = None
self.display_list = []
def add_command(self, command, *args):
self.commands.append(command)
if len(args) > 0:
self.parameters.extend(args)
if len(self.commands) == 4:
header = self.commands[0] | self.commands[1] << 8 | \
self.commands[2] << 16 | self.commands[3] << 24
self.display_list.append(header)
self.display_list.extend(self.parameters)
self.commands = []
self.parameters = []
def finalize(self):
# If there are pending commands, add NOPs to complete the display list
if len(self.commands) > 0:
padding = 4 - len(self.commands)
for i in range(padding):
self.nop()
# Prepend size to the list
self.display_list.insert(0, len(self.display_list))
def save_to_file(self, path):
with open(path, "wb") as f:
for u32 in self.display_list:
b = [u32 & 0xFF, \
(u32 >> 8) & 0xFF, \
(u32 >> 16) & 0xFF, \
(u32 >> 24) & 0xFF]
f.write(bytearray(b))
def nop(self):
self.add_command(command_name_to_id("NOP"))
def mtx_push(self):
self.add_command(command_name_to_id("MTX_PUSH"))
def mtx_pop(self, index):
self.add_command(command_name_to_id("MTX_POP"), index)
def mtx_restore(self, index):
self.add_command(command_name_to_id("MTX_RESTORE"), index)
def mtx_load_4x3(self, m):
fixed_m = [float_to_f32(v) for v in m]
self.add_command(command_name_to_id("MTX_LOAD_4x3"), *fixed_m)
def mtx_mult_4x3(self, m):
fixed_m = [float_to_f32(v) for v in m]
self.add_command(command_name_to_id("MTX_MULT_4x3"), *fixed_m)
def color(self, r, g, b):
arg = int(r * 31) | (int(g * 31) << 5) | (int(b * 31) << 10)
self.add_command(command_name_to_id("COLOR"), arg)
def normal(self, x, y, z):
# Skip if it's the same normal
if self.normal_last is not None:
if self.normal_last[0] == x and self.normal_last[1] == y and \
self.normal_last[2] == z:
return
arg = float_to_n10(x) | (float_to_n10(y) << 10) | float_to_n10(z) << 20
self.add_command(command_name_to_id("NORMAL"), arg)
self.normal_last = (x, y, z)
def texcoord(self, u, v):
# Skip if it's the same texcoord
if self.texcoord_last is not None:
if self.texcoord_last[0] == u and self.texcoord_last[1] == v:
return
arg = float_to_t16(u) | (float_to_t16(v) << 16)
self.add_command(command_name_to_id("TEXCOORD"), arg)
self.texcoord_last = (u, v)
def vtx_16(self, x, y, z):
args = [float_to_v16(x) | (float_to_v16(y) << 16), float_to_v16(z)]
self.add_command(command_name_to_id("VTX_16"), *args)
self.vtx_last = (x, y, z)
def vtx_10(self, x, y, z):
arg = float_to_v10(x) | (float_to_v10(y) << 10) | float_to_v10(z) << 20
self.add_command(command_name_to_id("VTX_10"), arg)
self.vtx_last = (x, y, z)
def vtx_xy(self, x, y):
arg = float_to_v16(x) | (float_to_v16(y) << 16)
self.add_command(command_name_to_id("VTX_XY"), arg)
self.vtx_last = (x, y, self.vtx_last[2])
def vtx_xz(self, x, z):
arg = float_to_v16(x) | (float_to_v16(z) << 16)
self.add_command(command_name_to_id("VTX_XZ"), arg)
self.vtx_last = (x, self.vtx_last[1], z)
def vtx_yz(self, y, z):
arg = float_to_v16(y) | (float_to_v16(z) << 16)
self.add_command(command_name_to_id("VTX_YZ"), arg)
self.vtx_last = (self.vtx_last[0], y, z)
def vtx_diff(self, x, y, z):
arg = float_to_diff10(x - self.vtx_last[0]) | \
(float_to_diff10(y - self.vtx_last[1]) << 10) | \
(float_to_diff10(z - self.vtx_last[2]) << 20)
self.add_command(command_name_to_id("VTX_DIFF"), arg)
self.vtx_last = (x, y, z)
def vtx(self, x, y, z):
"""
Picks the best vtx command based on the previous vertex and the error of
the conversion.
"""
# Allow {vtx_xy, vtx_yz, vtx_xz, vtx_diff} if there is a previous vertex
allow_diff = self.vtx_last is not None
# First, check if any of the coordinates is exactly the same as the
# previous command. We can trivially use vtx_xy, vtx_xz, vtx_yz because
# they have the min possible size and the max possible accuracy
if allow_diff:
if float_to_v16(self.vtx_last[0]) == float_to_v16(x):
self.vtx_yz(y, z)
return
elif float_to_v16(self.vtx_last[1]) == float_to_v16(y):
self.vtx_xz(x, z)
return
elif float_to_v16(self.vtx_last[2]) == float_to_v16(z):
self.vtx_xy(x, y)
return
# If not, there are three options: vtx_16, vtx_10, vtx_diff. Pick the
# one with the lowest error.
# TODO: Maybe use vtx_diff, but this may cause accuracy issues if it is
# used several times in a row.
error_vtx_16 = error(v16_to_float(float_to_v16(x)), x,
v16_to_float(float_to_v16(y)), y,
v16_to_float(float_to_v16(z)), z)
error_vtx_10 = error(v10_to_float(float_to_v10(x)), x,
v10_to_float(float_to_v10(y)), y,
v10_to_float(float_to_v10(z)), z)
if error_vtx_10 <= error_vtx_16:
self.vtx_10(x, y, z)
else:
self.vtx_16(x, y, z)
return
def begin_vtxs(self, poly_type):
self.add_command(command_name_to_id("BEGIN_VTXS"), poly_type_to_id(poly_type))
self.begin_vtx_last = poly_type
def end_vtxs(self):
self.add_command(command_name_to_id("END_VTXS"))
self.begin_vtx_last = None
def switch_vtxs(self, poly_type):
"""Sends a new BEGIN_VTXS if the polygon type has changed."""
if self.begin_vtx_last != poly_type:
if self.begin_vtx_last is not None:
self.end_vtxs()
self.begin_vtxs(poly_type)
if __name__ == "__main__":
dl = DisplayList()
dl.begin_vtxs("triangles")
dl.color(1.0, 0, 0)
dl.vtx_16(1.0, -1.0, 0)
dl.color(0, 1.0, 0)
dl.vtx_10(1.0, 1.0, 0)
dl.color(0, 0, 1.0)
dl.vtx_xy(-1.0, -1.0)
dl.end_vtxs()
dl.finalize()
print(', '.join([hex(i) for i in dl.display_list]))
dl.save_to_file("test.bin")

859
tools/md5_to_dsma.py Executable file
View File

@ -0,0 +1,859 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2022 Antonio Niño Díaz <antonio_nd@outlook.com>
import os
from collections import namedtuple
from math import sqrt
from display_list import DisplayList, float_to_f32
class MD5FormatError(Exception):
pass
VALID_TEXTURE_SIZES = [8, 16, 32, 64, 128, 256, 512, 1024]
def is_valid_texture_size(size):
return size in VALID_TEXTURE_SIZES
def assert_num_args(cmd, real, expected, tokens):
if real != expected:
raise MD5FormatError(f"Unexpected nargs for '{cmd}' ({real} != {expected}): {tokens}")
class Quaternion():
def __init__(self, w, x, y, z):
self.w = w
self.x = x
self.y = y
self.z = z
def to_v3(self):
return Vector(self.x, self.y, self.z)
def complement(self):
return Quaternion(self.w, -self.x, -self.y, -self.z)
def normalize(self):
mag = sqrt((self.w ** 2) + (self.x ** 2) + (self.y ** 2) + (self.z ** 2))
return Quaternion(self.w / mag, self.x /mag, self.y / mag, self.z / mag)
def mul(self, other):
w = (self.w * other.w) - (self.x * other.x) - (self.y * other.y) - (self.z * other.z)
x = (self.x * other.w) + (self.w * other.x) + (self.y * other.z) - (self.z * other.y)
y = (self.y * other.w) + (self.w * other.y) + (self.z * other.x) - (self.x * other.z)
z = (self.z * other.w) + (self.w * other.z) + (self.x * other.y) - (self.y * other.x)
return Quaternion(w, x, y, z)
def quaternion_fill_incomplete_w(v):
"""
This expands an incomplete quaternion, not a regular vector. This is
needed if a quaternion is stored as the components x, y and z and it is
expected that the code will fill the value of w.
"""
t = 1.0 - (v[0] * v[0]) - (v[1] * v[1]) - (v[2] * v[2])
if t < 0:
w = 0
else:
w = -sqrt(t)
return Quaternion(w, v[0], v[1], v[2])
class Vector():
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def to_q(self):
return Quaternion(0, self.x, self.y, self.z)
def length(self):
return sqrt((self.x ** 2) + (self.y ** 2) + (self.z ** 2))
def normalize(self):
mag = self.length()
return Vector(self.x / mag, self.y / mag, self.z / mag)
def add(self, other):
return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
def sub(self, other):
return Vector(self.x - other.x, self.y - other.y, self.z - other.z)
def cross(self, other):
x = (self.y * other.z) - (other.y * self.z)
y = (self.z * other.x) - (other.z * self.x)
z = (self.x * other.y) - (other.x * self.y)
return Vector(x, y, z)
def mul_m4x3(self, m):
x = (self.x * m[0][0]) + (self.y * m[0][1]) + (self.z * m[0][2]) + (m[0][3] * 1)
y = (self.x * m[1][0]) + (self.y * m[1][1]) + (self.z * m[1][2]) + (m[1][3] * 1)
z = (self.x * m[2][0]) + (self.y * m[2][1]) + (self.z * m[2][2]) + (m[2][3] * 1)
return Vector(x, y, z)
def joint_info_to_m4x3(q, trans):
"""
This generates a 4x3 matrix that represents a rotation and a translation.
q is a Quaternion with a orientation, trans is a Vector with a translation.
"""
wx = 2 * q.w * q.x
wy = 2 * q.w * q.y
wz = 2 * q.w * q.z
x2 = 2 * q.x * q.x
xy = 2 * q.x * q.y
xz = 2 * q.x * q.z
y2 = 2 * q.y * q.y
yz = 2 * q.y * q.z
z2 = 2 * q.z * q.z
return [[1 - y2 - z2, xy - wz, xz + wy, trans.x],
[ xy + wz, 1 - x2 - z2, yz - wx, trans.y],
[ xz - wy, yz + wx, 1 - x2 - y2, trans.z]]
def parse_md5mesh(input_file):
Joint = namedtuple("Joint", "name parent pos orient")
Vert = namedtuple("Vert", "st startWeight countWeight")
Weight = namedtuple("Weight", "joint bias pos")
Mesh = namedtuple("Mesh", "numverts verts numtris tris numweights weights")
joints = []
meshes = []
with open(input_file, 'r') as md5mesh_file:
numJoints = None
numMeshes = None
# This can have three values:
# - "root": Parsing commands in the md5mesh outside of any group
# - "joints": Inside a "joints" node.
# - "mesh": Inside a "mesh" node.
mode = "root"
# Temporary variables used to store mesh information before packing it
numverts = None
verts = None
numtris = None
tris = None
numweights = None
weights = None
for line in md5mesh_file:
# Remove comments
line = line.split('//')[0]
# Parse line
tokens = line.split()
if len(tokens) == 0: # Empty line
continue
cmd = tokens[0]
tokens = tokens[1:]
nargs = len(tokens)
if mode == "root":
if cmd == 'MD5Version':
assert_num_args('MD5Version', nargs, 1, tokens)
version = int(tokens[0])
if version != 10:
raise MD5FormatError(f"Invalid 'MD5Version': {version} != 10")
elif cmd == 'commandline':
# Ignore this
pass
elif cmd == 'numJoints':
assert_num_args('numJoints', nargs, 1, tokens)
numJoints = int(tokens[0])
if numJoints == 0:
raise MD5FormatError(f"'numJoints' is 0")
elif cmd == 'numMeshes':
assert_num_args('numMeshes', nargs, 1, tokens)
numMeshes = int(tokens[0])
if numMeshes == 0:
raise MD5FormatError(f"'numMeshes' is 0")
elif cmd == 'joints':
assert_num_args('joints', nargs, 1, tokens)
if tokens[0] != '{':
raise MD5FormatError(f"Unexpected token for 'joints': {tokens}")
if numJoints is None:
raise MD5FormatError("'joints' command before 'numJoints'")
mode = "joints"
elif cmd == 'mesh':
assert_num_args('mesh', nargs, 1, tokens)
if tokens[0] != '{':
raise MD5FormatError(f"Unexpected token for 'mesh': {tokens}")
if numMeshes is None:
raise MD5FormatError("'mesh' command before 'numMeshes'")
mode = "mesh"
else:
print(f"Ignored unsupported command: {cmd} {tokens}")
elif mode == "joints":
if cmd == '}':
if nargs > 0:
raise MD5FormatError(f"Unexpected tokens after 'joints {{}}': {tokens}")
mode = "root"
else:
_, name, line = line.split('"')
tokens = line.strip().split(" ")
nargs = len(tokens)
assert_num_args('joint entry', nargs, 11, tokens)
parent = int(tokens[0])
if tokens[1] != '(':
raise MD5FormatError(f"Unexpected token 1 for joint': {tokens}")
pos = Vector(float(tokens[2]), float(tokens[3]), float(tokens[4]))
if tokens[5] != ')':
raise MD5FormatError(f"Unexpected token 5 for joint': {tokens}")
if tokens[6] != '(':
raise MD5FormatError(f"Unexpected token 6 for joint': {tokens}")
orient = (float(tokens[7]), float(tokens[8]), float(tokens[9]))
q_orient = quaternion_fill_incomplete_w(orient)
if tokens[10] != ')':
raise MD5FormatError(f"Unexpected token 10 for joint': {tokens}")
joints.append(Joint(name, parent, pos, q_orient))
elif mode == "mesh":
if cmd == '}':
if nargs != 0:
raise MD5FormatError(f"Unexpected tokens after 'mesh {{}}': {tokens}")
mode = "root"
meshes.append(Mesh(numverts, verts, numtris, tris, numweights, weights))
numverts = None
verts = None
numtris = None
tris = None
numweights = None
weights = None
elif cmd == 'shader':
# Ignore this
pass
elif cmd == 'numverts':
assert_num_args('numverts', nargs, 1, tokens)
numverts = int(tokens[0])
verts = [None] * numverts
elif cmd == 'vert':
assert_num_args('vert', nargs, 7, tokens)
if numverts is None:
raise MD5FormatError("'vert' command before 'numverts'")
index = int(tokens[0])
if tokens[1] != '(':
raise MD5FormatError(f"Unexpected token 1 for vert': {tokens}")
st = (float(tokens[2]), float(tokens[3]))
if tokens[4] != ')':
raise MD5FormatError(f"Unexpected token 4 for vert': {tokens}")
startWeight = int(tokens[5])
countWeight = int(tokens[6])
if countWeight != 1:
raise MD5FormatError(
f"Vertex with {countWeight} weights detected, but this tool "
"only supports vertices with one weight. Ensure that all your "
"vertices are assigned exactly one weight with a bias of 1.0."
)
verts[index] = Vert(st, startWeight, countWeight)
elif cmd == 'numtris':
assert_num_args('numtris', nargs, 1, tokens)
numtris = int(tokens[0])
tris = [None] * numtris
elif cmd == 'tri':
assert_num_args('tri', nargs, 4, tokens)
if numtris is None:
raise MD5FormatError("'tri' command before 'numtris'")
index = int(tokens[0])
# Reverse order so that they face the right direction
vertIndices = (int(tokens[3]), int(tokens[2]), int(tokens[1]))
tris[index] = vertIndices
elif cmd == 'numweights':
assert_num_args('numweights', nargs, 1, tokens)
numweights = int(tokens[0])
weights = [None] * numweights
elif cmd == 'weight':
assert_num_args('weight', nargs, 8, tokens)
if numverts is None:
raise MD5FormatError("'weight' command before 'numweights'")
index = int(tokens[0])
jointIndex = int(tokens[1])
bias = float(tokens[2])
if bias != 1.0:
raise MD5FormatError(
f"Weight with bias {bias} detected, but this tool only"
"supports weights with bias equal to 1.0. Ensure that all"
"your vertices are assigned exactly one weight with a"
"bias of 1.0."
)
if tokens[3] != '(':
raise MD5FormatError(f"Unexpected token 3 for weight': {tokens}")
pos = Vector(float(tokens[4]), float(tokens[5]), float(tokens[6]))
if tokens[7] != ')':
raise MD5FormatError(f"Unexpected token 7 for weight': {tokens}")
weights[index] = Weight(jointIndex, bias, pos)
else:
print(f"Ignored unsupported command: {cmd} {tokens}")
if mode != "root":
raise MD5FormatError("Unexpected end of file (expected '}')")
realJoints = len(joints)
if numJoints != realJoints:
raise MD5FormatError(f"Incorrect number of joints: {numJoints} != {realJoints}")
realMeshes = len(meshes)
if numJoints != realJoints:
raise MD5FormatError(f"Incorrect number of joints: {numJoints} != {realJoints}")
return (joints, meshes)
def parse_md5anim(input_file):
Joint = namedtuple("Joint", "name parent pos orient")
joints = []
frames = []
with open(input_file, 'r') as md5anim_file:
numFrames = None
numJoints = None
baseframe = []
hierarchy = []
# This can have three values:
# - "root": Parsing commands in the md5mesh outside of any group
# - "hierarchy": Inside a "hierarchy" node.
# - "bounds": Inside a "bounds" node.
# - "baseframe": Inside a "baseframe" node.
# - "frame": Inside a "frame" node.
mode = "root"
frame_index = None
for line in md5anim_file:
# Remove comments
line = line.split('//')[0]
# Parse line
tokens = line.split()
if len(tokens) == 0: # Empty line
continue
cmd = tokens[0]
tokens = tokens[1:]
nargs = len(tokens)
if mode == "root":
if cmd == 'MD5Version':
assert_num_args('MD5Version', nargs, 1, tokens)
version = int(tokens[0])
if version != 10:
raise MD5FormatError(f"Invalid 'MD5Version': {version} != 10")
elif cmd == 'commandline':
# Ignore this
pass
elif cmd == 'numFrames':
assert_num_args('numFrames', nargs, 1, tokens)
numFrames = int(tokens[0])
if numFrames == 0:
raise MD5FormatError(f"'numFrames' is 0")
frames = [None] * numFrames
elif cmd == 'numJoints':
assert_num_args('numJoints', nargs, 1, tokens)
numJoints = int(tokens[0])
if numJoints == 0:
raise MD5FormatError(f"'numJoints' is 0")
elif cmd == 'frameRate':
# Ignore this
pass
elif cmd == 'numAnimatedComponents':
# Ignore this
pass
elif cmd == 'hierarchy':
assert_num_args('hierarchy', nargs, 1, tokens)
if tokens[0] != '{':
raise MD5FormatError(f"Unexpected token for 'hierarchy': {tokens}")
mode = "hierarchy"
elif cmd == 'bounds':
assert_num_args('bounds', nargs, 1, tokens)
if tokens[0] != '{':
raise MD5FormatError(f"Unexpected token for 'bounds': {tokens}")
mode = "bounds"
elif cmd == 'baseframe':
assert_num_args('baseframe', nargs, 1, tokens)
if tokens[0] != '{':
raise MD5FormatError(f"Unexpected token for 'baseframe': {tokens}")
mode = "baseframe"
elif cmd == 'frame':
assert_num_args('frame', nargs, 2, tokens)
frame_index = int(tokens[0])
if tokens[1] != '{':
raise MD5FormatError(f"Unexpected token for 'frame': {tokens}")
if numFrames is None:
raise MD5FormatError("'frame' command before 'numFrames'")
mode = "frame"
joints = []
else:
print(f"Ignored unsupported command: {cmd} {tokens}")
elif mode == "hierarchy":
if cmd == '}':
if nargs > 0:
raise MD5FormatError(f"Unexpected tokens after 'hierarchy {{}}': {tokens}")
mode = "root"
else:
_, name, line = line.split('"')
tokens = line.strip().split(" ")
nargs = len(tokens)
assert_num_args('hierarchy entry', nargs, 3, tokens)
parent_index = int(tokens[0])
flags = int(tokens[1])
if flags != 63:
raise MD5FormatError(f"Unexpected flags in hierarchy: {flags}")
frame_data_index = int(tokens[2])
hierarchy.append(parent_index)
elif mode == "bounds":
if cmd == '}':
if nargs > 0:
raise MD5FormatError(f"Unexpected tokens after 'bounds {{}}': {tokens}")
mode = "root"
else:
# Ignore everything else
pass
elif mode == "baseframe":
if cmd == '}':
if nargs > 0:
raise MD5FormatError(f"Unexpected tokens after 'baseframe {{}}': {tokens}")
mode = "root"
else:
values = line.strip().split()
assert_num_args('baseframe joint', len(values), 10, values)
if values[0] != '(':
raise MD5FormatError(f"Unexpected token 0 for baseframe': {values}")
pos = Vector(float(values[1]), float(values[2]), float(values[3]))
if values[4] != ')':
raise MD5FormatError(f"Unexpected token 4 for baseframe': {values}")
if values[5] != '(':
raise MD5FormatError(f"Unexpected token 5 for baseframe': {values}")
orient = (float(values[6]), float(values[7]), float(values[8]))
q_orient = quaternion_fill_incomplete_w(orient)
if values[9] != ')':
raise MD5FormatError(f"Unexpected token 9 for baseframe': {values}")
baseframe.append(Joint("", -1, pos, q_orient))
elif mode == "frame":
if cmd == '}':
if nargs > 0:
raise MD5FormatError(f"Unexpected tokens after 'frame {{}}': {tokens}")
mode = "root"
# Now that the frame has been read, process the real
# positions and orientations of the bones before storing
# them.
transformed_joints = []
for joint, parent_index in zip(joints, hierarchy):
if parent_index == -1:
# Root bone
transformed_joints.append(joint)
else:
parent_pos = transformed_joints[parent_index].pos
parent_orient = transformed_joints[parent_index].orient
this_pos = joint.pos
this_orient = joint.orient
q = parent_orient
qt = q.complement()
q_pos_delta = q.mul(this_pos.to_q()).mul(qt)
pos_delta = q_pos_delta.to_v3()
pos = parent_pos.add(pos_delta)
orient = parent_orient.mul(this_orient).normalize()
transformed_joints.append(Joint("", -1, pos, orient))
frames[frame_index] = transformed_joints
else:
values = line.strip().split()
assert_num_args('frame joint', len(values), 6, values)
pos = Vector(float(values[0]), float(values[1]), float(values[2]))
orient = (float(values[3]), float(values[4]), float(values[5]))
q_orient = quaternion_fill_incomplete_w(orient)
joints.append(Joint("", -1, pos, q_orient))
if mode != "root":
raise MD5FormatError("Unexpected end of file (expected '}')")
realJoints = len(joints)
if numJoints != realJoints:
raise MD5FormatError(f"Incorrect number of joints: {numJoints} != {realJoints}")
realFrames = len(frames)
if numFrames != realFrames:
raise MD5FormatError(f"Incorrect number of frames: {numFrames} != {realFrames}")
return frames
def save_animation(frames, output_file, blender_fix):
version = 1
num_frames = len(frames)
num_bones = len(frames[0])
u32_array = [version, num_frames, num_bones]
for joints in frames:
if num_bones != len(joints):
raise MD5FormatError("Different number of bones across frames")
for joint in joints:
this_pos = joint.pos
this_orient = joint.orient
if blender_fix:
# It is needed to rotate all bones because all bones have
# absolute transformations. Rotate orientation and position by
# -90 degrees on the X axis.
q_rot = Quaternion(0.7071068, -0.7071068, 0, 0)
this_orient = q_rot.mul(this_orient)
this_pos = Vector(this_pos.x, this_pos.z, -this_pos.y)
pos = [float_to_f32(this_pos.x), float_to_f32(this_pos.y),
float_to_f32(this_pos.z)]
orient = [float_to_f32(this_orient.w), float_to_f32(this_orient.x),
float_to_f32(this_orient.y), float_to_f32(this_orient.z)]
u32_array.extend(pos)
u32_array.extend(orient)
with open(output_file, "wb") as f:
for u32 in u32_array:
b = [u32 & 0xFF, \
(u32 >> 8) & 0xFF, \
(u32 >> 16) & 0xFF, \
(u32 >> 24) & 0xFF]
f.write(bytearray(b))
def convert_md5mesh(model_file, name, output_folder, texture_size,
draw_normal_polygons, suffix, blender_fix,
export_base_pose):
print(f"Converting model: {model_file}")
# Parse md5mesh file
joints, meshes = parse_md5mesh(model_file)
print(f"Loaded {len(joints)} joint(s) and {len(meshes)} mesh(es).")
if len(meshes) > 1:
print("WARNING: More than one mesh found. All meshes will share the same "
"texture. If you want them to have different textures, you must use "
"multiple .md5mesh files.")
if export_base_pose:
print("Converting base pose...")
save_animation([joints],
os.path.join(output_folder, f"{name}.dsa{suffix}"),
blender_fix)
print("Converting meshes...")
# Display list shared between all meshes
dl = DisplayList()
dl.switch_vtxs("triangles")
base_matrix = 30 - len(joints) + 1
last_joint_index = None
for mesh in meshes:
print(f" Vertices: {mesh.numverts}")
print(f" Tris: {mesh.numtris}")
print(f" Weights: {mesh.numweights}")
print(" Generating per-triangle normals...")
tri_normal = []
for tri in mesh.tris:
verts = [mesh.verts[i] for i in tri]
weights = [mesh.weights[v.startWeight] for v in verts]
vtx = []
for vert, weight in zip(verts, weights):
joint = joints[weight.joint]
m = joint_info_to_m4x3(joint.orient, joint.pos)
final = weight.pos.mul_m4x3(m)
vtx.append(final)
a = vtx[0].sub(vtx[1])
b = vtx[1].sub(vtx[2])
n = a.cross(b)
if n.length() > 0:
n = n.normalize()
tri_normal.append(n)
else:
tri_normal.append(Vector(0, 0, 0))
print(" Generating display list...")
for tri, norm in zip(mesh.tris, tri_normal):
verts = [mesh.verts[i] for i in tri]
weights = [mesh.weights[v.startWeight] for v in verts]
finals = []
for vert, weight in zip(verts, weights):
# Texture
# -------
st = vert.st
u = st[0] * texture_size[0]
v = st[1] * texture_size[1]
dl.texcoord(u, v)
# Vertex and normal
# -----------------
# Load joint matrix. When drawing normal polygons it has to be
# loaded every time, because drawing the normal restores the
# original matrix.
joint_index = weight.joint
if draw_normal_polygons or joint_index != last_joint_index:
dl.mtx_restore(base_matrix + joint_index)
last_joint_index = joint_index
# Calculate normal in joint space
joint = joints[joint_index]
q = joint.orient
qt = q.complement()
n = norm.to_q()
# Transform by the inverted quaternion
n = qt.mul(n).mul(q).to_v3()
if n.length() > 0:
n = n.normalize()
dl.normal(n.x, n.y, n.z)
# The vertex is already in joint space
dl.vtx(weight.pos.x, weight.pos.y, weight.pos.z)
if draw_normal_polygons:
# Calculate actual location of the vertex so that the
# vertices of the triangle can be averaged as origin of the
# normal polygon.
q = joint.orient
qt = q.complement()
v = weight.pos.to_q()
delta = q.mul(v).mul(qt).to_v3()
final = joint.pos.add(delta)
finals.append(final)
if draw_normal_polygons:
# Don't use any of the joint transformation matrices
dl.mtx_restore(1)
vert_avg = Vector(
(finals[0].x + finals[1].x + finals[2].x) / 3,
(finals[0].y + finals[1].y + finals[2].y) / 3,
(finals[0].z + finals[1].z + finals[2].z) / 3
)
vert_avg_end = vert_avg.add(norm)
dl.texcoord(0, 0)
dl.color(1, 0, 0)
dl.vtx(vert_avg.x + 0.1, vert_avg.y, vert_avg.z)
dl.vtx(vert_avg.x, vert_avg.y, vert_avg.z)
dl.color(0, 1, 0)
dl.vtx(vert_avg_end.x, vert_avg_end.y, vert_avg_end.z)
dl.color(1, 0, 0)
dl.vtx(vert_avg.x, vert_avg.y, vert_avg.z)
dl.vtx(vert_avg.x, vert_avg.y + 0.1, vert_avg.z)
dl.color(0, 1, 0)
dl.vtx(vert_avg_end.x, vert_avg_end.y, vert_avg_end.z)
dl.color(1, 0, 0)
dl.vtx(vert_avg.x, vert_avg.y, vert_avg.z)
dl.vtx(vert_avg.x, vert_avg.y, vert_avg.z + 0.1)
dl.color(0, 1, 0)
dl.vtx(vert_avg_end.x, vert_avg_end.y, vert_avg_end.z)
dl.end_vtxs()
dl.finalize()
dl.save_to_file(os.path.join(output_folder, f"{name}.dsm{suffix}"))
def convert_md5anim(name, output_folder, anim_file, skip_frames, suffix,
blender_fix):
print(f"Converting animation: {anim_file}")
frames = parse_md5anim(anim_file)
# Create name of animation based on file name
file_basename = os.path.basename(anim_file).replace(".md5anim", "")
anim_name = file_basename.replace(".", "_").lower()
frames = frames[::skip_frames+1]
save_animation(frames, os.path.join(output_folder,
f"{name}_{anim_name}.dsa{suffix}"), blender_fix)
if __name__ == "__main__":
import argparse
import sys
import traceback
print("md5_to_dsma v0.1.0")
print("Copyright (c) 2022 Antonio Niño Díaz <antonio_nd@outlook.com>")
print("All rights reserved")
print("")
parser = argparse.ArgumentParser(
description='Converts md5mesh and md5anim files into DSM and DSA files.')
# Required arguments
parser.add_argument("--name", required=True,
help="model name to be used in output files")
parser.add_argument("--output", required=True,
help="output folder")
# Optional arguments
parser.add_argument("--model", required=False, type=str, default=None,
help="input md5mesh file")
parser.add_argument("--texture", required=False, type=int, default=[],
nargs="+", action="extend",
help="texture width and height (e.g. '--texture 32 64')")
parser.add_argument("--anims", required=False, type=str, default=[],
nargs="+", action="extend",
help="list of md5anim files to convert")
parser.add_argument("--bin", required=False,
action='store_true',
help="add '.bin' to the name of the output files")
parser.add_argument("--blender-fix", required=False,
action='store_true',
help="rotate model -90 degrees on X axis to match Blender's orientation")
parser.add_argument("--export-base-pose", required=False,
action='store_true',
help="export base pose of a md5mesh as a DSA file")
parser.add_argument("--skip-frames", required=False,
default=0, type=int,
help="number of frames to skip in an animation (0 = export all, 1 = export half, 2 = export 33%, etc)")
parser.add_argument("--draw-normal-polygons", required=False,
action='store_true',
help="draw polygons with the shape of normals for debugging")
args = parser.parse_args()
if args.model is not None:
if len(args.texture) != 2:
print("Please, provide exactly 2 values to the --texture argument")
sys.exit(1)
if not is_valid_texture_size(args.texture[0]):
print(f"Invalid texture width. Valid values: {VALID_TEXTURE_SIZES}")
sys.exit(1)
if not is_valid_texture_size(args.texture[1]):
print(f"Invalid texture height. Valid values: {VALID_TEXTURE_SIZES}")
sys.exit(1)
# Create output directory if it doesn't exist
os.makedirs(args.output, exist_ok=True)
# Add '.bin' to the name of the files if requested
suffix = ".bin" if args.bin else ""
try:
if args.model is not None:
convert_md5mesh(args.model, args.name, args.output, args.texture,
args.draw_normal_polygons, suffix, args.blender_fix,
args.export_base_pose)
for anim_file in args.anims:
convert_md5anim(args.name, args.output, anim_file, args.skip_frames,
suffix, args.blender_fix)
except BaseException as e:
print("ERROR: " + str(e))
traceback.print_exc()
sys.exit(1)
except MD5FormatError as e:
print("ERROR: Invalid MD5 file: " + str(e))
traceback.print_exc()
sys.exit(1)
print("Done!")
sys.exit(0)