mirror of
https://github.com/aap/librw.git
synced 2025-12-18 16:39:51 +00:00
wrote basic skeleton; clumpview
This commit is contained in:
134
tools/clumpview/camera.cpp
Normal file
134
tools/clumpview/camera.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include <rw.h>
|
||||
|
||||
#define PI 3.14159265359f
|
||||
#include "camera.h"
|
||||
|
||||
using rw::Quat;
|
||||
using rw::V3d;
|
||||
|
||||
void
|
||||
Camera::update(void)
|
||||
{
|
||||
if(m_rwcam){
|
||||
m_rwcam->nearPlane = m_near;
|
||||
m_rwcam->farPlane = m_far;
|
||||
m_rwcam->setFOV(m_fov, m_aspectRatio);
|
||||
|
||||
rw::Frame *f = m_rwcam->getFrame();
|
||||
if(f){
|
||||
V3d forward = normalize(sub(m_target, m_position));
|
||||
V3d left = normalize(cross(m_up, forward));
|
||||
V3d nup = cross(forward, left);
|
||||
f->matrix.right = left; // lol
|
||||
f->matrix.up = nup;
|
||||
f->matrix.at = forward;
|
||||
f->matrix.pos = m_position;
|
||||
f->matrix.optimize();
|
||||
f->updateObjects();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Camera::setTarget(V3d target)
|
||||
{
|
||||
m_position = sub(m_position, sub(m_target, target));
|
||||
m_target = target;
|
||||
}
|
||||
|
||||
float
|
||||
Camera::getHeading(void)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
float a = atan2(dir.y, dir.x)-PI/2.0f;
|
||||
return m_localup.z < 0.0f ? a-PI : a;
|
||||
}
|
||||
|
||||
void
|
||||
Camera::turn(float yaw, float pitch)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
Quat r = Quat::rotation(yaw, rw::makeV3d(0.0f, 0.0f, 1.0f));
|
||||
dir = rotate(dir, r);
|
||||
m_localup = rotate(m_localup, r);
|
||||
|
||||
V3d right = normalize(cross(dir, m_localup));
|
||||
r = Quat::rotation(pitch, right);
|
||||
dir = rotate(dir, r);
|
||||
m_localup = normalize(cross(right, dir));
|
||||
if(m_localup.z >= 0.0) m_up.z = 1.0;
|
||||
else m_up.z = -1.0f;
|
||||
|
||||
m_target = add(m_position, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::orbit(float yaw, float pitch)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
Quat r = Quat::rotation(yaw, rw::makeV3d(0.0f, 0.0f, 1.0f));
|
||||
dir = rotate(dir, r);
|
||||
m_localup = rotate(m_localup, r);
|
||||
|
||||
V3d right = normalize(cross(dir, m_localup));
|
||||
r = Quat::rotation(-pitch, right);
|
||||
dir = rotate(dir, r);
|
||||
m_localup = normalize(cross(right, dir));
|
||||
if(m_localup.z >= 0.0) m_up.z = 1.0;
|
||||
else m_up.z = -1.0f;
|
||||
|
||||
m_position = sub(m_target, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::dolly(float dist)
|
||||
{
|
||||
V3d dir = setlength(sub(m_target, m_position), dist);
|
||||
m_position = add(m_position, dir);
|
||||
m_target = add(m_target, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::zoom(float dist)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
float curdist = length(dir);
|
||||
if(dist >= curdist)
|
||||
dist = curdist-0.01f;
|
||||
dir = setlength(dir, dist);
|
||||
m_position = add(m_position, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::pan(float x, float y)
|
||||
{
|
||||
V3d dir = normalize(sub(m_target, m_position));
|
||||
V3d right = normalize(cross(dir, m_up));
|
||||
V3d localup = normalize(cross(right, dir));
|
||||
dir = add(scale(right, x), scale(localup, y));
|
||||
m_position = add(m_position, dir);
|
||||
m_target = add(m_target, dir);
|
||||
}
|
||||
|
||||
float
|
||||
Camera::distanceTo(V3d v)
|
||||
{
|
||||
return length(sub(m_position, v));
|
||||
}
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
m_position.set(0.0f, 6.0f, 0.0f);
|
||||
m_target.set(0.0f, 0.0f, 0.0f);
|
||||
m_up.set(0.0f, 0.0f, 1.0f);
|
||||
m_localup = m_up;
|
||||
m_fov = 70.0f;
|
||||
m_aspectRatio = 1.0f;
|
||||
m_near = 0.1f;
|
||||
m_far = 100.0f;
|
||||
m_rwcam = NULL;
|
||||
}
|
||||
|
||||
26
tools/clumpview/camera.h
Normal file
26
tools/clumpview/camera.h
Normal file
@@ -0,0 +1,26 @@
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
rw::Camera *m_rwcam;
|
||||
rw::V3d m_position;
|
||||
rw::V3d m_target;
|
||||
rw::V3d m_up;
|
||||
rw::V3d m_localup;
|
||||
|
||||
float m_fov, m_aspectRatio;
|
||||
float m_near, m_far;
|
||||
|
||||
|
||||
void setTarget(rw::V3d target);
|
||||
float getHeading(void);
|
||||
|
||||
void turn(float yaw, float pitch);
|
||||
void orbit(float yaw, float pitch);
|
||||
void dolly(float dist);
|
||||
void zoom(float dist);
|
||||
void pan(float x, float y);
|
||||
|
||||
void update(void);
|
||||
float distanceTo(rw::V3d v);
|
||||
Camera(void);
|
||||
};
|
||||
181
tools/clumpview/main.cpp
Normal file
181
tools/clumpview/main.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include "camera.h"
|
||||
#include <assert.h>
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
Camera *camera;
|
||||
rw::Clump *clump;
|
||||
rw::World *world;
|
||||
rw::EngineStartParams engineStartParams;
|
||||
|
||||
void
|
||||
Init(void)
|
||||
{
|
||||
sk::globals.windowtitle = "Clump viewer";
|
||||
sk::globals.width = 640;
|
||||
sk::globals.height = 480;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InitRW(void)
|
||||
{
|
||||
// rw::platform = rw::PLATFORM_D3D8;
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
char *filename = "teapot.dff";
|
||||
rw::StreamFile in;
|
||||
if(in.open(filename, "rb") == NULL){
|
||||
printf("couldn't open file\n");
|
||||
return false;
|
||||
}
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
assert(clump);
|
||||
in.close();
|
||||
|
||||
clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
||||
|
||||
FORLIST(lnk, clump->atomics){
|
||||
rw::Atomic *a = rw::Atomic::fromClump(lnk);
|
||||
if(a->pipeline && a->pipeline->platform != rw::platform)
|
||||
a->pipeline = NULL;
|
||||
}
|
||||
|
||||
|
||||
world = rw::World::create();
|
||||
|
||||
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
||||
ambient->setColor(0.2f, 0.2f, 0.2f);
|
||||
world->addLight(ambient);
|
||||
|
||||
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
|
||||
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
direct->setColor(0.8f, 0.8f, 0.8f);
|
||||
direct->setFrame(rw::Frame::create());
|
||||
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
||||
world->addLight(direct);
|
||||
|
||||
camera = new Camera;
|
||||
camera->m_rwcam = rw::Camera::create();
|
||||
camera->m_rwcam->setFrame(rw::Frame::create());
|
||||
camera->m_aspectRatio = 640.0f/480.0f;
|
||||
camera->m_near = 0.1f;
|
||||
camera->m_far = 450.0f;
|
||||
camera->m_target.set(0.0f, 0.0f, 0.0f);
|
||||
camera->m_position.set(0.0f, -10.0f, 0.0f);
|
||||
// camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
|
||||
// camera->setPosition(Vec3(0.0f, -70.0f, 0.0f));
|
||||
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||
camera->update();
|
||||
|
||||
world->addCamera(camera->m_rwcam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Draw(float timeDelta)
|
||||
{
|
||||
static rw::RGBA clearcol = { 0x80, 0x80, 0x80, 0xFF };
|
||||
camera->m_rwcam->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
camera->update();
|
||||
camera->m_rwcam->beginUpdate();
|
||||
|
||||
clump->render();
|
||||
|
||||
camera->m_rwcam->endUpdate();
|
||||
camera->m_rwcam->showRaster();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case 'W':
|
||||
camera->orbit(0.0f, 0.1f);
|
||||
break;
|
||||
case 'S':
|
||||
camera->orbit(0.0f, -0.1f);
|
||||
break;
|
||||
case 'A':
|
||||
camera->orbit(-0.1f, 0.0f);
|
||||
break;
|
||||
case 'D':
|
||||
camera->orbit(0.1f, 0.0f);
|
||||
break;
|
||||
case sk::KEY_UP:
|
||||
camera->turn(0.0f, 0.1f);
|
||||
break;
|
||||
case sk::KEY_DOWN:
|
||||
camera->turn(0.0f, -0.1f);
|
||||
break;
|
||||
case sk::KEY_LEFT:
|
||||
camera->turn(0.1f, 0.0f);
|
||||
break;
|
||||
case sk::KEY_RIGHT:
|
||||
camera->turn(-0.1f, 0.0f);
|
||||
break;
|
||||
case 'R':
|
||||
camera->zoom(0.1f);
|
||||
break;
|
||||
case 'F':
|
||||
camera->zoom(-0.1f);
|
||||
break;
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Init();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return ::InitRW() ? EVENTPROCESSED : EVENTERROR;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case IDLE:
|
||||
Draw(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
BIN
tools/clumpview/teapot.dff
Normal file
BIN
tools/clumpview/teapot.dff
Normal file
Binary file not shown.
Reference in New Issue
Block a user