mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
Started experimenting with Bullet
git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@46 ea6a568a-9f4f-0410-981a-c910a81bb256
This commit is contained in:
parent
4d37d36d1e
commit
1cfaeeb8fc
14 changed files with 371 additions and 53 deletions
23
Makefile
23
Makefile
|
@ -8,14 +8,18 @@ DMD=gdmd -version=Posix
|
|||
# Some extra flags for niftool and bsatool
|
||||
NIFFLAGS=-debug=warnstd -debug=check -debug=statecheck -debug=strict -debug=verbose
|
||||
|
||||
# Compiler settings for Ogre + OIS. Change as needed.
|
||||
# Compiler settings for Ogre + OIS.
|
||||
CF_OIS=$(shell pkg-config --cflags OGRE OIS)
|
||||
OGCC=$(CXX) $(CXXFLAGS) $(CF_OIS)
|
||||
|
||||
# Compiler settings for ffmpeg. Change as needed.
|
||||
# Compiler settings for ffmpeg.
|
||||
CF_FFMPEG=$(shell pkg-config --cflags libavcodec libavformat)
|
||||
AVGCC=$(CXX) $(CXXFLAGS) $(CF_FFMPEG)
|
||||
|
||||
# Settings for Bullet
|
||||
CF_BULLET=-Iinclude/bullet
|
||||
BGCC=$(CXX) $(CXXFLAGS) $(CF_BULLET)
|
||||
|
||||
# Ogre C++ files, on the form ogre/cpp_X.cpp. Only the first file is
|
||||
# passed to the compiler, the rest are dependencies.
|
||||
ogre_cpp=ogre framelistener interface overlay bsaarchive
|
||||
|
@ -23,10 +27,14 @@ ogre_cpp=ogre framelistener interface overlay bsaarchive
|
|||
# FFmpeg files, in the form sound/cpp_X.cpp.
|
||||
avcodec_cpp=avcodec
|
||||
|
||||
## No modifications should be required below this line. ##
|
||||
# Bullet cpp files
|
||||
bullet_cpp=bullet
|
||||
|
||||
#### No modifications should be required below this line. ####
|
||||
|
||||
ogre_cpp_files=$(ogre_cpp:%=ogre/cpp_%.cpp)
|
||||
avcodec_cpp_files=$(avcodec_cpp:%=sound/cpp_%.cpp)
|
||||
bullet_cpp_files=$(bullet_cpp:%=bullet/cpp_%.cpp)
|
||||
|
||||
# All object files needed by openmw and esmtool
|
||||
src := $(wildcard */*.d)
|
||||
|
@ -47,7 +55,7 @@ obj_nif := $(src_nif:%.d=nifobjs/%.o)
|
|||
all: openmw esmtool niftool bsatool bored
|
||||
|
||||
# Only build C++ sources. Used when building from DSSS.
|
||||
cpp: cpp_ogre.o cpp_avcodec.o
|
||||
cpp: cpp_ogre.o cpp_avcodec.o cpp_bullet.o
|
||||
|
||||
cpp_ogre.o: $(ogre_cpp_files)
|
||||
$(OGCC) -c $<
|
||||
|
@ -55,6 +63,9 @@ cpp_ogre.o: $(ogre_cpp_files)
|
|||
cpp_avcodec.o: $(avcodec_cpp_files)
|
||||
$(AVGCC) -c $<
|
||||
|
||||
cpp_bullet.o: $(bullet_cpp_files)
|
||||
$(BGCC) -c $<
|
||||
|
||||
objs/%.o: %.d
|
||||
dirname $@ | xargs mkdir -p
|
||||
$(DMD) -c $< -of$@
|
||||
|
@ -63,8 +74,8 @@ nifobjs/%.o: %.d
|
|||
dirname $@ | xargs mkdir -p
|
||||
$(DMD) $(NIFFLAGS) -c $< -of$@
|
||||
|
||||
openmw: openmw.d cpp_ogre.o cpp_avcodec.o $(obj)
|
||||
$(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat
|
||||
openmw: openmw.d cpp_ogre.o cpp_avcodec.o cpp_bullet.o $(obj)
|
||||
$(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat bullet/libBulletDynamics.a bullet/libBulletCollision.a bullet/libLinearMath.a
|
||||
|
||||
esmtool: esmtool.d cpp_ogre.o cpp_avcodec.o $(obj)
|
||||
$(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat
|
||||
|
|
43
bullet/bindings.d
Normal file
43
bullet/bindings.d
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.snaptoad.com/
|
||||
|
||||
This file (bindings.d) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
module bullet.bindings;
|
||||
|
||||
/*
|
||||
* This module is the interface between D and the C++ code that
|
||||
* handles Bullet.
|
||||
*/
|
||||
|
||||
extern(C):
|
||||
|
||||
// Initialize the dynamic world. Returns non-zero if an error occurs.
|
||||
int cpp_initBullet();
|
||||
void cpp_timeStep(float delta);
|
||||
void cpp_cleanupBullet();
|
||||
|
||||
// Insert a debug collision object
|
||||
void cpp_insertBox(float x, float y, float z);
|
||||
|
||||
// Move the player's collision shape
|
||||
int cpp_movePlayerCollision(float x, float y, float z,
|
||||
float dx, float dy, float dz);
|
11
bullet/bullet.d
Normal file
11
bullet/bullet.d
Normal file
|
@ -0,0 +1,11 @@
|
|||
module bullet.bullet;
|
||||
|
||||
import bullet.bindings;
|
||||
|
||||
void initBullet()
|
||||
{
|
||||
if(cpp_initBullet())
|
||||
throw new Exception("Bullet setup failed");
|
||||
}
|
||||
|
||||
void cleanupBullet() { cpp_cleanupBullet(); }
|
196
bullet/cpp_bullet.cpp
Normal file
196
bullet/cpp_bullet.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
#include "btBulletCollisionCommon.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||
btCollisionDispatcher *m_dispatcher;
|
||||
btBroadphaseInterface *m_broadphase;
|
||||
//btSequentialImpulseConstraintSolver* m_solver;
|
||||
//btDynamicsWorld *m_dynamicsWorld;
|
||||
btCollisionWorld *m_collisionWorld;
|
||||
|
||||
//btCollisionObject* m_playerObject;
|
||||
btConvexShape *playerShape;
|
||||
|
||||
extern "C" int32_t cpp_initBullet()
|
||||
{
|
||||
// Set up basic objects
|
||||
m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
m_broadphase = new btDbvtBroadphase();
|
||||
m_collisionWorld =
|
||||
new btCollisionWorld(m_dispatcher, m_broadphase,
|
||||
m_collisionConfiguration);
|
||||
|
||||
/*m_solver = new btSequentialImpulseConstraintSolver;
|
||||
m_dynamicsWorld =
|
||||
new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase,
|
||||
m_solver, m_collisionConfiguration);
|
||||
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
|
||||
*/
|
||||
|
||||
// Create player collision object
|
||||
//playerShape = new btCylinderShape(btVector3(50, 50, 50));
|
||||
playerShape = new btSphereShape(50);
|
||||
|
||||
/*
|
||||
m_playerObject = new btCollisionObject ();
|
||||
m_playerObject->setCollisionShape (m_shape);
|
||||
m_playerObject->setCollisionFlags (btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
*/
|
||||
|
||||
/*
|
||||
// Dynamic shapes:
|
||||
|
||||
// Re-using the same collision is better for memory usage and
|
||||
// performance.
|
||||
|
||||
btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
|
||||
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
|
||||
//m_collisionShapes.push_back(colShape);
|
||||
|
||||
// Create Dynamic Objects
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
|
||||
mass = 1.f;
|
||||
|
||||
colShape->calculateLocalInertia(mass,localInertia);
|
||||
|
||||
///create 125 (5x5x5) dynamic objects
|
||||
#define ARRAY_SIZE_X 5
|
||||
#define ARRAY_SIZE_Y 5
|
||||
#define ARRAY_SIZE_Z 5
|
||||
|
||||
#define START_POS_X -5
|
||||
#define START_POS_Y -5
|
||||
#define START_POS_Z -3
|
||||
|
||||
float start_x = START_POS_X - ARRAY_SIZE_X/2;
|
||||
float start_y = START_POS_Y;
|
||||
float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
|
||||
|
||||
for (int k=0;k<ARRAY_SIZE_Y;k++)
|
||||
for (int i=0;i<ARRAY_SIZE_X;i++)
|
||||
for(int j = 0;j<ARRAY_SIZE_Z;j++)
|
||||
{
|
||||
startTransform.setOrigin(btVector3(2.0*i + start_x,
|
||||
10+2.0*k + start_y,
|
||||
2.0*j + start_z));
|
||||
|
||||
btDefaultMotionState* myMotionState =
|
||||
new btDefaultMotionState(startTransform);
|
||||
|
||||
btRigidBody::btRigidBodyConstructionInfo
|
||||
rbInfo(mass,myMotionState,colShape,localInertia);
|
||||
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
body->setActivationState(ISLAND_SLEEPING);
|
||||
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
body->setActivationState(ISLAND_SLEEPING);
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int32_t cpp_movePlayerCollision(float x, float y, float z,
|
||||
float dx, float dy, float dz)
|
||||
{
|
||||
btTransform start, end;
|
||||
start.setIdentity();
|
||||
end.setIdentity();
|
||||
|
||||
// The sweep test moves the shape from the old position to the
|
||||
// new. The 0.1 offset in one of the coordinates is to make sure a
|
||||
// sweep is performed even when the player does not move.
|
||||
start.setOrigin(btVector3(x, y, z));
|
||||
end.setOrigin(btVector3(x+dx,y+dy,z+dz));
|
||||
|
||||
btCollisionWorld::ClosestConvexResultCallback cb(btVector3(0,0,0),
|
||||
btVector3(0,0,0));
|
||||
|
||||
m_collisionWorld->convexSweepTest(playerShape, start, end, cb);
|
||||
|
||||
if(cb.hasHit()) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
extern "C" void cpp_insertBox(float x, float y, float z)
|
||||
{
|
||||
btCollisionShape* groundShape =
|
||||
new btSphereShape(50);
|
||||
//new btBoxShape(btVector3(100,100,100));
|
||||
|
||||
btTransform groundTransform;
|
||||
groundTransform.setIdentity();
|
||||
groundTransform.setOrigin(btVector3(x,y,z));
|
||||
|
||||
btCollisionObject *obj = new btCollisionObject;
|
||||
obj->setCollisionShape(groundShape);
|
||||
obj->setWorldTransform(groundTransform);
|
||||
|
||||
m_collisionWorld->addCollisionObject(obj);
|
||||
|
||||
/*
|
||||
m_collisionWorld->addCollisionObject(obj,
|
||||
btBroadphaseProxy::DebrisFilter, // ??
|
||||
btBroadphaseProxy::StaticFilter); // Only static objects
|
||||
|
||||
/*
|
||||
btDefaultMotionState* myMotionState =
|
||||
new btDefaultMotionState(groundTransform);
|
||||
|
||||
btRigidBody::btRigidBodyConstructionInfo
|
||||
rbInfo(0, myMotionState, groundShape, btVector3(0,0,0));
|
||||
|
||||
btRigidBody* body = new btRigidBody(rbInfo);
|
||||
|
||||
// Add the body to the dynamics world
|
||||
m_dynamicsWorld->addRigidBody(body);
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
extern "C" void cpp_timeStep(float delta)
|
||||
{
|
||||
// TODO: Find what unit Bullet uses here
|
||||
m_dynamicsWorld->stepSimulation(delta / 1000.f);
|
||||
}
|
||||
*/
|
||||
|
||||
// Cleanup in the reverse order of creation/initialization
|
||||
extern "C" void cpp_cleanupBullet()
|
||||
{
|
||||
// Remove the rigidbodies from the dynamics world and delete them
|
||||
for (int i=m_collisionWorld->getNumCollisionObjects()-1; i>=0 ;i--)
|
||||
{
|
||||
btCollisionObject* obj = m_collisionWorld->getCollisionObjectArray()[i];
|
||||
/*
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
|
||||
if (body && body->getMotionState())
|
||||
delete body->getMotionState();
|
||||
*/
|
||||
|
||||
m_collisionWorld->removeCollisionObject( obj );
|
||||
delete obj;
|
||||
}
|
||||
|
||||
// Delete collision shapes
|
||||
/*
|
||||
for (int j=0;j<m_collisionShapes.size();j++)
|
||||
{
|
||||
btCollisionShape* shape = m_collisionShapes[j];
|
||||
delete shape;
|
||||
}
|
||||
*/
|
||||
|
||||
delete m_collisionWorld;
|
||||
//delete m_solver;
|
||||
delete m_broadphase;
|
||||
delete m_dispatcher;
|
||||
delete m_collisionConfiguration;
|
||||
}
|
|
@ -334,8 +334,6 @@ struct ResourceManager
|
|||
assert(ti.bsaFile == -1);
|
||||
}
|
||||
|
||||
ti.ml = null;
|
||||
|
||||
textureLookup[ti.name] = ti;
|
||||
|
||||
return ti;
|
||||
|
@ -447,7 +445,6 @@ struct TextureResource
|
|||
int bsaFile; // If set to -1, the file is in the file system
|
||||
int bsaIndex;
|
||||
char[] type; // Texture format, eg "tga" or "dds";
|
||||
ManualLoader ml;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -460,11 +457,13 @@ struct TextureResource
|
|||
return bsaIndex == -1;
|
||||
}
|
||||
|
||||
/*KILLME
|
||||
// Returns true if resource is loaded
|
||||
bool isLoaded()
|
||||
{
|
||||
return ml != null;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// OLD STUFF
|
||||
|
@ -495,11 +494,5 @@ struct TextureResource
|
|||
|
||||
writefln(" Done\n");
|
||||
}
|
||||
|
||||
void killBSAs()
|
||||
{
|
||||
foreach(BSAFile f; archives)
|
||||
delete f;
|
||||
}
|
||||
}
|
||||
+/
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
[openmw.d]
|
||||
# Add libraries and the two C++ object files
|
||||
buildflags = -llOgreMain -llopenal -llOIS -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o
|
||||
buildflags = -llOgreMain -llopenal -llOIS -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o cpp_bullet.o bullet/libBulletDynamics.a bullet/libBulletCollision.a bullet/libLinearMath.a
|
||||
|
||||
# Make sure the C++ object files are built first
|
||||
version(Windows) {
|
||||
|
@ -34,7 +34,7 @@ prebuild += dsss clean niftool
|
|||
[esmtool.d]
|
||||
# Because of interdepencies between the ESM code and the resource
|
||||
# manager, we have to include all the C++ stuff.
|
||||
buildflags = -llOgreMain -llopenal -llOIS -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o
|
||||
buildflags = -llOgreMain -llopenal -llOIS -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o cpp_bullet.o bullet/libBulletDynamics.a bullet/libBulletCollision.a bullet/libLinearMath.a
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -557,6 +557,13 @@ struct TES3File
|
|||
file.seekCur(leftSub);
|
||||
}
|
||||
|
||||
// Check the name and size before skipping
|
||||
void skipHNSub(char[] name, uint size)
|
||||
{
|
||||
getSubNameIs(name);
|
||||
skipHSubSize(size);
|
||||
}
|
||||
|
||||
// These read an entire sub-record, including the header. They also
|
||||
// adjust and check leftSub and leftRecord variables through calling
|
||||
// getSubHeader().
|
||||
|
|
|
@ -123,9 +123,9 @@ struct ExteriorCell
|
|||
|
||||
struct ExtCellHash
|
||||
{
|
||||
// This is a pretty good hash, gives no collisions at all for
|
||||
// Morrowind.esm and a table size of 2048, and very few collisions
|
||||
// overall. Not that it matters of course.
|
||||
// This is a pretty good hash, gives no collisions for all of
|
||||
// Morrowind.esm when the table size is 2048, and it gives very few
|
||||
// collisions overall. Not that it matters that much.
|
||||
static uint hash(uint val)
|
||||
{
|
||||
uint res = cast(ushort)val;
|
||||
|
@ -304,8 +304,7 @@ struct Land
|
|||
// Save file position
|
||||
getContext(context);
|
||||
|
||||
// TODO: We don't decode these yet. Se ESLand.h from
|
||||
// Morrowindremake for a lot of hints.
|
||||
// Skip these here. Load the actual data when the cell is loaded.
|
||||
if(isNextSub("VNML")) skipHSubSize(12675);
|
||||
if(isNextSub("VHGT")) skipHSubSize(4232);
|
||||
if(isNextSub("WNAM")) skipHSubSize(81);
|
||||
|
@ -342,7 +341,8 @@ struct PathGrid
|
|||
assert(state == LoadState.Unloaded);
|
||||
|
||||
readHNExact(&data, data.sizeof, "DATA");
|
||||
getHNString("NAME"); // Cell name, we don't really need it.
|
||||
getHNString("NAME"); // Cell name, we don't really need it so just
|
||||
// ignore it.
|
||||
|
||||
// Remember this file position
|
||||
getContext(context);
|
||||
|
@ -352,7 +352,7 @@ struct PathGrid
|
|||
{
|
||||
int size = skipHSub();
|
||||
if(size != 16*data.s2)
|
||||
fail("Path grid table size");
|
||||
fail("Path grid table size mismatch");
|
||||
}
|
||||
|
||||
// Size varies. Path grid chances? Connections? Multiples of 4
|
||||
|
|
|
@ -33,6 +33,8 @@ import core.config;
|
|||
import scene.soundlist;
|
||||
import scene.player;
|
||||
|
||||
import bullet.bindings;
|
||||
|
||||
import ogre.bindings;
|
||||
|
||||
import input.keys;
|
||||
|
@ -246,6 +248,10 @@ void initializeInput()
|
|||
{
|
||||
cpp_moveCamera(position[0], position[1], position[2],
|
||||
rotation[0], rotation[1], rotation[2]);
|
||||
|
||||
// Insert a collision box close to the player
|
||||
cpp_insertBox(position[0], position[1]+500, position[2]);
|
||||
cpp_drawBox(position[0], position[1]+500, position[2]);
|
||||
}
|
||||
|
||||
// TODO/FIXME: This should have been in config, but DMD's module
|
||||
|
@ -294,29 +300,41 @@ extern(C) int d_frameStarted(float time)
|
|||
if(pause) return 1;
|
||||
|
||||
const float moveSpeed = 900;
|
||||
float speed = moveSpeed * time;
|
||||
|
||||
// Check if the movement keys are pressed
|
||||
float moveX = 0, moveY = 0, moveZ = 0;
|
||||
float x, y, z;
|
||||
|
||||
if(isPressed(Keys.MoveLeft)) moveX -= moveSpeed;
|
||||
if(isPressed(Keys.MoveRight)) moveX += moveSpeed;
|
||||
if(isPressed(Keys.MoveForward)) moveZ -= moveSpeed;
|
||||
if(isPressed(Keys.MoveBackward)) moveZ += moveSpeed;
|
||||
if(isPressed(Keys.MoveUp)) moveY += moveSpeed;
|
||||
if(isPressed(Keys.MoveDown)) moveY -= moveSpeed;
|
||||
if(isPressed(Keys.MoveLeft)) moveX -= speed;
|
||||
if(isPressed(Keys.MoveRight)) moveX += speed;
|
||||
if(isPressed(Keys.MoveForward)) moveZ -= speed;
|
||||
if(isPressed(Keys.MoveBackward)) moveZ += speed;
|
||||
if(isPressed(Keys.MoveUp)) moveY += speed;
|
||||
if(isPressed(Keys.MoveDown)) moveY -= speed;
|
||||
|
||||
// Move camera. We only support "ghost-mode" at the moment, so we
|
||||
// move without physics or collision detection.
|
||||
cpp_moveCameraRel(moveX*time, moveY*time, moveZ*time);
|
||||
// Move the player. This is a temporary hack, we should do this more
|
||||
// efficiently in C++.
|
||||
if(moveX != 0 || moveY !=0 || moveZ != 0)
|
||||
{
|
||||
cpp_moveCameraRel(moveX, moveY, moveZ);
|
||||
cpp_getCameraPos(&x, &y, &z);
|
||||
bool nw = cpp_movePlayerCollision(x, y, z, moveX, moveY, moveZ) != 0;
|
||||
|
||||
if(nw != collides)
|
||||
{
|
||||
if(nw) writefln("Entered shape");
|
||||
else writefln("Left shape");
|
||||
collides = nw;
|
||||
}
|
||||
}
|
||||
|
||||
sndCumTime += time;
|
||||
if(sndCumTime > sndRefresh)
|
||||
{
|
||||
float x, y, z;
|
||||
float fx, fy, fz;
|
||||
float ux, uy, uz;
|
||||
|
||||
cpp_getCameraPos(&x, &y, &z);
|
||||
cpp_getCameraOrientation(&fx, &fy, &fz, &ux, &uy, &uz);
|
||||
|
||||
soundScene.update(x,y,z,fx,fy,fz,ux,uy,uz);
|
||||
|
@ -326,3 +344,4 @@ extern(C) int d_frameStarted(float time)
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool collides = false;
|
||||
|
|
|
@ -45,9 +45,6 @@ import core.resource;
|
|||
// these directly in D code, only pass them back to the C++ code.
|
||||
typedef void* NodePtr;
|
||||
|
||||
// Pointer to a manual loader class in C++.
|
||||
typedef void* ManualLoader;
|
||||
|
||||
extern(C):
|
||||
|
||||
// Do engine configuration. Returns 0 if we should continue, 1 if
|
||||
|
@ -152,3 +149,6 @@ void cpp_moveCameraRel(float x, float y, float z);
|
|||
|
||||
// Do some debug action. Check the menu for today's specials!
|
||||
void cpp_debug(int i);
|
||||
|
||||
// Insert a 100x100x100 axis-aligned cube at x,y,z
|
||||
void cpp_drawBox(float x, float y, float z);
|
||||
|
|
|
@ -146,11 +146,13 @@ extern "C" void cpp_getCameraOrientation(float *fx, float *fy, float *fz,
|
|||
*uz = up[1];
|
||||
}
|
||||
|
||||
// Move and rotate camera in place. Transforms Morrowind coordinates
|
||||
// to OGRE coordinates.
|
||||
// Move and rotate camera in place.
|
||||
extern "C" void cpp_moveCamera(float x, float y, float z,
|
||||
float r1, float r2, float r3)
|
||||
{
|
||||
// Transforms Morrowind coordinates to OGRE coordinates. The camera
|
||||
// is not affected by the rotation of the root node, so we must
|
||||
// transform this manually.
|
||||
mCamera->setPosition(Vector3(x,z,-y));
|
||||
|
||||
// Rotation is probably not correct, but for now I have no reference
|
||||
|
|
|
@ -56,3 +56,23 @@ SceneNode *root;
|
|||
#include "cpp_bsaarchive.cpp"
|
||||
#include "cpp_interface.cpp"
|
||||
#include "cpp_overlay.cpp"
|
||||
|
||||
// Testing
|
||||
extern "C" void cpp_drawBox(float x, float y, float z)
|
||||
{
|
||||
// Create a plane aligned with the xy-plane.
|
||||
/*
|
||||
MeshManager::getSingleton().createPlane("box1",
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
Plane(Vector3::UNIT_X, 0),
|
||||
100,100);
|
||||
Entity *ent = mSceneMgr->createEntity( "box", "box1" );
|
||||
*/
|
||||
|
||||
Entity *ent = mSceneMgr->createEntity( "box", SceneManager::PT_SPHERE);
|
||||
ent->setCastShadows(false);
|
||||
SceneNode *nd = root->createChildSceneNode();
|
||||
nd->attachObject(ent);
|
||||
//nd->setScale(0.5, 0.5, 0.5);
|
||||
nd->setPosition(x,y,z);
|
||||
}
|
||||
|
|
9
openmw.d
9
openmw.d
|
@ -31,6 +31,8 @@ import std.file;
|
|||
import ogre.ogre;
|
||||
import ogre.bindings;
|
||||
|
||||
import bullet.bullet;
|
||||
|
||||
import scene.celldata;
|
||||
import scene.soundlist;
|
||||
|
||||
|
@ -219,10 +221,13 @@ void main(char[][] args)
|
|||
{
|
||||
// Warm up OGRE
|
||||
setupOgre();
|
||||
|
||||
// Clean up ogre when we're finished.
|
||||
scope(exit) cleanupOgre();
|
||||
|
||||
// Set up Bullet
|
||||
initBullet();
|
||||
scope(exit) cleanupBullet();
|
||||
|
||||
|
||||
if(cd.inCell)
|
||||
{
|
||||
setAmbient(cd.ambi.ambient, cd.ambi.sunlight,
|
||||
|
|
|
@ -39,7 +39,8 @@ import sound.audio;
|
|||
import scene.player;
|
||||
|
||||
// Base properties common to all live objects. Currently extremely
|
||||
// sketchy.
|
||||
// sketchy. TODO: This will all be handled in Monster script at some
|
||||
// point.
|
||||
struct LiveObjectBase
|
||||
{
|
||||
// Should this stuff be in here?
|
||||
|
@ -92,7 +93,7 @@ struct LiveObjectBase
|
|||
// ??
|
||||
byte unam;
|
||||
|
||||
// Don't even get me started on script-related issues
|
||||
// TODO: Scripts
|
||||
}
|
||||
|
||||
// Generic version of a "live" object
|
||||
|
@ -223,6 +224,21 @@ class CellData
|
|||
|
||||
loadReferences();
|
||||
|
||||
// TODO: Set up landscape system here.
|
||||
/*
|
||||
with(esFile)
|
||||
{
|
||||
restoreContext(exCell.land.context, reg);
|
||||
|
||||
// TODO: Not all of these will be present at all times
|
||||
readHNExact(,12675, "VNML");
|
||||
readHNExact(,4232, "VHGT");
|
||||
readHNExact(,81, "WNAM");
|
||||
readHNExact(,12675, "VCLR");
|
||||
readHNExact(,512, "VTEX");
|
||||
}
|
||||
*/
|
||||
|
||||
const float cellWidth = 8192;
|
||||
|
||||
// TODO/FIXME: This is temporary
|
||||
|
@ -243,7 +259,7 @@ class CellData
|
|||
|
||||
esFile.restoreContext(inCell.context, reg);
|
||||
|
||||
// TODO: Read this crap in loadcell.d
|
||||
// TODO: Read this in loadcell.d
|
||||
if(esFile.isNextSub("INTV") || esFile.isNextSub("WHGT"))
|
||||
water = esFile.getHInt();
|
||||
//writefln("Water height: ", water);
|
||||
|
@ -555,12 +571,6 @@ class CellData
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Skip this? Large chance that the same file will be used for
|
||||
// the next cell load, and the rest of our system can handle
|
||||
// that without closing or reopening the file.
|
||||
|
||||
//close(); // Close the file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -582,8 +592,9 @@ struct CellFreelist
|
|||
if(next) return list[--next];
|
||||
|
||||
// Since these are reused, there's no waste in allocating on the
|
||||
// stack here. Also, this is only semi-runtime (executed when
|
||||
// loading a cell), thus a rare GC slow down is non-critical.
|
||||
// heap here. Also, this is only semi-runtime (executed when
|
||||
// loading a cell), thus an occational GC slow down is not
|
||||
// critical.
|
||||
return new CellData(new RegionManager("CELL"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue