home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
MEDIT.LZH
/
ANIM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-18
|
30KB
|
1,157 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 <stdio.h>
#include <dir.h>
#include "matrix.h"
#include "anim.h"
#include "display.h"
#include "status.h"
#include "pers.h"
#include "winframe.h"
#include "mecha.h"
#include "bezier.h"
#include "motion.h"
#include "files.h"
#include "timebar.h"
#include "drange.h"
#include "syscolor.h"
#include "polyline.h"
#include "bmpopen.h"
#include "log.h"
const double scalemax = (1/8.0);
const double scalemin = (1/256.0);
const double scalerate = 1.414213562373;
AnimationData::AnimationData()
{
Frame = NULL;
FrontView = SideView = TopView = NULL;
PersView = NULL;
Status = NULL;
scrollX = scrollY = scrollZ = NULL;
frameCounter = 0;
for (int i = 0; i < buttons; ++i) {
button[i] = NULL;
}
button_ok = button_cancel = NULL;
statusbar = NULL;
statusbar_time = NULL;
drawflag = SelNone;
HelpState = FALSE;
ViewType[0] = SelX;
ViewType[1] = SelY;
ViewType[2] = SelZ;
hiddenremove = FALSE;
meshflag = TRUE;
meshspacing = 2500;
gridflag = TRUE;
gridspacing = 500;
rotspacing = 10;
scalespacing = (int)(0.1 * scalespacingfactor);
getcwd(filedir, filenamedirlength);
filename[0] = '\0';
strcpy(lastopenmechadir, mechadir.c_str());
drawmode = DrawWire;
motion = select = camera = NULL;
wireframe.line = NULL;
wireframe.lines = 0;
InitMotion();
}
void AnimationData::SetScrollLimit(int flag)
{
int WX = TopView->Attr.W;
int WY = TopView->Attr.H;
int WZ = SideView->Attr.H;
int lx = limitdim/scrollstep - (WX/2) / displayscale / scrollstep;
int ly = limitdim/scrollstep - (WY/2) / displayscale / scrollstep;
int lz = limitdim/scrollstep - (WZ/2) / displayscale / scrollstep;
scrollX->SetRange(-lx, lx);
scrollY->SetRange(-ly, ly);
scrollZ->SetRange(-lz, lz);
scrollX->PageMagnitude = WX / displayscale / scrollstep;
scrollX->LineMagnitude = (scrollX->PageMagnitude+7) / 8;
scrollY->PageMagnitude = WY / displayscale / scrollstep;
scrollY->LineMagnitude = (scrollY->PageMagnitude+7) / 8;
scrollZ->PageMagnitude = WZ / displayscale / scrollstep;
scrollZ->LineMagnitude = (scrollZ->PageMagnitude+7) / 8;
if (flag) {
scrollX->SetPosition(-displayoffset.x / displayscale / scrollstep);
scrollY->SetPosition(displayoffset.y / displayscale / scrollstep);
scrollZ->SetPosition(displayoffset.z / displayscale / scrollstep);
}
if (-displayoffset.x / displayscale / scrollstep < -lx) {
displayoffset.x = lx * displayscale * scrollstep;
scrollX->SetPosition(-lx);
} else if (-displayoffset.x / displayscale / scrollstep> lx) {
displayoffset.x = -lx * displayscale * scrollstep;
scrollX->SetPosition(lx);
}
if (displayoffset.y / displayscale / scrollstep < -ly) {
displayoffset.y = -ly * displayscale * scrollstep;
scrollX->SetPosition(-ly);
} else if (displayoffset.y / displayscale / scrollstep> ly) {
displayoffset.y = ly * displayscale * scrollstep;
scrollX->SetPosition(ly);
}
if (displayoffset.z / displayscale / scrollstep< -lz) {
displayoffset.z = -lz * displayscale * scrollstep;
;scrollX->SetPosition(-lz);
} else if (displayoffset.z / displayscale / scrollstep> lz) {
displayoffset.z = lz * displayscale * scrollstep;
scrollX->SetPosition(lz);
}
if (zoomflag == FALSE) {
scrollX->Show(SW_HIDE); scrollX->Show(SW_SHOW);
scrollY->Show(SW_HIDE); scrollY->Show(SW_SHOW);
scrollZ->Show(SW_HIDE); scrollZ->Show(SW_SHOW);
}
}
void AnimationData::ScaleUp(void)
{
if (displayscale * scalerate <= scalemax) {
displayscale *= scalerate;
displayoffset *= scalerate;
SetScrollLimit();
CalcPointsAll();
Redraw();
}
}
void AnimationData::ScaleDown(void)
{
if (displayscale / scalerate >= scalemin) {
displayscale /= scalerate;
displayoffset *= (1.0/scalerate);
SetScrollLimit();
CalcPointsAll();
Redraw();
}
}
int AnimationData::ScaleUpLimitCheck(void)
{
return displayscale <= scalemax/scalerate;
}
int AnimationData::ScaleDownLimitCheck(void)
{
return displayscale >= scalemin*scalerate;
}
void AnimationData::DeleteMotion(Motion *m)
{
if (m == NULL || m == camera || m == camera->target) {
return;
}
for (Motion *mt = motion; mt != NULL; mt = mt->next) {
if (mt->next == m) {
mt->next = m->next;
break;
}
}
if (motion == m) {
motion = m->next;
}
SelectMotion(NULL);
Redraw();
delete m;
editflag++;
}
void AnimationData::CopyMotion(Motion *m)
{
if (m == NULL || m == camera || m == camera->target) {
return;
}
Motion *nm = new Motion(*m);
nm->next = motion;
motion = nm;
Vector wh(TopView->Attr.W, TopView->Attr.H, 0);
wh *= (1.0/displayscale/8.0);
if (nm->motiondata == NULL) {
nm->position += wh;
} else {
for (int i = 0; i < nm->motiondata->bezier->points*3+2; ++i) {
nm->motiondata->bezier->point[i] += wh;
}
}
nm->GetPosition(selectframe);
CalcPoints(nm);
SelectMotion(nm);
Redraw();
editflag++;
}
void AnimationData::AddMotion(Mechanic *m, Bezier *b)
{
int begin = BEGIN, end = maxframe;
Motion *mot;
if (b->points == 0) {
mot = new Motion(m, begin, end);
mot->position = b->point[0];
} else {
mot = new Motion(m, begin, end, b);
}
mot->next = motion;
motion = mot;
mot->GetPosition(selectframe);
CalcPoints(mot);
SelectMotion(mot);
editflag++;
}
int AnimationData::GetMechaName(char *filename)
{
#if 0
char str[filenamedirlength];
strcpy(str, mechadir.c_str());
str[strlen(str)-1] = '\0';
#endif
OpModeDefault();
#if 0
TOpenSaveDialog::TData FileData(
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
"メカデザインファイル(*.fsc)|*.fsc|"
"すべてのファイル(*.*)|*.*|",
0, lastopenmechadir, "fsc");
TFileOpenDialog OpenDlg(Frame, FileData);
if (OpenDlg.Execute() == IDOK) {
strcpy(filename, FileData.FileName);
return TRUE;
} else {
filename[0] = '\0';
return FALSE;
}
#else
if (FileOpenDialogWithBMP(Frame, filename,
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
"メカデザインファイル(*.fsc)|*.fsc|"
"すべてのファイル(*.*)|*.*|",
0, lastopenmechadir, "fsc") == IDOK) {
if (filename[0] && filename[1] == ':' && filename[2] == '\\') {
char *p;
strcpy(lastopenmechadir, filename);
if ((p = strrchr(lastopenmechadir, '\\')) != NULL) {
*p = '\0';
}
}
return TRUE;
} else {
filename[0] = '\0';
return FALSE;
}
#endif
}
static inline void engrid(Vector& v, int grid)
{
if (v.x > 0) {
v.x = (double)( ((long)( v.x) + grid/2) / grid) * (double) grid;
} else {
v.x = -(double)( ((long)(-v.x) + grid/2) / grid) * (double) grid;
}
if (v.y > 0) {
v.y = (double)( ((long)( v.y) + grid/2) / grid) * (double) grid;
} else {
v.y = -(double)( ((long)(-v.y) + grid/2) / grid) * (double) grid;
}
if (v.z > 0) {
v.z = (double)( ((long)( v.z) + grid/2) / grid) * (double) grid;
} else {
v.z = -(double)( ((long)(-v.z) + grid/2) / grid) * (double) grid;
}
}
void AnimationData::AddMechanicFix(char *filename)
{
OpModeDefault();
Mechanic *mec;
char str[_MAX_PATH];
if ((mec = MechaFile::OpenMechanic(filename)) == NULL) {
strcpy(str, mechadir.c_str());
strcat(str, filename);
if ((mec = MechaFile::OpenMechanic(str)) == NULL) {
Frame->MessageBox("メカを読み込めませんでした。", Frame->GetApplication()->GetName(), MB_OK);
return;
}
}
Bezier *bezier = new Bezier();
Vector v((-1.0/displayscale) * displayoffset);
if (gridflag) {
engrid(v, gridspacing);
}
bezier->AddPoint(v, v);
AddMotion(mec, bezier);
Redraw();
}
void AnimationData::AddMechanicMove(char *filename)
{
OpModeDefault();
Mechanic *mec;
char str[_MAX_PATH];
if ((mec = MechaFile::OpenMechanic(filename)) == NULL) {
strcpy(str, mechadir.c_str());
strcat(str, filename);
if ((mec = MechaFile::OpenMechanic(str)) == NULL) {
Frame->MessageBox("メカを読み込めませんでした。", Frame->GetApplication()->GetName(), MB_OK);
return;
}
}
Bezier *bezier = new Bezier();
Vector v0((-1.0/displayscale) * displayoffset);
Vector v1(1.0/displayscale * TopView->Attr.W / 3.0, 0.0, 0.0);
Vector va(v0-v1), vb(v0+v1);
if (gridflag) {
engrid(va, gridspacing);
engrid(vb, gridspacing);
}
bezier->AddPoint(va, va+(2.0/3.0)*v1);
bezier->AddPoint(vb, vb+(2.0/3.0)*v1);
AddMotion(mec, bezier);
Redraw();
}
void AnimationData::ExchangeMechanic(char *filename)
{
if (select == NULL || select == camera || select == camera->target) {
return;
}
OpModeDefault();
Mechanic *mec;
char str[_MAX_PATH];
if ((mec = MechaFile::OpenMechanic(filename)) == NULL) {
strcpy(str, mechadir.c_str());
strcat(str, filename);
if ((mec = MechaFile::OpenMechanic(str)) == NULL) {
Frame->MessageBox("メカを読み込めませんでした。", Frame->GetApplication()->GetName(), MB_OK);
return;
}
}
select->SetMech(mec);
CalcPoints(select);
editflag++;
Redraw();
}
void AnimationData::Redraw(SelectType t, int flag)
{
if (flag) {
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
mot->GetPosition(selectframe);
CalcPoints(mot);
}
camera->GetPosition(selectframe);
CalcPoints(camera);
BuildWireFrame(selectframe);
} else {
if (wireframe.line == NULL) {
BuildWireFrame(selectframe);
}
}
if (t & SelZ) TopView->Redraw();
if (t & SelY) SideView->Redraw();
if (t & SelX) FrontView->Redraw();
if (t & SelPers) PersView->Redraw();
if (t & SelStat) Status->Redraw();
if (opstat == OpLight) {
if (t & SelZ) TopView->ShowLight(org_point, TRUE);
if (t & SelY) SideView->ShowLight(org_point, TRUE);
if (t & SelX) FrontView->ShowLight(org_point, TRUE);
if (t & SelPers)PersView->ShowLight(org_point, TRUE);
return;
} else if (opstat == OpPlay) {
return;
} else if (drawmode == DrawPlaneObject) {
if (select == camera || select == camera->target) {
if ((camera->motiondata == NULL && camera->beginframe <= selectframe && selectframe <= camera->endframe)
|| selectframe == camera->beginframe
|| selectframe == camera->endframe) {
Matrix m = GetCubeMatrix(camera);
if (t & SelZ) TopView->ShowCamera(m, TRUE);
if (t & SelY) SideView->ShowCamera(m, TRUE);
if (t & SelX) FrontView->ShowCamera(m, TRUE);
}
}
return;
}
if (select == camera || select == camera->target) {
if ((camera->motiondata == NULL && camera->beginframe <= selectframe && selectframe <= camera->endframe)
|| selectframe == camera->beginframe
|| selectframe == camera->endframe) {
Matrix m = GetCubeMatrix(camera);
if (t & SelZ) TopView->ShowCamera(m, TRUE);
if (t & SelY) SideView->ShowCamera(m, TRUE);
if (t & SelX) FrontView->ShowCamera(m, TRUE);
}
} else if (select != NULL) {
if ((select->motiondata == NULL && select->beginframe <= selectframe && selectframe <= select->endframe)
|| selectframe == select->beginframe
|| selectframe == select->endframe) {
SelectType nt[3];
Matrix m = GetCubeMatrix(select);
SelectAxis(nt, m);
if (t & SelZ) TopView->ShowCube(m, TRUE, nt[0]);
if (t & SelY) SideView->ShowCube(m, TRUE, nt[1]);
if (t & SelX) FrontView->ShowCube(m, TRUE, nt[2]);
}
}
}
void AnimationData::DrawBezier(Bezier *bezier)
{
FrontView->DrawBezier(bezier);
SideView->DrawBezier(bezier);
TopView->DrawBezier(bezier);
}
void AnimationData::ShowCube(Matrix& omat, Matrix& nmat)
{
if (select == camera || select == camera->target) {
TopView->ShowCamera(omat, FALSE);
TopView->ShowCamera(nmat, FALSE);
SideView->ShowCamera(omat, FALSE);
SideView->ShowCamera(nmat, FALSE);
FrontView->ShowCamera(omat, FALSE);
FrontView->ShowCamera(nmat, FALSE);
} else {
TopView->ShowCube(omat, FALSE, SelNone);
TopView->ShowCube(nmat, FALSE, SelNone);
SideView->ShowCube(omat, FALSE, SelNone);
SideView->ShowCube(nmat, FALSE, SelNone);
FrontView->ShowCube(omat, FALSE, SelNone);
FrontView->ShowCube(nmat, FALSE, SelNone);
}
}
void AnimationData::ShowLight(Vector& ovec, Vector& nvec)
{
TopView->ShowLight(ovec, FALSE);
TopView->ShowLight(nvec, FALSE);
SideView->ShowLight(ovec, FALSE);
SideView->ShowLight(nvec, FALSE);
FrontView->ShowLight(ovec, FALSE);
FrontView->ShowLight(nvec, FALSE);
PersView->ShowLight(ovec, FALSE);
PersView->ShowLight(nvec, FALSE);
}
Matrix AnimationData::GetMatrix(Motion *mot, int frame)
{
return Matrix::m_move(displayoffset).scale(displayscale) * mot->GetMatrix(frame);
}
Matrix AnimationData::GetMatrix(Motion *mot)
{
return Matrix::m_move(displayoffset).scale(displayscale) * mot->GetMatrix(selectframe);
}
void AnimationData::GetCubeMatrix(Motion *mot, Matrix& move, Matrix& rot, Matrix& scal)
{
double maxx, maxy, maxz;
const int minimumsize = markersize * 8;
maxx = maxy = maxz = 1;
if (mot == camera) {
maxy = tan(camera->angle/2.0);
maxz = maxy * 3 / 4;
} else {
Mechanic *mecha = mot->mecha;
if (mecha != NULL) {
if (mecha->maxx > -mecha->minx) {
maxx = mecha->maxx;
} else {
maxx = -mecha->minx;
}
if (mecha->maxy > -mecha->miny) {
maxy = mecha->maxy;
} else {
maxy = -mecha->miny;
}
if (mecha->maxz > -mecha->minz) {
maxz = mecha->maxz;
} else {
maxz = -mecha->minz;
}
}
}
mot->GetMatrix(move, rot, scal, selectframe);
move = Matrix::m_move(displayoffset).scale(displayscale) * move;
scal = scal.scale(maxx, maxy, maxz);
if (mot != camera) {
if (scal.v[0].x > 0.0) {
if (scal.v[0].x < minimumsize/displayscale) scal.v[0].x = minimumsize/displayscale;
} else {
if (scal.v[0].x > -minimumsize/displayscale) scal.v[0].x = -minimumsize/displayscale;
}
if (scal.v[1].y > 0.0) {
if (scal.v[1].y < minimumsize/displayscale) scal.v[1].y = minimumsize/displayscale;
} else {
if (scal.v[1].y > -minimumsize/displayscale) scal.v[1].y = -minimumsize/displayscale;
}
if (scal.v[2].z > 0.0) {
if (scal.v[2].z < minimumsize/displayscale) scal.v[2].z = minimumsize/displayscale;
} else {
if (scal.v[2].z > -minimumsize/displayscale) scal.v[2].z = -minimumsize/displayscale;
}
}
}
Matrix AnimationData::GetCubeMatrix(Motion *mot)
{
Matrix m,r,s;
GetCubeMatrix(mot, m, r, s);
return m * r * s;
}
void AnimationData::CalcViewMatrix(void)
{
int fx, fy;
fx = PersView->Attr.W;
fy = PersView->Attr.H;
Matrix cmat;
// cmat = camera->GetMatrix(selectframe).inv();
cmat = (Matrix::m_move(camera->position).rot(camera->rotation)).inv();
Matrix tmpmat(0);
tmpmat.v[0].z = tmpmat.v[1].x = tmpmat.v[2].y = 1.0;
cmat = tmpmat * cmat;
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;
viewmat = cmat;
}
void AnimationData::CalcView(Motion *mot)
{
// if (drawmode != DrawWire) return;
if (drawmode == DrawWire || (drawmode == DrawPlane && mot == select)) {
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
} else {
mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
}
}
void AnimationData::CalcViewAll(void)
{
// if (drawmode != DrawWire) return;
CalcViewMatrix();
if (drawmode == DrawWire) {
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
}
} else if (drawmode == DrawPlane) {
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
if (mot == select) {
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
} else {
mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
}
}
} else {
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
}
}
}
void AnimationData::CalcPoints(Motion *mot)
{
// if (mot != camera && mot != select) return;
if (drawmode == DrawWire || (drawmode == DrawPlane && mot == select)) {
mot->CalcPoints(GetMatrix(mot));
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
} else {
mot->CalcPointsBox(GetMatrix(mot));
mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
}
if (wireframe.line != NULL) {
delete[] wireframe.line;
wireframe.lines = 0;
wireframe.line = NULL;
}
}
void AnimationData::CalcPointsAll(void)
{
camera->CalcPoints(GetMatrix(camera));
CalcViewMatrix();
// if (drawmode != DrawWire) return;
if (drawmode == DrawWire) {
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
mot->CalcPoints(GetMatrix(mot));
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
}
BuildWireFrame(selectframe);
} else if (drawmode == DrawPlane) {
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
if (mot == select) {
mot->CalcPoints(GetMatrix(mot));
mot->CalcView(viewmat * mot->GetMatrix(selectframe));
} else {
mot->CalcPointsBox(GetMatrix(mot));
mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
}
}
} else {
for (Motion *mot = motion; mot != NULL; mot = mot->next) {
mot->CalcPointsBox(GetMatrix(mot));
mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
}
}
}
void AnimationData::SetDrawMode(DrawMode mode)
{
if (drawmode != mode) {
drawmode = mode;
CalcPointsAll();
Redraw();
}
}
void AnimationData::ExpandFrame(int frame)
{
if (frame <= BEGIN || frame == maxframe) {
return;
}
for (Motion *m = motion;m != NULL; m = m->next) {
int b = (double)(m->beginframe - BEGIN) * (double)(frame-BEGIN) / (double)(maxframe-BEGIN) + 0.5 + BEGIN;
int f = (double)(m->endframe - BEGIN) * (double)(frame-BEGIN) / (double)(maxframe-BEGIN) + 0.5 + BEGIN;
if (b > frame) b = frame;
if (f > frame) f = frame;
if (m->motiondata != NULL && b == f) {
if (b > BEGIN) {
b = f-1;
} else {
f = b+1;
}
}
m->Zoom(b,f);
}
camera->Zoom(BEGIN, frame);
camera->target->Zoom(BEGIN, frame);
int ns = (double)(selectframe- BEGIN) * (double)(frame-BEGIN) / (double)(maxframe-BEGIN) + 0.5 + BEGIN;
maxframe = frame;
frameCounter->SetRange(1, maxframe);
SelectFrame(ns);
Redraw();
editflag++;
}
void AnimationData::SelectFrame(int frame)
{
if (frame < BEGIN || frame > maxframe) {
return;
}
selectframe = frame;
frameCounter->SetPosition(selectframe);
CalcPointsAll();
char str[32];
sprintf(str, "時刻: %d", selectframe);
statusbar_time->SetText(str);
Frame->GetApplication()->PumpWaitingMessages();
}
void AnimationData::SelectMotion(Motion *m)
{
if (select != m) {
Motion *os = select;
select = m;
if (drawmode == DrawPlane) {
if (os != NULL) CalcPoints(os);
if (m != NULL) CalcPoints(m);
}
}
}
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);
}
}
static void merge(char *all, char *dir, char *name)
{
if (dir[0] == '\0') {
strcpy(all, name);
} else if (dir[1] == ':' && dir[2] == '\0') {
strcpy(all, dir);
strcat(all, name);
} else {
strcpy(all, dir);
strcat(all, "\\");
strcat(all, name);
}
}
void AnimationData::WriteFile(char *fname)
{
char str[filenamedirlength];
if (fname != NULL) {
split(filedir, filename, fname);
SetCaption();
}
merge(str, filedir, filename);
if (Motion::FileWrite(motion, camera, light, str) == FALSE && errormessage[0]) {
PersView->GetApplication()->GetMainWindow()->MessageBox(errormessage);
}
editflag = 0;
}
void AnimationData::ReadFile(char *fname)
{
OpModeDefault();
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;
SelectMotion(NULL);
motion = nm;
camera = nc;
maxframe = max;
light = v;
SelectFrame(BEGIN);
opstat = OpDefault;
frameCounter->SetRange(BEGIN, maxframe);
CalcPointsAll();
Redraw();
editflag = 0;
SetCaption();
}
}
void AnimationData::InitMotion(void)
{
Motion *next, *m;
for (m = motion; m != NULL; m = next) {
next = m->next;
delete m;
}
filename[0] = '\0';
backup_displayscale = displayscale = 1.0 / 64.0;
backup_displayoffset = displayoffset = Vector(0.0, 0.0, 0.0);
zoomflag = FALSE;
opstat = OpDefault;
light = Vector(-3.0, -2.0, -4.0);
light *= (1.0/light.length());
maxframe = 100;
motion = select = NULL;
selectstatus = SelNone;
selectframe = 1;
Motion *target = new Motion(NULL, BEGIN, maxframe);
camera = new CameraMotion(target, maxframe);
camera->position = Vector(8000,6000,6000);
camera->GetPosition(BEGIN);
viewmat = Matrix(0);
drag_mat = drag_scale = drag_rot = drag_move = Matrix(1);
// if (scrollX) scrollX->Show(SW_SHOW);
// if (scrollY) scrollY->Show(SW_SHOW);
// if (scrollZ) scrollZ->Show(SW_SHOW);
editflag = 0;
}
void AnimationData::NewFile(void)
{
OpModeDefault();
InitMotion();
frameCounter->SetPosition(selectframe);
frameCounter->SetRange(BEGIN, maxframe);
SetCaption();
SelectMotion(NULL);
SelectFrame(BEGIN);
Redraw();
// Redraw(SelAll, TRUE);
editflag = 0;
}
void AnimationData::SetCaption(void)
{
TApplication *app = TopView->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());
}
}
void AnimationData::OpModeDefault(void)
{
switch (opstat) {
case OpDefault:
break;
case OpLight:
#if 0
TopView->ShowLight(org_point, FALSE);
SideView->ShowLight(org_point, FALSE);
FrontView->ShowLight(org_point, FALSE);
#else
opstat = OpDefault;
Redraw();
#endif
if (org_point.length() > minimumdouble) {
light = (1.0 / org_point.length()) * org_point;
editflag++;
}
break;
case OpSelZoom:
zoomflag = FALSE;
// scrollX->Show(SW_SHOW);
// scrollY->Show(SW_SHOW);
// scrollZ->Show(SW_SHOW);
break;
case OpPlay:
Frame->KillTimer(OpPlay);
CalcPointsAll();
opstat = OpDefault;
Redraw();
break;
}
opstat = OpDefault;
Status->Redraw();
}
void AnimationData::OpModeLight(void)
{
OpModeDefault();
SelectMotion(NULL);
int size = TopView->Attr.W;
if (size > TopView->Attr.H) {
size = TopView->Attr.H;
}
if (size > FrontView->Attr.H) {
size = FrontView->Attr.H;
}
org_point = (size / 3) * light;
opstat = OpLight;
Redraw();
}
void AnimationData::OpModeZoom(void)
{
if (zoomflag != FALSE) {
displayoffset = backup_displayoffset;
displayscale = backup_displayscale;
SetScrollLimit(TRUE);
// scrollX->Show(SW_SHOW);
// scrollY->Show(SW_SHOW);
// scrollZ->Show(SW_SHOW);
Redraw(SelXYZ, TRUE);
zoomflag = FALSE;
} else {
backup_displayoffset = displayoffset;
backup_displayscale = displayscale;
// scrollX->Show(SW_HIDE);
// scrollY->Show(SW_HIDE);
// scrollZ->Show(SW_HIDE);
zoomflag = TRUE;
opstat = OpSelZoom;
}
Status->Redraw();
}
void AnimationData::OpModePlay(void)
{
OpModeDefault();
Frame->SetTimer(OpPlay, 33);
// DrawMode oldmode = drawmode;
// drawmode = DrawPlaneObject;
// CalcPointsAll();
// drawmode = oldmode;
opstat = OpPlay;
Status->Redraw();
}
void AnimationData::SelectAxis(SelectType t[3], Matrix& m)
{
Vector vx = m.v[0].unit() ;
Vector vy = m.v[1].unit() ;
Vector vz = m.v[2].unit() ;
if (vx.x < 0) vx.x = -vx.x;
if (vx.y < 0) vx.y = -vx.y;
if (vx.z < 0) vx.z = -vx.z;
if (vy.x < 0) vy.x = -vy.x;
if (vy.y < 0) vy.y = -vy.y;
if (vy.z < 0) vy.z = -vy.z;
if (vz.x < 0) vz.x = -vz.x;
if (vz.y < 0) vz.y = -vz.y;
if (vz.z < 0) vz.z = -vz.z;
if (vx.z > vy.z && vx.z > vz.z) { // Z成分のもっとも少ないベクトルを選択
t[0] = SelX;
if (vy.y > vz.y) { // Y成分のもっとも少ないベクトルを選択
t[1] = SelY;
t[2] = SelZ;
} else {
t[1] = SelZ;
t[2] = SelY;
}
} else if (vy.z > vz.z) {
t[0] = SelY;
if (vx.y > vz.y) {
t[1] = SelX;
t[2] = SelZ;
} else {
t[1] = SelZ;
t[2] = SelX;
}
} else {
t[0] = SelZ;
if (vx.y > vy.y) {
t[1] = SelX;
t[2] = SelY;
} else {
t[1] = SelY;
t[2] = SelX;
}
}
}
TStatusBar *AnimationData::InitStatusBar(void)
{
statusbar = new TStatusBar(0, TGadget::Recessed);
// statusbar_mode = new TTextGadget(0, TGadget::Recessed, TTextGadget::Left, 10);
// statusbar->Insert(*statusbar_mode);
statusbar_time = new TTextGadget(0, TGadget::Recessed, TTextGadget::Left, 8);
statusbar->Insert(*statusbar_time);
return statusbar;
}
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, mot);
} else if (!inverseflag && m >= 0) {
polydata->AddPoly(mot->mecha->polypoint + mot->mecha->poly[i], offp, mot);
}
}
}
}
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;
(*tmpline)[l].id = polydata->line[i].id;
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.line != NULL) {
delete[] wireframe.line;
wireframe.line = NULL;
}
if (!hiddenremove) {
return;
}
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.line, &polydata);
wireframe.lines = l;
}
void AnimationData::WinHelp(UINT fuCommand,DWORD dwData)
{
char helpfile[256];
strcpy(helpfile, pathdir.c_str());
strcat(helpfile, "MEDIT.HLP");
HelpState = TopView->GetApplication()->GetMainWindow()->WinHelp(helpfile, fuCommand, dwData);
}