home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
MEDIT.LZH
/
PERS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-06
|
14KB
|
515 lines
/* Project medit
Project Team DoGA
Copyright (c) 1995. All Rights Reserved.
サブシステム: medit.apx Application
ファイル: pers.cpp
作成者: Taka2
概要
====
TWinPers (TWindow) のインプリメンテーション用のソースファイル
*/
#include <owl\owlpch.h>
#pragma hdrstop
#include <stdio.h>
#include "syscolor.h"
#include "pers.h"
#include "anim.h"
#include "mecha.h"
#include "display.h"
//
// このアプリケーションで処理するすべてのメッセージ/コマンドの
// 応答テーブルを作成する
//
DEFINE_RESPONSE_TABLE1(TWinPers, TWindow)
//{{TWinPersRSP_TBL_BEGIN}}
EV_WM_LBUTTONDOWN,
//{{TWinPersRSP_TBL_END}}
END_RESPONSE_TABLE;
//{{TWinPers Implementation}}
TWinPers::TWinPers (TWindow* parent, AnimationData *dat, int x, int y, int w, int h):
TWindow(parent, 0, 0)
{
// INSERT>> コンストラクタ用のコードはここに
SetBkgndColor(TColor::LtGray);
Attr.X = x;
Attr.Y = y;
Attr.W = w;
Attr.H = h;
anim = dat;
}
TWinPers::~TWinPers ()
{
Destroy();
// INSERT>> デストラクタ用のコードはここに
}
void TWinPers::Paint (TDC& dc, BOOL erase, TRect& rect)
{
TWindow::Paint(dc, erase, rect);
// INSERT>> 追加のコードはここに
// anim->Redraw(SelPers, FALSE);
Redraw();
}
void TWinPers::RedrawMain(TDC& dc)
{
dc.SelectObject(TPen(cBackGround));
dc.SelectObject(TBrush(cBackGround));
dc.Rectangle(dc.GetClipBox());
if (anim->opstat != OpPlay) {
ShowMesh(dc);
}
if (anim->hiddenremove && anim->drawmode == DrawWire && anim->opstat != OpPlay) {
if (anim->wireframe.line == NULL) {
anim->BuildWireFrame(anim->selectframe);
}
LineSegment *l = anim->wireframe.line;
if (anim->select != NULL && anim->select != anim->camera) {
dc.SelectObject(TPen(cWireNoSelect));
int sel = FALSE;
for (int i = anim->wireframe.lines; i > 0; --i) {
if (!sel && l->id == anim->select) {
dc.SelectObject(TPen(cWireSelect));
sel = TRUE;
} else if (sel && l->id != anim->select) {
dc.SelectObject(TPen(cWireNoSelect));
sel = FALSE;
}
dc.MoveTo(l->x1, l->y1);
dc.LineTo(l->x2, l->y2);
l++;
}
} else {
dc.SelectObject(TPen(cWireNormal));
for (int i = anim->wireframe.lines; i > 0; --i) {
dc.MoveTo(l->x1, l->y1);
dc.LineTo(l->x2, l->y2);
l++;
}
}
#if 0
if (anim->select != NULL && anim->select != anim->camera) {
dc.SelectObject(TPen(cWireNoSelect));
} else {
dc.SelectObject(TPen(cWireNormal));
}
for (int i = anim->wireframe.lines; i > 0; --i) {
dc.MoveTo(l->x1, l->y1);
dc.LineTo(l->x2, l->y2);
l++;
}
if (anim->select != NULL && anim->select != anim->camera && anim->select != anim->camera->target) {
ShowMotion(dc, anim->select);
}
#endif
} else {
for (Motion *mot = anim->motion; mot != NULL; mot = mot->next) {
if (mot != anim->select) {
ShowMotion(dc, mot);
}
}
if (anim->select != NULL && anim->select != anim->camera && anim->select != anim->camera->target) {
ShowMotion(dc, anim->select);
}
}
}
void TWinPers::Redraw(void)
{
#if 0
TClientDC dc(*this);
if (anim->opstat != OpPlay) {
RedrawMain(dc);
} else {
TMemoryDC mdc(dc);
TBitmap bitmap(dc, Attr.W, Attr.H);
mdc.SelectObject(bitmap);
RedrawMain(mdc);
dc.BitBlt(0,0,Attr.W, Attr.H, mdc, 0, 0, SRCCOPY);
}
#else
TClientDC dc(*this);
TMemoryDC mdc(dc);
TBitmap bitmap(dc, Attr.W, Attr.H);
mdc.SelectObject(bitmap);
RedrawMain(mdc);
dc.BitBlt(0,0,Attr.W, Attr.H, mdc, 0, 0, SRCCOPY);
#endif
}
void TWinPers::ShowMotion(TDC& dc, Motion *mot)
{
if (anim->selectframe < mot->beginframe || mot->endframe < anim->selectframe) {
return;
}
if (mot == anim->select) {
dc.SelectObject(TPen(cWireSelect));
} else if (mot == anim->camera) {
dc.SelectObject(TPen(cWireCamera));
} else if ((anim->select != NULL && anim->select != anim->camera)
|| anim->opstat == OpLight) {
dc.SelectObject(TPen(cWireNoSelect));
} else {
dc.SelectObject(TPen(cWireNormal));
}
if (mot->boxflag == FALSE) {
int begin, end = -1;
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) {
end = -1;
} else {
if ((begin = mot->line_1[i]) != end) {
dc.MoveTo(mot->view_x[begin], mot->view_y[begin]);
}
end = mot->line_2[i];
dc.LineTo(mot->view_x[end], mot->view_y[end]);
}
}
} else if (mot->motiondata == NULL) {
if (mot->view_z[0] > 0) {
dc.MoveTo(mot->view_x[0], mot->view_y[0]);
dc.LineTo(mot->view_x[1], mot->view_y[1]);
dc.LineTo(mot->view_x[2], mot->view_y[2]);
dc.LineTo(mot->view_x[3], mot->view_y[3]);
dc.LineTo(mot->view_x[0], mot->view_y[0]);
dc.LineTo(mot->view_x[4], mot->view_y[4]);
dc.LineTo(mot->view_x[5], mot->view_y[5]);
dc.LineTo(mot->view_x[6], mot->view_y[6]);
dc.LineTo(mot->view_x[7], mot->view_y[7]);
dc.LineTo(mot->view_x[4], mot->view_y[4]);
dc.MoveTo(mot->view_x[1], mot->view_y[1]);
dc.LineTo(mot->view_x[5], mot->view_y[5]);
dc.MoveTo(mot->view_x[2], mot->view_y[2]);
dc.LineTo(mot->view_x[6], mot->view_y[6]);
dc.MoveTo(mot->view_x[3], mot->view_y[3]);
dc.LineTo(mot->view_x[7], mot->view_y[7]);
}
} else {
if (mot->view_z[0] > 0) {
dc.MoveTo(mot->view_x[0], mot->view_y[0]);
dc.LineTo(mot->view_x[1], mot->view_y[1]);
dc.LineTo(mot->view_x[2], mot->view_y[2]);
dc.LineTo(mot->view_x[0], mot->view_y[0]);
dc.LineTo(mot->view_x[3], mot->view_y[3]);
dc.LineTo(mot->view_x[4], mot->view_y[4]);
}
}
#if 0
if (anim->drawmode == DrawWire) {
int begin, end = -1;
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) {
end = -1;
} else {
if ((begin = mot->line_1[i]) != end) {
dc.MoveTo(mot->view_x[begin], mot->view_y[begin]);
}
end = mot->line_2[i];
dc.LineTo(mot->view_x[end], mot->view_y[end]);
}
}
} else if (anim->drawmode == DrawPlane || anim->drawmode == DrawPlaneObject) {
double maxx = 0, maxy = 0, maxz = 0;
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;
}
}
Matrix cm = anim->viewmat * mot->GetMatrix(anim->selectframe);
Vector p[8];
if (mot->motiondata == NULL) {
p[0] = cm * Vector( maxx, maxy, maxz);
p[1] = cm * Vector( maxx, maxy,-maxz);
p[2] = cm * Vector( maxx,-maxy,-maxz);
p[3] = cm * Vector( maxx,-maxy, maxz);
p[4] = cm * Vector(-maxx, maxy, maxz);
p[5] = cm * Vector(-maxx, maxy,-maxz);
p[6] = cm * Vector(-maxx,-maxy,-maxz);
p[7] = cm * Vector(-maxx,-maxy, maxz);
int vx[8], vy[8], drawflag = TRUE;
for (int i = 0; i < 8; ++i) {
if (p[i].z <= 1.0) {
drawflag = FALSE;
break;
}
vx[i] = int(p[i].x / p[i].z);
vy[i] = int(p[i].y / p[i].z);
}
if (drawflag != FALSE) {
dc.MoveTo(vx[0], vy[0]);
dc.LineTo(vx[1], vy[1]);
dc.LineTo(vx[2], vy[2]);
dc.LineTo(vx[3], vy[3]);
dc.LineTo(vx[0], vy[0]);
dc.LineTo(vx[4], vy[4]);
dc.LineTo(vx[5], vy[5]);
dc.LineTo(vx[6], vy[6]);
dc.LineTo(vx[7], vy[7]);
dc.LineTo(vx[4], vy[4]);
dc.MoveTo(vx[1], vy[1]);
dc.LineTo(vx[5], vy[5]);
dc.MoveTo(vx[2], vy[2]);
dc.LineTo(vx[6], vy[6]);
dc.MoveTo(vx[3], vy[3]);
dc.LineTo(vx[7], vy[7]);
}
} else {
p[0] = cm * Vector( maxx, 0.0, 0.0);
p[1] = cm * Vector(-maxx, maxy, 0.0);
p[2] = cm * Vector(-maxx,-maxy, 0.0);
p[3] = cm * Vector(-maxx, 0.0, maxz);
p[4] = cm * Vector(-maxx, 0.0, 0.0);
int vx[5], vy[5], drawflag = TRUE;
for (int i = 0; i < 5; ++i) {
if (p[i].z <= 1.0) {
drawflag = FALSE;
break;
}
vx[i] = int(p[i].x / p[i].z);
vy[i] = int(p[i].y / p[i].z);
}
if (drawflag != FALSE) {
dc.MoveTo(vx[0], vy[0]);
dc.LineTo(vx[1], vy[1]);
dc.LineTo(vx[2], vy[2]);
dc.LineTo(vx[0], vy[0]);
dc.LineTo(vx[3], vy[3]);
dc.LineTo(vx[4], vy[4]);
}
}
}
#endif
}
static void DrawLine(TDC& dc, Vector& v0, Vector& v1)
{
if (v0.z <= 1.5 && v1.z <= 1.5) {
return;
}
if (v0.z <= 1.0) {
double rate = (1.0 - v1.z) / (v0.z - v1.z);
v0 = Vector(v1.x + (v0.x - v1.x) * rate,
v1.y + (v0.y - v1.y) * rate,
1.0);
} else if (v1.z <= 1.0) {
double rate = (1.0 - v0.z) / (v1.z - v0.z);
v1 = Vector(v0.x + (v1.x - v0.x) * rate,
v0.y + (v1.y - v0.y) * rate,
1.0);
}
double x0 = v0.x/v0.z, y0 = v0.y/v0.z;
double x1 = v1.x/v1.z, y1 = v1.y/v1.z;
if ((x0 < 0 && x1 < 0) || (x0 > 2048 && x1 > 2048)) {
return;
}
if (x0 < 0) {
y0 = y1 + (y0-y1) * ( 0-x1) / (x0-x1);
x0 = 0;
} else if (x0 > 2048) {
y0 = y1 + (y0-y1) * (2048-x1) / (x0-x1);
x0 = 2048;
}
if (x1 < 0) {
y1 = y0 + (y1-y0) * ( 0-x0) / (x1-x0);
x1 = 0;
} else if (x1 > 2048) {
y1 = y0 + (y1-y0) * (2048-x0) / (x1-x0);
x1 = 2048;
}
if ((y0 < 0 && y1 < 0) || (y0 > 2048 && y1 > 2048)) {
return;
}
if (y0 < 0) {
x0 = x1 + (x0-x1) * ( 0-y1) / (y0-y1);
y0 = 0;
} else if (y0 > 2048) {
x0 = x1 + (x0-x1) * (2048-y1) / (y0-y1);
y0 = 2048;
}
if (y1 < 0) {
x1 = x0 + (x1-x0) * ( 0-y0) / (y1-y0);
y1 = 0;
} else if (y1 > 2048) {
x1 = x0 + (x1-x0) * (2048-y0) / (y1-y0);
y1 = 2048;
}
dc.MoveTo(x0,y0);
dc.LineTo(x1,y1);
}
void TWinPers::ShowMesh(TDC& dc)
{
if (anim->meshflag == FALSE) {
return;
}
Vector& v = anim->displayoffset;
double bx = - (1.0 / anim->displayscale) * (v.x + anim->TopView->Attr.W / 2);
double by = - (1.0 / anim->displayscale) * (v.y + anim->TopView->Attr.H / 2);
// int cx = (1.0 / anim->displayscale) * anim->TopView->Attr.W / anim->meshspacing+1;
// int cy = (1.0 / anim->displayscale) * anim->TopView->Attr.H / anim->meshspacing+1;
dc.SetROP2(R2_COPYPEN);
dc.SelectObject(TPen(cGrid));
dc.SelectObject(TPen(cGrid,1,PS_DOT));
dc.SetBkMode(TRANSPARENT);
int i;
double xb = bx, yb = by;
double xe = - (1.0 / anim->displayscale) * (v.x - anim->TopView->Attr.W / 2);
double ye = - (1.0 / anim->displayscale) * (v.y - anim->TopView->Attr.H / 2);
if (bx < 0) {
bx = -((long)(-bx/anim->meshspacing) ) * anim->meshspacing;
} else {
bx = ((long)( bx/anim->meshspacing)+1) * anim->meshspacing;
}
if (by < 0) {
by = -((long)(-by/anim->meshspacing)) * anim->meshspacing;
} else {
by = ((long)( by/anim->meshspacing)+1) * anim->meshspacing;
}
int cx = (xe - bx) / anim->meshspacing + 1;
int cy = (ye - by) / anim->meshspacing + 1;
// double xb = bx, xe = bx + (double)(cx) * anim->meshspacing;
// double yb = by, ye = by + (double)(cy) * anim->meshspacing;
for (i = 0; i < cx; ++i,bx += anim->meshspacing) {
Vector v0 = anim->viewmat * Vector(bx, yb, 0.0);
Vector v1 = anim->viewmat * Vector(bx, ye, 0.0);
if (-anim->meshspacing/2 < bx && bx < anim->meshspacing/2) {
dc.SelectObject(TPen(cGridZero));
DrawLine(dc, v0, v1);
dc.SelectObject(TPen(cGrid,1,PS_DOT));
} else {
DrawLine(dc, v0, v1);
}
}
for (i = 0; i < cy; ++i,by += anim->meshspacing) {
Vector v0 = anim->viewmat * Vector(xb, by, 0.0);
Vector v1 = anim->viewmat * Vector(xe, by, 0.0);
if (-anim->meshspacing/2 < by && by < anim->meshspacing/2) {
dc.SelectObject(TPen(cGridZero));
DrawLine(dc, v0, v1);
dc.SelectObject(TPen(cGrid,1,PS_DOT));
} else {
DrawLine(dc, v0, v1);
}
}
}
void TWinPers::ShowLight(Vector& vec, int /*flag*/)
{
TClientDC dc(*this);
dc.SetROP2(R2_NOTXORPEN);
dc.SelectObject(TPen(cBackGround));
#define ARROW_POINTS 7
#define W1 (1.0/16.0)
#define W2 (1.0/4.0)
#define L1 1.0
#define L2 (1.0/3.0)
// static double ratex[ARROW_POINTS] = {0, L2, L2, L1, L1, L2, L2};
// static double ratey[ARROW_POINTS] = {0, W2, W1, W1,-W1,-W1,-W2};
static double ratex[ARROW_POINTS] = {0, L2, L2, L1, L1, L2, L2};
static double ratey[ARROW_POINTS] = {0, W2, W1, W1,-W1,-W1,-W2};
Vector vx, vy;
double l = (anim->camera->position - anim->camera->target->position).length() / 1.2 / vec.length();
vx = -l * vec;
vy = vx * (anim->camera->position - anim->camera->target->position);
double ly = vy.length();
if (ly < minimumdouble) return;
vy *= (vx.length()/ly);
Vector v0 = anim->camera->target->position - 0.5 * vx;
int i, px[ARROW_POINTS], py[ARROW_POINTS];
for (i = 0; i < ARROW_POINTS; i++) {
Vector v = anim->viewmat * (v0 + vx * ratex[i] + vy * ratey[i]);
if (v.z < 1) return;
px[i] = v.x / v.z;
py[i] = v.y / v.z;
}
dc.MoveTo(px[ARROW_POINTS-1], py[ARROW_POINTS-1]);
for (i = 0; i < ARROW_POINTS; i++) {
dc.LineTo(px[i], py[i]);
}
#if 0
double l = (anim->camera->position - anim->camera->target->position).length() / 2.0 / vec.length();
Vector v = anim->viewmat * (anim->camera->target->position - l * vec);
double vx, vy;
if (v.z < 1) {
return;
}
TPoint pc(Attr.W/2, Attr.H/2);
TPoint vl(v.x/v.z, v.y/v.z);
vx = vl.x - pc.x;
vy = -vl.y + pc.y;
dc.MoveTo(pc);
dc.LineTo(vl);
l = sqrt(vx*vx+vy*vy);
if (l > 1.0) {
vx *= ((double)(markersize*8) /l);
vy *= ((double)(markersize*8) /l);
TPoint v1(vx + 0.5 * vy, -vy + 0.5 * vx);
TPoint v2(vx - 0.5 * vy, -vy - 0.5 * vx);
dc.MoveTo(pc+v1);
dc.LineTo(pc);
dc.LineTo(pc+v2);
}
#endif
}
void TWinPers::EvLButtonDown (UINT modKeys, TPoint& point)
{
TWindow::EvLButtonDown(modKeys, point);
if (anim->opstat == OpPlay) {
anim->OpModeDefault();
}
}