home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
WIREVIEW.LZH
/
ANIM.CPP
next >
Wrap
C/C++ Source or Header
|
1996-07-10
|
11KB
|
388 lines
#include <owl\owlpch.h>
#pragma hdrstop
#include <owl\scrollba.h>
#include <owl\inputdia.h>
#include <owl\opensave.h>
#include <owl\slider.h>
#include <owl\statusba.h>
#include <owl\gadget.h>
#include <owl\textgadg.h>
#include <dir.h>
#include "matrix.h"
#include "anim.h"
#include "view.h"
#include "winframe.h"
#include "mecha.h"
#include "suflib.h"
#include "bezier.h"
#include "motion.h"
#include "files.h"
#include "syscolor.h"
#include "polyline.h"
#include "log.h"
AnimationData::AnimationData()
{
Frame = NULL;
PersView = NULL;
getcwd(filedir, filenamedirlength);
filename[0] = '\0';
motion = NULL;
camera = NULL;
wireframe = NULL;
InitMotion();
}
void AnimationData::CalcViewMatrix(void)
{
int fx, fy;
fx = PersView->Attr.W;
fy = PersView->Attr.H;
Matrix cmat;
// cmat = camera->GetMatrix(selectframe).inv();
camera->GetPosition(selectframe);
cmat = (Matrix::m_move(camera->position).rot(camera->rotation)).inv();
//logprintf("camera=\n");
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].x, cmat.v[1].x, cmat.v[2].x, cmat.v[3].x);
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].y, cmat.v[1].y, cmat.v[2].y, cmat.v[3].y);
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].z, cmat.v[1].z, cmat.v[2].z, cmat.v[3].z);
Matrix tmpmat(0);
tmpmat.v[0].z = tmpmat.v[1].x = tmpmat.v[2].y = 1.0;
cmat = tmpmat * cmat;
//logprintf("trans=\n");
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].x, cmat.v[1].x, cmat.v[2].x, cmat.v[3].x);
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].y, cmat.v[1].y, cmat.v[2].y, cmat.v[3].y);
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].z, cmat.v[1].z, cmat.v[2].z, cmat.v[3].z);
tmpmat = Matrix(1);
tmpmat.v[2].x = double(fx)/2.0;
tmpmat.v[2].y = double(fy)/2.0;
tmpmat.v[0].x = - fx / 2.0 / tan(camera->angle/2.0);
tmpmat.v[1].y = tmpmat.v[0].x;
cmat = tmpmat * cmat;
//logprintf("viewmat=\n");
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].x, cmat.v[1].x, cmat.v[2].x, cmat.v[3].x);
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].y, cmat.v[1].y, cmat.v[2].y, cmat.v[3].y);
//logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].z, cmat.v[1].z, cmat.v[2].z, cmat.v[3].z);
viewmat = cmat;
}
void AnimationData::CalcView(Motion *mot)
{
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
}
void AnimationData::CalcViewAll(void)
{
CalcViewMatrix();
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
}
}
void AnimationData::SelectFrame(int frame)
{
if (frame < BEGIN || frame > maxframe || selectframe == frame) {
return;
}
selectframe = frame;
frameCounter->SetPosition(selectframe);
}
static void split(char *dir, char *name, char *all)
{
char *p;
strcpy(dir, all);
if ((p = strrchr(dir, '\\')) != NULL) {
*p = '\0';
strcpy(name, p+1);
} else if ((p = strrchr(dir, '/')) != NULL) {
*p = '\0';
strcpy(name, p+1);
} else {
dir[0] = '\0';
strcpy(name, all);
}
}
void AnimationData::ReadFile(char *fname)
{
if (Frame != NULL) Frame->KillTimer(OpPlay);
if (Frame != NULL) Frame->KillTimer(OpPause);
Motion *nm;
Motion *next;
CameraMotion *nc;
Vector v;
char nfiledir[_MAX_PATH], nfilename[_MAX_PATH];
split(nfiledir, nfilename, fname);
int max;
if ((max = Motion::FileRead(nm, nc, v, fname)) >= 0) {
strcpy(filedir, nfiledir);
strcpy(filename, nfilename);
for (Motion *m = motion; m != NULL; m = next) {
next = m->next;
delete m;
}
delete camera;
motion = nm;
camera = nc;
maxframe = max;
opstat = OpPause;
SelectFrame(BEGIN);
SetCaption();
wireframe = new WireFrame[maxframe - BEGIN + 1];
if (frameCounter != NULL) {
frameCounter->SetRange(BEGIN, maxframe);
frameCounter->SetRuler(10);
}
for (int i = BEGIN; i <= maxframe; ++i) {
wireframe[i-BEGIN].line = NULL;
}
opstat = OpPlay;
// if (Frame != NULL) Frame->SetTimer(OpPause, 1000);
if (Frame != NULL) Frame->SetTimer(OpPlay, 300);
}
// if (Frame != NULL) Frame->SetTimer(OpPlay, 66);
}
void AnimationData::InitMotion(void)
{
if (Frame != NULL) Frame->KillTimer(OpPlay);
if (Frame != NULL) Frame->KillTimer(OpPause);
Motion *next, *m;
for (m = motion; m != NULL; m = next) {
next = m->next;
delete m;
}
FreeWireFrame();
filename[0] = '\0';
opstat = OpPause;
maxframe = BEGIN;
motion = NULL;
selectframe = BEGIN;
Motion *target = new Motion(NULL, BEGIN, maxframe);
if (camera != NULL) {
delete camera->target;
delete camera;
}
camera = new CameraMotion(target, maxframe);
camera->position = Vector(8000,6000,6000);
camera->GetPosition(BEGIN);
viewmat = Matrix(0);
}
void AnimationData::NewFile(void)
{
InitMotion();
SetCaption();
}
int AnimationData::GetMotionName(char *filename)
{
char str[128];
strcpy(str, motiondir.c_str());
str[strlen(str)-1] = '\0';
TOpenSaveDialog::TData FileData(
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
"モーションデザインファイル(*.frm)|*.frm|"
"すべてのファイル(*.*)|*.*|",
0, str, "fsc");
TFileOpenDialog OpenDlg(Frame, FileData);
if (OpenDlg.Execute() == IDOK) {
strcpy(filename, FileData.FileName);
return TRUE;
} else {
filename[0] = '\0';
return FALSE;
}
}
void AnimationData::SetCaption(void)
{
TApplication *app = PersView->GetApplication();
TWindow *frame = app->GetMainWindow();
if (filename[0]) {
char str[_MAX_PATH];
sprintf(str, "%s - %s", app->GetName(), filename);
frame->SetCaption(str);
} else {
frame->SetCaption(app->GetName());
}
}
int AnimationData::GetLinesNoBackFace(int frame, LineSegment **tmpline, PolyData *polydata)
{
int W = PersView->Attr.W;
int H = PersView->Attr.H;
Motion *mot;
polydata->Init(W,H);
for (mot = motion; mot != NULL; mot = mot->next) {
if (mot->beginframe <= frame && frame <= mot->endframe) {
int inverseflag = FALSE;
if (mot->scale.x < 0) inverseflag = !inverseflag;
if (mot->scale.y < 0) inverseflag = !inverseflag;
if (mot->scale.z < 0) inverseflag = !inverseflag;
int offp;
offp = polydata->points;
for (int i = 0; i < mot->mecha->points; ++i) {
polydata->point[i+offp].x = mot->view_x[i];
polydata->point[i+offp].y = mot->view_y[i];
polydata->point[i+offp].z = mot->view_z[i];
}
polydata->points += mot->mecha->points;
for (i = 0; i < mot->mecha->polys; ++i) {
int *pid = mot->mecha->polypoint + mot->mecha->poly[i];
PolyPoint *p1 = &polydata->point[pid[0]+offp];
PolyPoint *p2 = &polydata->point[pid[1]+offp];
PolyPoint *p3 = &polydata->point[pid[2]+offp];
long m = (long)(p1->x-p2->x)*(long)(p3->y-p2->y) - (long)(p1->y-p2->y)*(long)(p3->x-p2->x);
if (inverseflag && m <= 0) {
polydata->AddPolyInv(mot->mecha->polypoint + mot->mecha->poly[i], offp);
} else if (!inverseflag && m >= 0) {
polydata->AddPoly(mot->mecha->polypoint + mot->mecha->poly[i], offp);
}
}
}
}
polydata->ConvertLines();
int lines = 0;
for (int i = 0; i < polydata->lines; ++i) {
if (polydata->line[i].p1 >= 0
&& polydata->line[i].p2 >= 0) {
PolyPoint &p1 = polydata->point[polydata->line[i].p1];
PolyPoint &p2 = polydata->point[polydata->line[i].p2];
if (p1.z > 0 && p2.z > 0
&& ((p1.x != p2.x) || (p1.y != p2.y))
&& (p1.x >= 0 || p2.x >= 0)
&& (p1.x < W || p2.x < W)
&& (p1.y >= 0 || p2.y >= 0)
&& (p1.y < H || p2.y < H)) {
lines++;
}
}
}
int l = 0;
*tmpline = new LineSegment[lines];
for (i = 0; i < polydata->lines; ++i) {
if (polydata->line[i].p1 >= 0 && polydata->line[i].p2 >= 0) {
PolyPoint &p1 = polydata->point[polydata->line[i].p1];
PolyPoint &p2 = polydata->point[polydata->line[i].p2];
if (p1.z > 0 && p2.z > 0
&& ((p1.x != p2.x) || (p1.y != p2.y))
&& (p1.x >= 0 || p2.x >= 0)
&& (p1.x < W || p2.x < W)
&& (p1.y >= 0 || p2.y >= 0)
&& (p1.y < H || p2.y < H)) {
(*tmpline)[l].x1 = (short)p1.x;
(*tmpline)[l].y1 = (short)p1.y;
(*tmpline)[l].x2 = (short)p2.x;
(*tmpline)[l].y2 = (short)p2.y;
l++;
}
}
}
return l;
}
int AnimationData::GetLines(int frame, LineSegment *tmpline)
{
int l = 0;
int W = PersView->Attr.W;
int H = PersView->Attr.H;
Motion *mot;
for (mot = motion; mot != NULL; mot = mot->next) {
if (mot->beginframe <= frame && frame <= mot->endframe) {
for (int i = 0; i < mot->lines; ++i) {
if (mot->view_z[mot->line_1[i]] > 0 && mot->view_z[mot->line_2[i]] > 0) {
tmpline[l].x1 = (short)mot->view_x[mot->line_1[i]];
tmpline[l].y1 = (short)mot->view_y[mot->line_1[i]];
tmpline[l].x2 = (short)mot->view_x[mot->line_2[i]];
tmpline[l].y2 = (short)mot->view_y[mot->line_2[i]];
if ((tmpline[l].x1 < 0 && tmpline[l].x2 < 0)
|| (tmpline[l].x1 >= W && tmpline[l].x2 >= W)
|| (tmpline[l].y1 < 0 && tmpline[l].y2 < 0)
|| (tmpline[l].y1 >= H && tmpline[l].y2 >= H)) {
} else {
l++;
}
}
}
}
}
return l;
}
void AnimationData::BuildWireFrame(int frame)
{
if (wireframe[frame-BEGIN].line != NULL) {
delete [] wireframe[frame-BEGIN+1].line;
}
int maxlines = 0;
int maxpolys = 0;
int maxpoints = 0;
int maxpolypoints = 0;
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
maxpoints += mot->mecha->points;
maxlines += mot->lines;
maxpolys += mot->mecha->polys;
maxpolypoints += mot->mecha->polypoints;
}
PolyData polydata(maxpoints, maxlines, maxpolys, maxpolypoints);
SelectFrame(frame);
CalcViewAll();
int l = GetLinesNoBackFace(frame, &wireframe[frame-BEGIN].line, &polydata);
wireframe[frame-BEGIN].lines = l;
}
void AnimationData::FreeWireFrame(void)
{
if (wireframe != NULL) {
for (int i = 0; wireframe[i].line!= NULL; ++i) {
delete [] wireframe[i].line;
}
delete [] wireframe;
}
wireframe = NULL;
}
void AnimationData::Resize(int x, int y, int ox, int oy)
{
if (wireframe != NULL) {
for (int i = BEGIN; i <= maxframe; ++i) {
LineSegment *line = wireframe[i-BEGIN].line;
if (line != NULL) {
for (int l = wireframe[i-BEGIN].lines; l > 0; --l) {
line->x1 = (short)((long)line->x1 * (long)x / (long)ox);
line->y1 = (short)((long)line->y1 * (long)y / (long)oy);
line->x2 = (short)((long)line->x2 * (long)x / (long)ox);
line->y2 = (short)((long)line->y2 * (long)y / (long)oy);
line++;
}
}
}
playmode = PmTimer;
}
}