home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
MEDIT.LZH
/
DRANGE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-10
|
16KB
|
690 lines
/* Project medit
Project Team DoGA
Copyright (c) 1995. All Rights Reserved.
サブシステム: medit.apx Application
ファイル: drange.cpp
作成者: Taka2
概要
====
TDRange (TDialog) のインプリメンテーション用のソースファイル
*/
#include <owl\owlpch.h>
#pragma hdrstop
#include <owl\static.h>
#include <owl\inputdia.h>
#include "drange.h"
#include "anim.h"
#include "motion.h"
#include "log.h"
static const TColor& cLine = TColor::Black;
static const TColor& cLineRange = TColor::LtGreen;
static const TColor& cMarkerLimit = TColor::LtYellow;
static const TColor& cMarkerLimitLine = TColor::Black;
static const TColor& cMarkerSpeed = TColor::LtBlue;
static const TColor& cGrid = TColor::LtYellow;
static const TColor& cLimit = TColor::LtBlue;
static const TColor& cLineSpeed = TColor::LtRed;
static const TColor& cRangeOutside = TColor::LtGray;
//
// このアプリケーションで処理するすべてのメッセージ/コマンドの
// 応答テーブルを作成する
//
DEFINE_RESPONSE_TABLE1(TDRange, TDialog)
//{{TDRangeRSP_TBL_BEGIN}}
EV_WM_LBUTTONDOWN,
EV_WM_LBUTTONUP,
EV_BN_CLICKED(IDOK, CmOK),
EV_WM_PAINT,
EV_WM_MOUSEMOVE,
EV_BN_CLICKED(IDHELP, HelpClicked),
//{{TDRangeRSP_TBL_END}}
END_RESPONSE_TABLE;
//{{TDRange Implementation}}
#define BEGINFRAME 1
#define ENDFRAME (anim->maxframe)
TDRange::TDRange (TWindow* parent, AnimationData *a, Motion *m, char *_mess, TResId resId, TModule* module):
TDialog(parent, resId, module)
{
// INSERT>> コンストラクタ用のコードはここに
// SetBkgndColor(TColor::LtGray);
anim = a;
motion = m;
mess = _mess;
message = new TStatic(this, IDC_TEXT_MESSAGE);
framebegin = new TStatic(this, IDC_NUM_TIME_BEGIN);
frameend = new TStatic(this, IDC_NUM_TIME_END);
framebegintext = new TStatic(this, IDC_TEXT_TIME_BEGIN);
frameendtext = new TStatic(this, IDC_TEXT_TIME_END);
pointbegin = new TStatic(this, IDC_TEXT_BEGIN);
pointend = new TStatic(this, IDC_TEXT_END);
begin = m->beginframe;
end = m->endframe;
if (m->motiondata != NULL) {
speed[0] = m->motiondata->speed[0];
speed[1] = m->motiondata->speed[1];
}
radius = 0;
dragflag = DRAG_NONE;
}
TDRange::~TDRange ()
{
Destroy();
}
int TDRange::GetX(int pos)
{
return axisx + (int)((double)rangex * (double)(pos - BEGINFRAME) / (double)(ENDFRAME - BEGINFRAME));
}
double TDRange::GetSpeedBegin(TPoint& p)
{
int b0 = GetX(begin);
int b1 = GetX(end);
int x = b0 - p.x;
int y = -axisy + p.y;
if (x == 0) {
return 0.0;
} else if (b0 == b1) {
return 4;
} else {
return (double)y / (double)x * (double)(b1-b0) / (double)rangey;
}
}
double TDRange::GetSpeedEnd(TPoint& p)
{
int b0 = GetX(begin);
int b1 = GetX(end);
int x = -b1 + p.x;
int y = axisy-rangey - p.y;
if (x == 0) {
return 0.0;
} else if (b0 == b1) {
return 4;
} else {
return (double)y / (double)x * (double)(b1-b0) / (double)rangey;
}
}
TPoint TDRange::GetBezierBegin(double s)
{
int b0 = GetX(begin);
int b1 = GetX(end);
if (s < 0) s = speed[0];
TPoint p;
if (b1 == b0) {
p.x = b0;
p.y = axisy - radius;
return p;
}
double a = s * rangey / (b1-b0);
double l = sqrt(a*a+1);
p.x = b0 + radius * 1.0 / l;
p.y = axisy - radius * a / l;
return p;
}
TPoint TDRange::GetBezierEnd(double s)
{
int b0 = GetX(begin);
int b1 = GetX(end);
if (s < 0) s = speed[1];
TPoint p;
if (b0 == b1) {
p.x = b1;
p.y = axisy - rangey + radius;
return p;
}
double a = s * rangey / (b1-b0);
double l = sqrt(a*a+1);
p.x = b1 - radius * 1.0 / l;
p.y = axisy - rangey + radius * a / l;
return p;
}
void TDRange::SetupWindow ()
{
TDialog::SetupWindow();
// INSERT>> 追加のコードはここに
message->SetText(mess);
char str[10];
sprintf(str, "%d", begin);
framebegin->SetText(str);
sprintf(str, "%d", end);
frameend->SetText(str);
framebegintext->SetText("BBB");
frameendtext->SetText("EEE");
axisx = framebegin->Attr.X + framebegin->Attr.W;
rangex = frameend->Attr.X - axisx;
axisy = pointbegin->Attr.Y + pointbegin->Attr.H/2;
rangey = axisy - (pointend->Attr.Y+pointend->Attr.H/2);
radius = rangey / 3;
// radius = (framebegin->Attr.Y - axisy);
// radius = axisx - (pointbegin->Attr.X + pointbegin->Attr.W);
if (motion == anim->camera || motion == anim->camera->target) {
framebegin->Show(SW_HIDE);
frameend->Show(SW_HIDE);
framebegintext->Show(SW_HIDE);
frameendtext->Show(SW_HIDE);
}
}
static double GetSpeedLimit(double s)
{
if (s < 1) {
return 4;
} else if (s < 3) {
return (9.0-s)/2.0;
} else {
return 9.0 - 2.0 * s;
}
}
void TDRange::DrawMarker(TDC& dc)
{
dc.SetROP2(R2_NOTXORPEN);
dc.SelectObject(TBrush(cMarkerSpeed));
dc.SelectObject(TPen(cLineRange));
TPoint p0, p1;
p0 = GetBezierBegin();
p1 = GetBezierEnd();
TPoint p0l = GetBezierBegin(GetSpeedLimit(speed[1]));
TPoint p1l = GetBezierEnd(GetSpeedLimit(speed[0]));
int x = GetX(begin), y = axisy;
dc.Arc(x-radius, y-radius, x+radius, y+radius,
x+radius, y, p0l.x, p0l.y);
dc.MoveTo(p0l);dc.LineTo(x,y);dc.LineTo(x+radius,y);
x = GetX(end);
y = axisy - rangey;
dc.Arc(x-radius, y-radius, x+radius, y+radius,
x-radius, y, p1l.x, p1l.y);
dc.MoveTo(p1l);dc.LineTo(x,y);dc.LineTo(x-radius,y);
// dc.MoveTo(GetX(begin), axisy);
// dc.LineTo(p0);
// dc.MoveTo(GetX(end), axisy-rangey);
// dc.LineTo(p1);
dc.SelectStockObject(BLACK_PEN);
dc.Rectangle(p0.x-markersize, p0.y -markersize, p0.x+markersize, p0.y +markersize);
dc.Rectangle(p1.x-markersize, p1.y -markersize, p1.x+markersize, p1.y +markersize);
}
void TDRange::DrawBegin(TDC& dc)
{
dc.SetROP2(R2_NOTXORPEN);
dc.SelectObject(TBrush(cMarkerLimit));
dc.SelectObject(TPen(cMarkerLimitLine));
int x0 = GetX(begin);
dc.Rectangle(x0-markersize, axisy+markersize*2, x0+markersize, axisy+markersize*4);
dc.SelectObject(TPen(cLimit));
dc.MoveTo(x0, axisy - rangey);
dc.LineTo(x0, axisy + markersize*3);
dc.LineTo(x0 + markersize*5, axisy + markersize*3);
dc.LineTo(x0 + markersize*4, axisy + markersize*2);
dc.MoveTo(x0 + markersize*5, axisy + markersize*3);
dc.LineTo(x0 + markersize*4, axisy + markersize*4);
if (lastbegin != x0) {
dc.SelectObject(TBrush(cRangeOutside));
dc.SelectObject(TPen(cRangeOutside));
dc.Rectangle(lastbegin-1, axisy-rangey, x0-1, axisy);
lastbegin = x0;
}
}
void TDRange::DrawEnd(TDC& dc)
{
dc.SetROP2(R2_NOTXORPEN);
dc.SelectObject(TBrush(cMarkerLimit));
dc.SelectObject(TPen(cMarkerLimitLine));
int x0 = GetX(end);
int x1 = GetX(begin);
if (x1 != x0) {
dc.Rectangle(x0-markersize, axisy+markersize*2, x0+markersize, axisy+markersize*4);
}
dc.SelectObject(TPen(cLimit));
if (x1!=x0) {
dc.MoveTo(x0, axisy - rangey);
dc.LineTo(x0, axisy + markersize*3);
} else {
dc.MoveTo(x0, axisy + markersize*3);
}
dc.LineTo(x0 - markersize*5, axisy + markersize*3);
dc.LineTo(x0 - markersize*4, axisy + markersize*2);
dc.MoveTo(x0 - markersize*5, axisy + markersize*3);
dc.LineTo(x0 - markersize*4, axisy + markersize*4);
if (lastend != x0) {
dc.SelectObject(TBrush(cRangeOutside));
dc.SelectObject(TPen(cRangeOutside));
dc.Rectangle(x0+1, axisy-rangey, lastend+1, axisy);
lastend = x0;
}
}
void TDRange::DrawLine(TDC& dc)
{
int x0, x1;
x0 = GetX(begin);
x1 = GetX(end);
dc.SelectObject(TPen(cLine));
dc.MoveTo(x1, axisy);
double t, tstep;
int x;
int count;
static const int xstep = 4;
count = (x1 - x0)/xstep;
if (count > 0) {
tstep = 1.0 / (double)(count);
} else {
tstep = 0;
}
x = x0;
t = 0;
double b, c;
b = speed[0] / 3.0;
c = 1.0 - speed[1] / 3.0;
dc.MoveTo(x0, axisy);
for (int i = count-1; i > 0; --i) {
x += xstep;
t += tstep;
double ny;
ny = + 3 * b * t * (1.0-t) * (1.0-t)
+ 3 * c * t * t * (1.0-t)
+ 1 * t * t * t;
if (ny < 0) ny = 0;
if (ny > 1.0) ny = 1.0;
dc.LineTo(x, axisy - ny * rangey);
}
dc.LineTo(x1, axisy - rangey);
dc.SelectObject(TPen(cLineSpeed));
}
void TDRange::Draw(void)
{
if (BEGINFRAME >= ENDFRAME) {
return;
}
TClientDC dc(*this);
if (motion->motiondata != NULL) {
DrawMarker(dc);
DrawLine(dc);
}
if (motion != anim->camera && motion != anim->camera->target) {
DrawBegin(dc);
DrawEnd(dc);
}
}
void TDRange::MoveBegin(void)
{
char str[8];
int x0 = GetX(begin);
sprintf(str, "%d", begin);
framebegin->SetText("");
framebegin->MoveWindow(x0-framebegin->Attr.W, framebegin->Attr.Y,
framebegin->Attr.W, framebegin->Attr.H);
framebegin->SetText(str);
int x1 = GetX(end);
int step = 0;
if ((x1 - x0 - 2) < framebegintext->Attr.W) {
step = (x1 - x0 - 2)/2;
} else {
step = framebegintext->Attr.W/2;
}
framebegintext->SetText("");
framebegintext->MoveWindow(x0 + step - framebegintext->Attr.W,
framebegintext->Attr.Y,
framebegintext->Attr.W,
framebegintext->Attr.H);
framebegintext->SetText("出現時刻");
if (x1-step != frameendtext->Attr.X) {
frameendtext->SetText("");
frameendtext->MoveWindow(x1-step, frameendtext->Attr.Y,
frameendtext->Attr.W, frameendtext->Attr.H);
frameendtext->SetText("消失時刻");
}
}
void TDRange::MoveEnd(void)
{
char str[8];
int x1 = GetX(end);
sprintf(str, "%d", end);
frameend->SetText("");
frameend->MoveWindow(x1, frameend->Attr.Y,
frameend->Attr.W, frameend->Attr.H);
frameend->SetText(str);
int x0 = GetX(begin);
int step = 0;
if ((x1 - x0 - 2) < framebegintext->Attr.W) {
step = (x1 - x0 - 2)/2;
} else {
step = framebegintext->Attr.W/2;
}
if (x0+step != framebegintext->Attr.X) {
framebegintext->SetText("");
framebegintext->MoveWindow(x0 + step - framebegintext->Attr.W,
framebegintext->Attr.Y,
framebegintext->Attr.W,
framebegintext->Attr.H);
framebegintext->SetText("出現時刻");
}
frameendtext->SetText("");
frameendtext->MoveWindow(x1-step, frameendtext->Attr.Y,
frameendtext->Attr.W, frameendtext->Attr.H);
frameendtext->SetText("消失時刻");
}
void TDRange::Redraw(void)
{
int i;
TClientDC dc(*this);
dc.SelectStockObject(WHITE_PEN);
// dc.SelectObject(TPen(TColor::LtGray));
// dc.SelectObject(TBrush(TColor::LtGray));
dc.Rectangle(axisx - 2 - markersize, axisy + 2 + markersize*4,
axisx + 2 + rangex + markersize, axisy - 2 - rangey - markersize*4);
dc.SelectStockObject(BLACK_PEN);
dc.MoveTo(axisx-2 , axisy+2 );
dc.LineTo(axisx+2 + rangex, axisy+2 );
dc.LineTo(axisx+2 + rangex, axisy-2 - rangey);
dc.LineTo(axisx-2 , axisy-2 - rangey);
dc.LineTo(axisx-2 , axisy+2 );
dc.SelectObject(TPen(cGrid));
int step = 500;
int frames = ENDFRAME - BEGINFRAME;
if (frames * (markersize*4) < rangex) {
step = 1;
} else if ((frames/5) * (markersize*4) < rangex) {
step = 5;
} else if ((frames/10) * (markersize*4) < rangex) {
step = 10;
} else if ((frames/50) * (markersize*4) < rangex) {
step = 50;
} else if ((frames/100) * (markersize*4) < rangex) {
step = 100;
} else if ((frames/500) * (markersize*4) < rangex) {
step = 500;
} else if ((frames/1000) * (markersize*4) < rangex) {
step = 1000;
}
for (i = BEGINFRAME; i < ENDFRAME; i ++) {
if (i % step == 0) {
int x = GetX(i);
dc.MoveTo(x, axisy );
dc.LineTo(x, axisy - rangey);
}
}
for (i = 10; i < 100; i+=10) {
int y = axisy - rangey * i / 100;
dc.MoveTo(axisx , y);
dc.LineTo(axisx + rangex , y);
}
MoveBegin();
MoveEnd();
lastbegin = axisx-1;
lastend = axisx + rangex+1;
if (BEGINFRAME < ENDFRAME) {
Draw();
}
}
void TDRange::Paint (TDC& dc, BOOL erase, TRect& rect)
{
TDialog::Paint(dc, erase, rect);
// INSERT>> 追加のコードはここに
Redraw();
}
static int dist(TPoint& p1, TPoint& p2)
{
int dist;
TPoint p = p1 - p2;
if (p.x < 0) {
dist = -p.x;
} else {
dist = p.x;
}
if (p.y < 0) {
dist += -p.y;
} else {
dist += p.y;
}
return dist;
}
void TDRange::EvLButtonDown (UINT modKeys, TPoint& point)
{
TDialog::EvLButtonDown(modKeys, point);
// INSERT>> 追加コードはここに
if (BEGINFRAME >= ENDFRAME) {
return;
}
dragflag = DRAG_NONE;
if (motion != anim->camera && motion != anim->camera->target) {
if (dist(TPoint(GetX(begin), axisy+markersize*3), point) < markersize*2) {
dragflag = DRAG_BEGIN;
SetCapture();
return;
}
if (dist(TPoint(GetX(end), axisy+markersize*3), point) < markersize*2) {
dragflag = DRAG_END;
SetCapture();
return;
}
}
if (motion->motiondata != NULL) {
if (dist(GetBezierBegin(), point) < markersize * 2) {
dragflag = DRAG_SPEED_BEGIN;
return;
}
if (dist(GetBezierEnd(), point) < markersize * 2) {
dragflag = DRAG_SPEED_END;
return;
}
}
}
void TDRange::EvMouseMove (UINT modKeys, TPoint& point)
{
TDialog::EvMouseMove(modKeys, point);
// INSERT>> 追加コードはここに
if (dragflag == DRAG_NONE) {
return;
}
int t = (int)((double)(ENDFRAME - BEGINFRAME) * (double)(point.x - axisx) / (double)rangex) + BEGINFRAME;
int t2;
double s;
Draw();
switch(dragflag) {
case DRAG_BEGIN:
if (t < BEGINFRAME) t = BEGINFRAME;
t2 = end;
if (motion->motiondata == NULL && t > end) {
// t = end;
if (t <= ENDFRAME) {
t2 = t;
} else {
t2 = t = ENDFRAME;
}
} else if (motion->motiondata != NULL && t >= end) {
// t = end-1;
if (t <= ENDFRAME-1) {
t2 = t+1;
} else {
t2 = ENDFRAME;
t = ENDFRAME-1;
}
}
if (t != begin) {
begin = t;
MoveBegin();
}
if (t2 != end) {
end = t2;
MoveEnd();
}
break;
case DRAG_END:
if (t > ENDFRAME) t = ENDFRAME;
t2 = begin;
if (motion->motiondata == NULL && t < begin) {
// t = begin;
if (t >= BEGINFRAME) {
t2 = t;
} else {
t2 = t = BEGINFRAME;
}
} else if (motion->motiondata != NULL && t <= begin) {
// t = begin+1;
if (t >= BEGINFRAME + 1) {
t2 = t-1;
} else {
t2 = BEGINFRAME;
t = BEGINFRAME+1;
}
}
if (t2 != begin) {
begin = t2;
MoveBegin();
}
if (t != end) {
end = t;
MoveEnd();
}
break;
case DRAG_SPEED_BEGIN:
s = GetSpeedBegin(point);
if (s > (t = GetSpeedLimit(speed[1]))) s = t;
if (s < 0.0) s = 0.0;
speed[0] = s;
break;
case DRAG_SPEED_END:
s = GetSpeedEnd(point);
if (s > (t = GetSpeedLimit(speed[0]))) s = t;
if (s < 0.0) s = 0.0;
speed[1] = s;
break;
}
Draw();
}
void TDRange::EvLButtonUp (UINT modKeys, TPoint& point)
{
TDialog::EvLButtonUp(modKeys, point);
dragflag = DRAG_NONE;
ReleaseCapture();
}
void TDRange::CmOK ()
{
// INSERT>> 追加コードはここに
if (motion != anim->camera && motion != anim->camera->target) {
motion->beginframe = begin;
motion->endframe = end;
}
if (motion->motiondata != NULL) {
motion->motiondata->speed[0] = speed[0];
motion->motiondata->speed[1] = speed[1];
}
CloseWindow(IDOK);
}
void TDRange::EvPaint ()
{
TDialog::EvPaint();
// INSERT>> 追加コードはここに
Redraw();
}
void TDRange::HelpClicked ()
{
// INSERT>> 追加コードはここに
anim->WinHelp(HELP_KEY, (DWORD)"速度調整グラフの使い方");
}