home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
MEDIT.LZH
/
MOTIONRW.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-12
|
13KB
|
439 lines
#include <iostream.h>
#include <math.h>
#include <string.h>
#include "matrix.h"
#include "bezier.h"
#include "motion.h"
#include "mecha.h"
#include "token.h"
#include "files.h"
#include "log.h"
static Vector readvector(TokenReader& reader, char *str)
{
Vector vec(0,0,0);
if ( str[0] != '(') return vec;
if (reader.GetToken(str) == 0 || str[0] == ')') return vec;
if (sscanf(str, "%lf", &(vec.x)) == 0) return vec;
if (reader.GetToken(str) == 0 || str[0] == ')') return vec;
if (sscanf(str, "%lf", &(vec.y)) == 0) return vec;
if (reader.GetToken(str) == 0 || str[0] == ')') return vec;
if (sscanf(str, "%lf", &(vec.z)) == 0) return vec;
if (reader.GetToken(str) == 0 || str[0] != ')') return vec;
return vec;
}
static int readheader(TokenReader& reader, int& begin, int& end, Vector& light, char *token)
{
reader.GetLine(token);
reader.GetLine(token);
reader.GetToken(token);
if (strcmpi(token, "Frame:") != 0) {
return FALSE;
}
reader.GetToken(token); begin = atoi(token);
reader.GetToken(token); end = atoi(token);
if (begin < 0 || end < begin) {
return FALSE;
}
light = Vector(-3.0, -2.0, -4.0);
light *= (1.0/light.length());
while (reader.GetToken(token)) {
if (strcmpi(token, "Light:") == 0) {
reader.GetToken(token);
if (token[0] == '(') {
Vector v = readvector(reader, token);
if (v.length() != 0.0) {
light = (1.0 / v.length()) * v;
}
}
}
if (strcmpi(token, "Motion:") == 0) {
return TRUE;
}
}
return FALSE;
}
Motion *Motion::ReadMotion(TokenReader& reader, char *token, int defaultbegin, int defaultend)
{
if (strcmpi(token, "Motion:") != 0) return NULL;
reader.GetToken(token);
reader.GetToken(token);
if (strcmpi(token, "Mechanic:") != 0) return NULL;
char filename[120]; reader.GetToken(filename);
reader.GetToken(token);
Mechanic *mec = NULL;
if (strcmpi(filename, "CAMERA") != 0
&& strcmpi(filename, "NONE") != 0
&& strcmpi(filename, "なし") != 0
&& strcmpi(filename, "TARGET") != 0) {
mec = MechaFile::OpenMechanic(filename);
}
int begin, end;
if (strcmpi(token, "Frame:") == 0) {
reader.GetToken(token); begin = atoi(token);
reader.GetToken(token); end = atoi(token);
if (begin < 0 || end < begin) return NULL;
reader.GetToken(token);
} else {
begin = defaultbegin;
end = defaultend;
}
if (strcmpi(token, "Bezier:") != 0) return NULL;
reader.GetToken(token);
if (token[0] != '(') return NULL;
Vector v = readvector(reader, token);
Bezier *b = new Bezier(v);
reader.GetToken(token);
while (token[0] == '(') {
Vector v1 = readvector(reader, token);
if (reader.GetToken(token) == 0 || token[0] != '(') break;
Vector v2 = readvector(reader, token);
if (reader.GetToken(token) == 0 || token[0] != '(') break;
Vector v3 = readvector(reader, token);
b->AddPoint(v1, v2, v3);
if (reader.GetToken(token) == 0) break;
}
if (b->points > 0) {
b->point[b->points*3+1] = 2.0 * b->point[b->points*3] - b->point[b->points*3-1];
} else {
b->point[1] = b->point[0];
}
b->UpdateLength();
Motion *m;
MotionData *md = NULL;
if (b->points == 0) {
m = new Motion(mec, begin, end, NULL);
m->position = b->point[0];
delete b;
} else {
m = new Motion(mec, begin, end, b);
md = m->motiondata;
md->dirtype = DirLinear;
}
if (strcmpi(token, "Position:") == 0) {
reader.GetToken(token);
int count = 0;
while (isdigit(token[0])) {
double speed;
if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
sscanf(token, "%lf", &speed);
if (md != NULL && count < 2) {
md->speed[count++] = speed;
}
if (reader.GetToken(token) == 0) break;
}
}
if (strcmpi(token, "Direction:") == 0) {
int count = 0;
reader.GetToken(token);
while (isdigit(token[0])) {
if (reader.GetToken(token) == 0) break;
if (token[0] == '(') {
Vector v = readvector(reader, token);
if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
if (md == NULL && count == 0) {
m->rotation = deg(1.0) * v;
count++;
} else if (md != NULL && count < 2) {
md->rotation[count++] = deg(1.0) * v;
}
if (reader.GetToken(token) == 0) break;
if (strcmpi(token, "Forward") == 0) {
if (md != NULL) {
md->dirtype = DirForward;
}
if (reader.GetToken(token) == 0) break;
}
} else {
break;
}
}
}
if (strcmpi(token, "Scale:") == 0) {
int count = 0;
reader.GetToken(token);
while (isdigit(token[0])) {
Vector v;
if (reader.GetToken(token) == 0 || token[0] != '(') break;
v = readvector(reader, token);
if (md == NULL && count == 0) {
m->scale = v;
count++;
} else if (md != NULL && count < 2) {
md->scale[count++] = v;
}
if (reader.GetToken(token) == 0) break;
}
}
return m;
}
int Motion::FileRead(Motion* &motion, CameraMotion* &camera, Vector& light, char *filename)
{
char token[128];
TokenReader reader(filename);
if (!reader.Suceed()) {
return -1;
}
int begin, end;
if (readheader(reader, begin, end, light, token) == FALSE) {
return -1;
}
Motion *m = Motion::ReadMotion(reader, token, begin, end);
if (m == NULL) {
return -1;
}
Motion *mt = Motion::ReadMotion(reader, token, begin, end);
if (mt == NULL) {
return -1;
}
camera = new CameraMotion(m, mt);
delete m;
motion = NULL;
while ((m = Motion::ReadMotion(reader, token, begin, end)) != NULL) {
m->next = motion;
motion = m;
}
return end;
}
void Motion::FileWriteList(Motion* motion, FILE *fp)
{
fprintf(fp, "Mechanic:\n");
for (Motion *m = motion; m != NULL; m = m->next) {
for (Motion *om = motion; om != m && om != NULL; om = om->next) {
if (om->mecha == m->mecha) {
break;
}
}
if (m->mecha != NULL && (om == m || om == NULL)) {
char str[120], *f;
f = m->mecha->filename;
if (strncmpi(m->mecha->filename, mechadir.c_str(), mechadir.length()) == 0) {
f = m->mecha->filename + mechadir.length();
}
strcpy(str, f);
int l = strlen(str);
if (l > 4 && str[l-4] == '.') {
str[l-4] = '\0';
}
fprintf(fp, "\t%s\n", str);
}
}
}
void Motion::GetName(char *str)
{
if (mecha != NULL) {
strcpy(str, mecha->name);
int l = strlen(str);
if (l > 4 && str[l-4] == '.') {
str[l-4] = '\0';
}
} else {
strcpy(str, "なし");
}
}
void CameraMotion::GetName(char *str)
{
strcpy(str, "CAMERA\n");
}
void Motion::MotionWrite(FILE *fp)
{
int i;
fprintf(fp, "Motion: 0\n");
char *f;
if (mecha == NULL) {
f = "NONE";
} else {
f = mecha->filename;
if (strncmpi(mecha->filename, mechadir.c_str(), mechadir.length()) == 0) {
f = mecha->filename + mechadir.length();
}
}
fprintf(fp, "\tMechanic: %s\n", f);
fprintf(fp, "\tFrame: %d %d\n", beginframe, endframe);
if (motiondata == NULL) {
fprintf(fp, "\tBezier:\n");
fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", position.x, position.y, position.z);
fprintf(fp, "\tPosition:\n");
fprintf(fp, "\tDirection:\n");
fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0\n", beginframe, rad(rotation.x), rad(rotation.y), rad(rotation.z));
fprintf(fp, "\tScale:\n");
fprintf(fp, "\t\t%3d ( %5.3lf %5.3lf %5.3lf )\n", beginframe, scale.x, scale.y, scale.z);
} else {
fprintf(fp, "\tBezier:\n");
Bezier *bezier = motiondata->bezier;
for (i = 0; i < bezier->points*3+1; ++i) {
fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", bezier->point[i].x, bezier->point[i].y, bezier->point[i].z);
}
fprintf(fp, "\tPosition:\n");
fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", beginframe, 0.0, 0, motiondata->speed[0]);
fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", endframe, bezier->TotalLength(), 0, motiondata->speed[1]);
fprintf(fp, "\tDirection:\n");
if (motiondata->dirtype == DirForward) {
fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0 Forward\n", beginframe,
rad(motiondata->rotation[0].x),
rad(motiondata->rotation[0].y),
rad(motiondata->rotation[0].z));
} else {
fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0\n", beginframe,
rad(motiondata->rotation[0].x),
rad(motiondata->rotation[0].y),
rad(motiondata->rotation[0].z));
fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0\n", endframe,
rad(motiondata->rotation[1].x),
rad(motiondata->rotation[1].y),
rad(motiondata->rotation[1].z));
}
fprintf(fp, "\tScale:\n");
fprintf(fp, "\t\t%3d ( %5.3lf %5.3lf %5.3lf )\n", beginframe,
motiondata->scale[0].x,
motiondata->scale[0].y,
motiondata->scale[0].z);
fprintf(fp, "\t\t%3d ( %5.3lf %5.3lf %5.3lf )\n", endframe,
motiondata->scale[1].x,
motiondata->scale[1].y,
motiondata->scale[1].z);
}
}
void CameraMotion::MotionWrite(FILE *fp)
{
int i;
fprintf(fp, "Motion: 0\n");
fprintf(fp, "\tMechanic: CAMERA\n");
fprintf(fp, "\tBezier:\n");
if (motiondata == NULL) {
fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", position.x, position.y, position.z);
} else {
Bezier *bezier = motiondata->bezier;
for (i = 0; i < bezier->points*3+1; ++i) {
fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", bezier->point[i].x, bezier->point[i].y, bezier->point[i].z);
}
fprintf(fp, "\tPosition:\n");
fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", beginframe, 0.0, 0, motiondata->speed[0]);
fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", endframe, bezier->TotalLength(), 0, motiondata->speed[1]);
}
fprintf(fp, "Motion: 0\n");
fprintf(fp, "\tMechanic: TARGET\n");
fprintf(fp, "\tBezier:\n");
if (motiondata == NULL) {
fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", target->position.x, target->position.y, target->position.z);
} else {
Bezier *bezier = target->motiondata->bezier;
for (i = 0; i < bezier->points*3+1; ++i) {
fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", bezier->point[i].x, bezier->point[i].y, bezier->point[i].z);
}
fprintf(fp, "\tPosition:\n");
fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", beginframe, 0.0, 0, target->motiondata->speed[0]);
fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", endframe, bezier->TotalLength(), 0, target->motiondata->speed[1]);
}
}
void Motion::PoseWrite(int frame, FILE *fp)
{
if (frame < beginframe || frame > endframe || mecha == NULL) {
return;
}
GetPosition(frame);
char n[120];
GetName(n);
fprintf(fp,
"\t{\tmov ( %8.1lf %8.1lf %8.1lf ) "
"rotz( %7.3lf ) roty( %7.3lf ) rotx( %7.3lf ) "
"scal ( %5.3lf %5.3lf %5.3lf ) obj %8s "
"}\n",
position.x, position.y, position.z,
rad(rotation.z), rad(rotation.y), rad(rotation.x),
scale.x, scale.y, scale.z, n);
}
void CameraMotion::PoseWrite(int frame, FILE *fp)
{
GetPosition(frame);
fprintf(fp,
"\t{\tmov ( %5.0lf %5.0lf %5.0lf ) "
"rotz( %7.3lf ) roty( %7.3lf ) rotx( %7.3lf ) "
"eye deg ( %d ) }\n",
position.x, position.y, position.z,
rad(rotation.z), rad(rotation.y), rad(rotation.x),
int(rad(angle)+0.5)
);
}
int Motion::FileWrite(Motion* motion, CameraMotion* camera, Vector& light, char *filename)
{
FILE *fp;
errormessage[0] = '\0';
if ((fp = fopen(filename, "w")) == NULL) {
sprintf(errormessage, "モーションファイルの保存に失敗しました : %s", _sys_errlist[errno]);
return FALSE;
}
Motion *m;
int maxframe = camera->endframe;
for (m = motion; m != NULL; m = m->next) {
if (maxframe < m->endframe) {
maxframe = m->endframe;
}
}
fprintf(fp,
"/* Motion Editor\n"
" Version 1.00γ\n"
"Frame: %d %d\n", BEGIN, maxframe);
FileWriteList(motion, fp);
fprintf(fp, "Light: ( %4.0lf %4.0lf %4.0lf )\n",
100.0 * light.x, 100.0 * light.y, 100.0 * light.z);
camera->MotionWrite(fp);
for (m = motion; m != NULL; m = m->next) {
if (m != camera && m != camera->target) {
m->MotionWrite(fp);
}
}
fprintf(fp, "*/\n");
for (int i = BEGIN; i <= maxframe; ++i) {
fprintf(fp, "fram\n{\n"
"\tlight pal( rgb ( 1.00 1.00 1.00 ) %4.0lf %4.0lf %4.0lf)\n",
100.0 * light.x, 100.0 * light.y, 100.0 * light.z);
camera->PoseWrite(i, fp);
for (m = motion; m != NULL; m = m->next) {
if (m != camera) {
m->PoseWrite(i, fp);
}
}
fprintf(fp, "}\n");
}
if (ferror(fp)) {
sprintf(errormessage, "モーションファイルの保存に失敗しました : %s", _sys_errlist[errno]);
fclose(fp);
return FALSE;
}
fclose(fp);
return TRUE;
}