home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-14 | 33.1 KB | 1,008 lines |
- /**********************************************************************
- *
- * File : rwsim.c
- *
- * Abstract : RenderWare N body simulation demo. Main module
- *
- **********************************************************************
- *
- * This file is a product of Criterion Software Ltd.
- *
- * This file is provided as is with no warranties of any kind and is
- * provided without any obligation on Criterion Software Ltd. or
- * Canon Inc. to assist in its use or modification.
- *
- * Criterion Software Ltd. will not, under any
- * circumstances, be liable for any lost revenue or other damages arising
- * from the use of this file.
- *
- * Copyright (c) 1995 Criterion Software Ltd.
- * All Rights Reserved.
- *
- * RenderWare is a trademark of Canon Inc.
- *
- ************************************************************************/
- #define INCLUDE_SHELLAPI_H
-
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <time.h>
-
- #include <rwlib.h>
-
- #include "common.h"
- #include "status.h"
- #include "resource.h"
-
- #ifndef __WINDOWS_386__
- #define MK_FP32(x) (x)
- #endif
-
- #define DAMPING CREAL(0.95)
- #define MAXTHINGS 25
-
- #define ERROR_DIALOG_TITLE "RenderWare n-Body Simulation Error"
-
- #define MAXIMUM_WINDOW_WIDTH 512
- #define MAXIMUM_WINDOW_HEIGHT 512
-
- /*--- Ansi Declarations */
-
- extern long far PASCAL MainWndProc(HWND, WORD, WPARAM, LPARAM);
-
- typedef struct
- {
- RwClump *geometry;
- int canmove;
- RwReal size;
- RwV3d pos, vel;
- RwMatrix4d *tumble, *rot, *antirot;
- RwReal rotangle, antiangle;
- RwV3d axis;
- int damprot;
- }
- Thing;
-
- Thing things[MAXTHINGS];
- int follow, numthings;
-
- HANDLE hInstance;
- RwScene *scene;
- RwCamera *pCamera;
- RwLight *pLight;
-
- static ThreeDInitialized = FALSE;
-
- static long frames = 0;
-
- /**************************************************************************
- About Dialogue Box Stuff
- **************************************************************************/
- void
- DlgDrawItem(DRAWITEMSTRUCT FAR * dis)
- {
- HDC hdcMemory;
- HBITMAP hbmplogo, hbmpOld;
- BITMAP bm;
-
- hbmplogo = LoadBitmap(hInstance, "RW_LOGO");
- GetObject(hbmplogo, sizeof (BITMAP), &bm);
-
- hdcMemory = CreateCompatibleDC(dis->hDC);
- hbmpOld = SelectObject(hdcMemory, hbmplogo);
-
- BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top,
- dis->rcItem.right - dis->rcItem.left,
- dis->rcItem.bottom - dis->rcItem.top,
- hdcMemory, 0, 0, SRCCOPY);
-
- SelectObject(hdcMemory, hbmpOld);
- DeleteDC(hdcMemory);
- DeleteObject(hbmplogo);
- }
-
- BOOL FAR PASCAL
- AboutDlgProc(HWND hDlg, WORD message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDOK:
- case IDCANCEL:
- EndDialog(hDlg, 0);
- return (TRUE);
- }
- break;
-
- case WM_DRAWITEM:
- DlgDrawItem((DRAWITEMSTRUCT FAR *) MK_FP32((void *) lParam));
- return (TRUE);
- }
- return (FALSE);
- }
-
- /**********************************************************************/
- /* Handle the given menu item. */
- /**********************************************************************/
-
- static void
- HandleMenu(HWND window, WPARAM menuItem)
- {
-
- switch (menuItem)
- {
- case CM_FILEEXIT:
- SendMessage(window, WM_CLOSE, 0, 0L);
- break;
- case CM_TRACK0:
- follow = 0;
- break;
- case CM_TRACK1:
- follow = 1;
- break;
- case CM_TRACK2:
- follow = 2;
- break;
- case CM_TRACK3:
- follow = 3;
- break;
- case CM_TRACK4:
- follow = 4;
- break;
- case CM_TRACK5:
- follow = 5;
- break;
- case CM_TRACK6:
- follow = 6;
- break;
- case CM_TRACK7:
- follow = 7;
- break;
- case CM_TRACK8:
- follow = 8;
- break;
- case CM_TRACK9:
- follow = 9;
- break;
- case CM_HELPABOUT:
- KillTimer(window, 1);
- DialogBox(hInstance, "ABOUT", window, MakeProcInstance(AboutDlgProc, hInstance));
- SetTimer(window, 1, 10, NULL);
- break;
- }
- }
-
- /*********************************************************************/
- static void
- randomvec(RwV3d * vec)
- {
- vec->x = RANDOM_REAL(CREAL(-1.0), CREAL(1.0));
- vec->y = RANDOM_REAL(CREAL(-1.0), CREAL(1.0));
- vec->z = RANDOM_REAL(CREAL(-1.0), CREAL(1.0));
- }
-
- /*********************************************************************/
- static void
- assignvec(RwV3d * vec, RwReal x, RwReal y, RwReal z)
- {
- vec->x = x;
- vec->y = y;
- vec->z = z;
- }
-
- /*********************************************************************/
- static RwPolygon3d *
- makezippy(RwPolygon3d * p)
- {
- static int zippy = 0;
-
- switch (zippy % 7)
- {
- case 0:
- RwSetPolygonColor(p, CREAL(0.7), CREAL(0.0), CREAL(0.0));
- break;
- case 1:
- RwSetPolygonColor(p, CREAL(0.0), CREAL(0.7), CREAL(0.0));
- break;
- case 2:
- RwSetPolygonColor(p, CREAL(0.0), CREAL(0.0), CREAL(0.7));
- break;
- case 3:
- RwSetPolygonColor(p, CREAL(0.7), CREAL(0.7), CREAL(0.0));
- break;
- case 4:
- RwSetPolygonColor(p, CREAL(0.7), CREAL(0.0), CREAL(0.7));
- break;
- case 5:
- RwSetPolygonColor(p, CREAL(0.0), CREAL(0.7), CREAL(0.7));
- break;
- case 6:
- RwSetPolygonColor(p, CREAL(0.7), CREAL(0.7), CREAL(0.7));
- break;
- }
- zippy++;
- return (p);
- }
-
- /*********************************************************************/
- static void
- makethings(RwScene * scene, Thing * things, int num)
- {
- RwClump *clump, *prototypes[4];
- RwV3d p;
- int i;
- RwInt32 which;
-
- RwSRandom((RwInt32) clock());
-
- for (i = 0; i < 4; i++)
- {
- RwClumpBegin();
- RwSetSurface(CREAL(0.4), CREAL(0.7), CREAL(0.0));
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))));
- switch (i)
- {
- case 0:
- RwTranslateCTM(CREAL(0.0), CREAL(-0.15 / 2), CREAL(0.0));
- RwCone(CREAL(0.15), CREAL(0.1), 12);
- RwRotateCTM(CREAL(1.0), CREAL(0.0), CREAL(0.0), CREAL(180.0));
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))));
- RwDisc(CREAL(0.0), CREAL(0.1), 12);
- break;
- case 1:
- RwSphere(CREAL(0.1), 3);
- break;
- case 2:
- RwTranslateCTM(CREAL(0.0), CREAL(-0.15 / 2), CREAL(0.0));
- RwCylinder(CREAL(0.15), CREAL(0.1), CREAL(0.1), 12);
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))));
- RwDisc(CREAL(0.15), CREAL(0.1), 12);
- RwRotateCTM(CREAL(1.0), CREAL(0.0), CREAL(0.0), CREAL(180.0));
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (RwRandom() % 4))));
- RwDisc(CREAL(0.0), CREAL(0.1), 12);
- break;
- default:
- RwBlock(CREAL(0.1), CREAL(0.2), CREAL(0.15));
- break;
- }
- RwClumpEnd(&prototypes[i]);
- }
-
- for (i = 0; i < num; i++)
- {
- which = RwRandom() % 4L;
- clump = RwDuplicateClump(prototypes[(int) which]);
- if ((RwRandom() & 7) < 2)
- RwForAllPolygonsInClump(clump, makezippy);
- RwAddClumpToScene(scene, clump);
- things[i].geometry = clump;
- things[i].size = CREAL(0.1);
- RwIdentityMatrix(things[i].tumble = RwCreateMatrix());
- RwIdentityMatrix(things[i].rot = RwCreateMatrix());
- /*
- RwIdentityMatrix(things[i].antirot = RwCreateMatrix());
- */
- things[i].damprot = 0;
- randomvec(&p);
- things[i].pos.x = RMul(p.x, RSub(CREAL(1.0), things[i].size));
- things[i].pos.y = RMul(p.y, RSub(CREAL(1.0), things[i].size));
- things[i].pos.z = RMul(p.z, RSub(CREAL(1.0), things[i].size));
- things[i].canmove = 7;
- assignvec(&things[i].vel, CREAL(0.0), CREAL(0.0), CREAL(0.0));
- }
- for (i = 0; i < 4; i++)
- RwDestroyClump(prototypes[i]);
- }
-
- /*********************************************************************/
- static
- twobody(Thing * things, int i, int j)
- {
- RwReal length, adjust, doti, dotj, speedi, speedj;
- RwV3d hit, axis, xferi, xferj;
- RwV3d veli, velj;
-
- hit.x = RSub(things[j].pos.x, things[i].pos.x);
- hit.y = RSub(things[j].pos.y, things[i].pos.y);
- hit.z = RSub(things[j].pos.z, things[i].pos.z);
- length = RAdd(RAdd(RMul(hit.x, hit.x), RMul(hit.y, hit.y)),
- RMul(hit.z, hit.z));
- if (length > CREAL(0.0) && length < CREAL(0.2 * 0.2))
- {
- if (1)
- {
- length = RSqrt(length);
- hit.x = RDiv(hit.x, length);
- hit.y = RDiv(hit.y, length);
- hit.z = RDiv(hit.z, length);
- adjust = RDiv(RSub(CREAL(0.2), length), CREAL(2));
-
- veli = things[i].vel;
- speedi = RAdd(RAdd(RMul(veli.x, veli.x), RMul(veli.y, veli.y)),
- RMul(veli.z, veli.z));
- if (speedi != CREAL(0.0))
- {
- speedi = RSqrt(speedi);
- veli.x = RDiv(veli.x, speedi);
- veli.y = RDiv(veli.y, speedi);
- veli.z = RDiv(veli.z, speedi);
- doti = RwDotProduct(&hit, &veli);
- if (doti > CREAL(0))
- {
- speedi = RMul(speedi, RMul(doti, DAMPING));
- xferi.x = RMul(hit.x, speedi);
- xferi.y = RMul(hit.y, speedi);
- xferi.z = RMul(hit.z, speedi);
- RwCrossProduct(&veli, &hit, &axis);
- /*
- RwRotateMatrix(things[i].rot, axis.x,axis.y,axis.z,
- RMul(speedi, RMul(RSub(CREAL(1),doti), CREAL(720.0))),
- rwREPLACE);
- */
- things[i].rotangle = RMul(speedi, RMul(RSub(CREAL(1), doti), CREAL(720.0)));
- things[i].axis.x = axis.x;
- things[i].axis.y = axis.y;
- things[i].axis.z = axis.z;
- /*
- RwRotateMatrix(things[i].antirot, axis.x,axis.y,axis.z,
- RMul(speedi, RMul(RSub(CREAL(1),doti), CREAL(-4.0))),
- rwREPLACE);
- */
- things[i].antiangle = RMul(speedi, RMul(RSub(CREAL(1), doti), CREAL(-4.0)));
- things[i].damprot = (int) (720.0 / 4.0);
- }
- else
- xferi.x = xferi.y = xferi.z = CREAL(0.0);
- }
- else
- xferi.x = xferi.y = xferi.z = CREAL(0.0);
- /* I happen to know that -= works :-) */
- if (things[i].canmove & 1)
- things[i].pos.x -= RMul(hit.x, adjust);
- if (!things[j].canmove & 1)
- things[i].pos.x -= RMul(hit.x, adjust);
- if (things[i].canmove & 2)
- things[i].pos.y -= RMul(hit.y, adjust);
- if (!things[j].canmove & 2)
- things[i].pos.y -= RMul(hit.y, adjust);
- if (things[i].canmove & 4)
- things[i].pos.z -= RMul(hit.z, adjust);
- if (!things[j].canmove & 4)
- things[i].pos.z -= RMul(hit.z, adjust);
-
- hit.x = -hit.x;
- hit.y = -hit.y;
- hit.z = -hit.z;
- velj = things[j].vel;
- speedj = RAdd(RAdd(RMul(velj.x, velj.x), RMul(velj.y, velj.y)),
- RMul(velj.z, velj.z));
- if (speedj != CREAL(0.0))
- {
- speedj = RSqrt(speedj);
- velj.x = RDiv(velj.x, speedj);
- velj.y = RDiv(velj.y, speedj);
- velj.z = RDiv(velj.z, speedj);
- dotj = RwDotProduct(&hit, &velj);
- if (dotj > CREAL(0))
- {
- speedj = RMul(speedj, RMul(dotj, DAMPING));
- xferj.x = RMul(hit.x, speedj);
- xferj.y = RMul(hit.y, speedj);
- xferj.z = RMul(hit.z, speedj);
- RwCrossProduct(&velj, &hit, &axis);
- /*
- RwRotateMatrix(things[j].rot, axis.x,axis.y,axis.z,
- RMul(speedj, RMul(RSub(CREAL(1),dotj), CREAL(720.0))),
- rwREPLACE);
- */
- things[j].rotangle = RMul(speedj, RMul(RSub(CREAL(1), dotj), CREAL(720.0)));
- things[j].axis.x = axis.x;
- things[j].axis.y = axis.y;
- things[j].axis.z = axis.z;
- /*
- RwRotateMatrix(things[j].antirot, axis.x,axis.y,axis.z,
- RMul(speedj, RMul(RSub(CREAL(1),dotj), CREAL(-4.0))),
- rwREPLACE);
- */
- things[j].antiangle = RMul(speedj, RMul(RSub(CREAL(1), dotj), CREAL(-4.0)));
- things[j].damprot = (int) (720.0 / 4.0);
- }
- else
- xferj.x = xferj.y = xferj.z = CREAL(0.0);
- }
- else
- xferj.x = xferj.y = xferj.z = CREAL(0.0);
- if (things[j].canmove & 1)
- things[j].pos.x -= RMul(hit.x, adjust);
- if (!things[i].canmove & 1)
- things[j].pos.x -= RMul(hit.x, adjust);
- if (things[j].canmove & 2)
- things[j].pos.y -= RMul(hit.y, adjust);
- if (!things[i].canmove & 2)
- things[j].pos.y -= RMul(hit.y, adjust);
- if (things[j].canmove & 4)
- things[j].pos.z -= RMul(hit.z, adjust);
- if (!things[i].canmove & 4)
- things[j].pos.z -= RMul(hit.z, adjust);
-
- /* A little bird told me that += always works :-) */
- things[i].vel.x += RSub(xferj.x, xferi.x);
- things[i].vel.y += RSub(xferj.y, xferi.y);
- things[i].vel.z += RSub(xferj.z, xferi.z);
-
- things[j].vel.x += RSub(xferi.x, xferj.x);
- things[j].vel.y += RSub(xferi.y, xferj.y);
- things[j].vel.z += RSub(xferi.z, xferj.z);
- }
- return (1);
- }
- return (0);
- }
-
- /*********************************************************************/
- void
- collisions(Thing * things, int num)
- {
- int i, j;
-
- for (i = 0; i < num; i++)
- {
- for (j = i + 1; j < num; j++)
- {
- if (twobody(things, i, j))
- break;
- }
- }
- }
-
- /*********************************************************************/
- static void
- gravitatethings(Thing * things, int num, RwV3d * acc)
- {
- int i;
- RwV3d p;
- RwReal val;
- RwReal limit;
-
- RwPushScratchMatrix();
- limit = CREAL(1.0 - 0.1);
- for (i = 0; i < num; i++)
- {
- if (things[i].damprot > 0)
- {
- /* Below is the original version of the damping code. This accumulates
- a new .rot matrix by repeated multiplication with .antirot. This
- causes the .rot matrix to drift causing shearing of the object.
- RwMultiplyMatrix(things[i].rot, things[i].antirot, RwScratchMatrix());
- RwCopyMatrix(RwScratchMatrix(), things[i].rot);
- */
- RwRotateMatrix(things[i].rot, things[i].axis.x, things[i].axis.y,
- things[i].axis.z,
- RSub(things[i].rotangle, things[i].antiangle), rwREPLACE);
- things[i].damprot--;
- }
- RwMultiplyMatrix(things[i].tumble, things[i].rot, RwScratchMatrix());
- if ((frames) % (num << 3) == (i << 3))
- RwOrthoNormalizeMatrix(RwScratchMatrix(), RwScratchMatrix());
- RwCopyMatrix(RwScratchMatrix(), things[i].tumble);
- p = things[i].pos;
- RwTranslateMatrix(RwScratchMatrix(), p.x, p.y, p.z, rwPOSTCONCAT);
- RwTransformClump(things[i].geometry, RwScratchMatrix(), rwREPLACE);
-
- things[i].canmove = 0;
- /* += */
- things[i].vel.x += acc->x;
- val = things[i].pos.x += things[i].vel.x;
- if (val < -limit || val > limit)
- {
- things[i].vel.x -= acc->x;
- things[i].vel.x = RMul(-things[i].vel.x, DAMPING);
- things[i].pos.x = val < CREAL(0.0) ? -limit : limit;
- }
- else
- things[i].canmove |= 1;
-
- things[i].vel.y += acc->y;
- val = things[i].pos.y += things[i].vel.y;
- if (val < -limit || val > limit)
- {
- things[i].vel.y -= acc->y;
- things[i].vel.y = RMul(-things[i].vel.y, DAMPING);
- things[i].pos.y = val < CREAL(0.0) ? -limit : limit;
- }
- else
- things[i].canmove |= 2;
-
- things[i].vel.z += acc->z;
- val = things[i].pos.z += things[i].vel.z;
- if (val < -limit || val > limit)
- {
- things[i].vel.z -= acc->z;
- things[i].vel.z = RMul(-things[i].vel.z, DAMPING);
- things[i].pos.z = val < CREAL(0.0) ? -limit : limit;
- }
- else
- things[i].canmove |= 4;
- }
- RwPopScratchMatrix();
- frames++;
- }
- /*********************************************************************/
- /*********************************************************************/
-
- BOOL
- InitApplication(HANDLE hInst)
- {
- WNDCLASS wc;
-
- wc.style = CS_BYTEALIGNWINDOW | CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC) MainWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInst;
- wc.hIcon = LoadIcon(hInst, "RW_ICON");
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = NULL;
- wc.lpszMenuName = "FILE_MENU";
- wc.lpszClassName = "RwNBodyWndClass";
-
- return (RegisterClass(&wc));
- }
-
- BOOL
- InitInstance(HANDLE hInst, int nCmdShow)
- {
- HWND hWnd;
- int i, j;
- RwClump *temp;
-
- hInstance = hInst;
-
- hWnd = CreateWindow("RwNBodyWndClass", "RenderWare n-Body Simulation",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, 350, 350,
- NULL, NULL, hInstance, NULL);
-
- if (hWnd == NULL)
- {
- MessageBox(NULL, "Internal Operating System Error",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- return (FALSE);
- }
-
- CheckDisplayDepth(hWnd);
-
- if (!RwOpen("MSWindows", NULL))
- {
- if (RwGetError() == E_RW_NOMEM)
- {
- MessageBox(hWnd,
- "Insufficient memory to open the RenderWare library",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- }
- else
- {
- MessageBox(hWnd, "Error opening the RenderWare library",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- }
- return (FALSE);
- }
-
- scene = RwCreateScene();
- if (scene == NULL)
- {
- RwClose();
- MessageBox(hWnd, "Error creating the RenderWare scene",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- return (FALSE);
- }
-
- pCamera = RwCreateCamera(MAXIMUM_WINDOW_WIDTH,
- MAXIMUM_WINDOW_HEIGHT, NULL);
-
- if (pCamera == NULL)
- {
- if (RwGetError() == E_RW_NOMEM)
- {
- MessageBox(hWnd,
- "Insufficient memory to create the RenderWare camera",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- }
- else
- {
- MessageBox(hWnd, "Error creating the RenderWare camera",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- }
- RwDestroyScene(scene);
- RwClose();
- return (FALSE);
- }
-
- RwClearCameraViewport(pCamera);
- RwSetCameraBackColor(pCamera, CREAL(0.0), CREAL(0.0), CREAL(0.0));
- RwVCMoveCamera(pCamera, CREAL(0.0), CREAL(0.0), CREAL(-7.0));
- pLight = RwCreateLight(rwDIRECTIONAL, CREAL(-0.5), CREAL(-1.0), CREAL(-1.0),
- CREAL(1.2));
-
- if (pLight == NULL)
- {
- RwDestroyCamera(pCamera);
- RwDestroyScene(scene);
- RwClose();
- MessageBox(hWnd, "Error creating the RenderWare light",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- return (FALSE);
- }
- RwAddLightToScene(scene, pLight);
-
- RwClumpBegin();
- RwVertex(CREAL(-1.0), CREAL(-1.005), CREAL(1.0));
- RwVertex(CREAL(1.0), CREAL(-1.005), CREAL(1.0));
- RwVertex(CREAL(1.0), CREAL(1.0), CREAL(1.0));
- RwVertex(CREAL(-1.0), CREAL(1.0), CREAL(1.0));
- RwVertex(CREAL(-1.0), CREAL(-1.005), CREAL(-1.0));
- RwVertex(CREAL(1.0), CREAL(-1.005), CREAL(-1.0));
- RwVertex(CREAL(1.0), CREAL(1.0), CREAL(-1.0));
- RwVertex(CREAL(-1.0), CREAL(1.0), CREAL(-1.0));
- RwSetSurface(CREAL(0.4), CREAL(0.6), CREAL(0.0));
- RwSetSurfaceColor(CREAL(0.5), CREAL(0.5), CREAL(0.5));
- RwQuad(2, 1, 4, 3);
- RwSetSurfaceColor(CREAL(0.0), CREAL(0.0), CREAL(0.7));
- RwQuad(6, 2, 3, 7);
- RwSetSurfaceColor(CREAL(0.0), CREAL(0.7), CREAL(0.0));
- RwQuad(5, 6, 7, 8);
- RwSetSurfaceColor(CREAL(0.7), CREAL(0.0), CREAL(0.0));
- RwQuad(1, 5, 8, 4);
- RwSetSurfaceColor(CREAL(0.0), CREAL(0.7), CREAL(0.0));
- RwQuad(8, 7, 3, 4);
- RwTransformBegin();
- RwTranslateCTM(CREAL(0.0), CREAL(-1.0), CREAL(0.0));
- RwScaleCTM(CREAL(0.25), CREAL(0.0), CREAL(0.25));
- for (i = -4; i <= 4; i++)
- for (j = -4; j <= 4; j++)
- RwVertex(INT2REAL(i), CREAL(0.0), INT2REAL(j));
- for (i = 0; i < 8; i++)
- for (j = 0; j < 8; j++)
- {
- if ((i ^ j) & 1)
- {
- RwSetSurface(CREAL(0.5), CREAL(0.2), CREAL(0.0));
- RwSetSurfaceColor(CREAL(1.0), CREAL(0.0), CREAL(0.0));
- }
- else
- {
- RwSetSurface(CREAL(0.5), CREAL(0.5), CREAL(0.0));
- RwSetSurfaceColor(CREAL(0.5), CREAL(0.5), CREAL(0.0));
- }
- RwQuad(9 + (i * 9) + j, 9 + (i * 9) + j + 1, 9 + ((i + 1) * 9) + j + 1, 9 + ((i + 1) * 9) + j);
- }
- RwTransformEnd();
- RwClumpEnd(&temp);
- RwAddHintToClump(temp, rwCONTAINER);
- RwAddClumpToScene(scene, temp);
-
- numthings = 10; /* number of objects */
- makethings(scene, things, numthings);
-
- follow = 0;
-
- /* thunderbirds are go! */
-
- SetTimer(hWnd, 1, 50, NULL);
-
- ThreeDInitialized = TRUE;
-
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
-
- return (TRUE);
- }
-
- /**************************************************************************/
- void
- OnSize(HWND hwnd, LPARAM lparam)
- {
- RwInt32 width;
- RwInt32 height;
-
- width = (RwInt32) LOWORD(lparam);
- height = (RwInt32) HIWORD(lparam);
- height = StatusAdjustHeight(hwnd, (int) height);
-
- /* Set the camera viewport to match the window's client area. */
-
- RwSetCameraViewport(pCamera, 0, 0, width, height);
- RwGetCameraViewport(pCamera, NULL, NULL, &width, &height);
-
- /* Maintain the view window at a 1:1 aspect ratio. */
-
- if ((width != 0) && (height != 0))
- {
- if (width >= height)
- RwSetCameraViewwindow(pCamera,
- CREAL(0.2),
- RMul(CREAL(0.2), RDiv(INT2REAL(height), INT2REAL(width))));
- else
- RwSetCameraViewwindow(pCamera,
- RMul(CREAL(0.2), RDiv(INT2REAL(width), INT2REAL(height))),
- CREAL(0.2));
- }
- ShowAppLeftStatus(hwnd, pCamera, "");
- ShowAppRightStatus(hwnd, pCamera, "");
- }
-
- long far PASCAL
- MainWndProc(HWND hWnd, WORD message, WPARAM wParam, LPARAM lParam)
- {
- HDC hDC;
- PAINTSTRUCT ps;
- static int x;
- static int y;
- static int bButtonDown = 0;
- MINMAXINFO FAR *minmaxinfo;
-
- switch (message)
- {
- case WM_COMMAND:
- if (LOWORD(lParam) == 0)
- HandleMenu(hWnd, wParam);
- return 0L;
-
- case (WM_SIZE):
- if (!ThreeDInitialized)
- break;
- OnSize(hWnd, lParam);
- break;
-
- case (WM_GETMINMAXINFO):
- minmaxinfo = (MINMAXINFO FAR *) MK_FP32((void *) lParam);
- minmaxinfo->ptMaxSize.x = MAXIMUM_WINDOW_WIDTH;
- minmaxinfo->ptMaxSize.y = MAXIMUM_WINDOW_HEIGHT;
- minmaxinfo->ptMaxTrackSize.x = MAXIMUM_WINDOW_WIDTH;
- minmaxinfo->ptMaxTrackSize.y = MAXIMUM_WINDOW_HEIGHT;
- break;
- case (WM_LBUTTONDOWN):
- if (!bButtonDown)
- {
- SetCapture(hWnd);
- ShowAppLeftStatus(hWnd, pCamera, "Pan and Tilt Camera");
- }
- else
- /* both must be down */
- {
- ShowAppLeftStatus(hWnd, pCamera, "Zoom Camera");
- }
- bButtonDown |= 1;
- x = LOWORD(lParam);
- y = HIWORD(lParam);
- break;
- case (WM_RBUTTONDOWN):
- if (!bButtonDown)
- {
- SetCapture(hWnd);
- ShowAppLeftStatus(hWnd, pCamera, "Pan and Zoom Camera");
- }
- else
- {
- ShowAppLeftStatus(hWnd, pCamera, "Zoom Camera");
- }
- bButtonDown |= 2;
- x = LOWORD(lParam);
- y = HIWORD(lParam);
- break;
- case (WM_MOUSEMOVE):
- if (bButtonDown)
- {
- int dx, dy;
-
- dx = ((short) LOWORD(lParam)) - x;
- dy = ((short) HIWORD(lParam)) - y;
- switch (bButtonDown)
- {
- case 1:
- {
- RwV3d at, up;
-
- RwPushScratchMatrix();
- RwGetCameraLookUp(pCamera, &up);
- RwRotateMatrix(RwScratchMatrix(), up.x, up.y, up.z, INT2REAL(-dx),
- rwREPLACE);
- RwGetCameraLookRight(pCamera, &at);
- RwRotateMatrix(RwScratchMatrix(), at.x, at.y, at.z, INT2REAL(-dy),
- rwPOSTCONCAT);
- RwTransformCamera(pCamera, RwScratchMatrix(), rwPOSTCONCAT);
- RwPopScratchMatrix();
- }
- break;
- case 2:
- RwVCMoveCamera(pCamera, CREAL(0.0), CREAL(0.0), RDiv(INT2REAL(-dy),
- CREAL(50.0)));
- RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0),
- INT2REAL(-dx), rwREPLACE);
- RwTransformCamera(pCamera, RwScratchMatrix(), rwPOSTCONCAT);
- break;
- case 3:
- RwVCMoveCamera(pCamera, CREAL(0.0), CREAL(0.0), RDiv(INT2REAL(-dy),
- CREAL(50.0)));
- break;
- }
- // InvalidateRect( hWnd, NULL, FALSE );
- x = (short) LOWORD(lParam);
- y = (short) HIWORD(lParam);
- }
- break;
- case (WM_LBUTTONUP):
- if (!ThreeDInitialized)
- break;
- bButtonDown &= ~1;
- if (!bButtonDown)
- {
- ReleaseCapture();
- ShowAppLeftStatus(hWnd, pCamera, "");
- }
- else
- ShowAppLeftStatus(hWnd, pCamera, "Pan and Zoom Camera");
- break;
- case (WM_RBUTTONUP):
- if (!ThreeDInitialized)
- break;
- bButtonDown &= ~2;
- if (!bButtonDown)
- {
- ShowAppLeftStatus(hWnd, pCamera, "");
- ReleaseCapture();
- }
- else
- {
- ShowAppLeftStatus(hWnd, pCamera, "Pan and Tilt Camera");
- }
- break;
-
- case (WM_PAINT):
- if (!ThreeDInitialized)
- break;
- hDC = BeginPaint(hWnd, &ps);
- RwBeginCameraUpdate(pCamera, (void *) (DWORD) hWnd);
- RwInvalidateCameraViewport(pCamera);
- RwClearCameraViewport(pCamera);
- RwRenderScene(scene);
- RwEndCameraUpdate(pCamera);
- RwShowCameraImage(pCamera, (void *) (DWORD) hDC);
- EndPaint(hWnd, &ps);
- ShowAppLeftStatus(hWnd, pCamera, "");
- ShowAppRightStatus(hWnd, pCamera, "");
- break;
- case (WM_CHAR):
- if (!ThreeDInitialized)
- break;
- if (wParam >= '0' && wParam <= '9' && wParam < numthings + '0')
- {
- follow = wParam - '0';
- }
- else if ((wParam == 't') || (wParam == 'T'))
- {
- DWORD t, u;
- int i;
- char szBuf[255];
-
- u = GetTickCount();
- while (u == (t = GetTickCount()));
- for (i = 0; i < 150; i++)
- {
- RwV3d vec;
-
- collisions(things, numthings);
- RwGetCameraLookUp(pCamera, &vec);
- vec.x = RDiv(vec.x, CREAL(-200));
- vec.y = RDiv(vec.y, CREAL(-200));
- vec.z = RDiv(vec.z, CREAL(-200));
- gravitatethings(things, numthings, &vec);
- if (1)
- {
- RwGetClumpOrigin(things[follow].geometry, &vec);
- RwPointCamera(pCamera, vec.x, vec.y, vec.z);
- RwSetCameraLookUp(pCamera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
- }
- RwBeginCameraUpdate(pCamera, (void *) (DWORD) hWnd);
- RwClearCameraViewport(pCamera);
- RwRenderScene(scene);
- hDC = GetDC(hWnd);
- RwEndCameraUpdate(pCamera);
- RwShowCameraImage(pCamera, (void *) (DWORD) hDC);
- ReleaseDC(hWnd, hDC);
- }
- u = GetTickCount();
- sprintf(szBuf, "Winsim took %lu ms for %d frames\n", u - t, i);
- MessageBox(hWnd, szBuf, "", MB_OK);
- }
- break;
- case (WM_TIMER):
- if (!ThreeDInitialized)
- break;
- if (1)
- {
- RwV3d vec;
-
- collisions(things, numthings);
- RwGetCameraLookUp(pCamera, &vec);
- vec.x = RDiv(vec.x, CREAL(-200));
- vec.y = RDiv(vec.y, CREAL(-200));
- vec.z = RDiv(vec.z, CREAL(-200));
- gravitatethings(things, numthings, &vec);
- if (!bButtonDown)
- {
- RwGetClumpOrigin(things[follow].geometry, &vec);
- RwPointCamera(pCamera, vec.x, vec.y, vec.z);
- RwSetCameraLookUp(pCamera, CREAL(0.0), CREAL(1.0), CREAL(0.0));
- }
- RwBeginCameraUpdate(pCamera, (void *) (DWORD) hWnd);
- RwClearCameraViewport(pCamera);
- RwRenderScene(scene);
- hDC = GetDC(hWnd);
- RwEndCameraUpdate(pCamera);
- RwShowCameraImage(pCamera, (void *) (DWORD) hDC);
- ReleaseDC(hWnd, hDC);
- }
- break;
- case (WM_DESTROY):
- KillTimer(hWnd, 1);
- PostQuitMessage(0);
- break;
- default:
- return (DefWindowProc(hWnd, message, wParam, lParam));
- }
-
- return (0L);
- }
-
- int PASCAL
- WinMain(HANDLE hInst, HANDLE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
- {
- MSG msg;
-
- if (!InitApplication(hInst))
- {
- MessageBox(NULL, "n-Body simulation is already running...",
- ERROR_DIALOG_TITLE, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
- return (FALSE);
- }
-
- if (!InitInstance(hInst, nCmdShow))
- {
- return (FALSE);
- }
-
- while (GetMessage(&msg, (HWND) NULL, (UINT) NULL, (UINT) NULL))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- RwDestroyCamera(pCamera);
- RwDestroyLight(pLight);
- while (numthings--)
- RwDestroyClump(things[numthings].geometry);
- RwDestroyScene(scene);
-
- RwClose();
-
- UnregisterClass("RwNBodyWndClass", hInst);
- return (msg.wParam);
- }
-