Started experimenting with Bullet

git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@46 ea6a568a-9f4f-0410-981a-c910a81bb256
pull/7/head
nkorslund 17 years ago
parent 4d37d36d1e
commit 1cfaeeb8fc

@ -8,14 +8,18 @@ DMD=gdmd -version=Posix
# Some extra flags for niftool and bsatool # Some extra flags for niftool and bsatool
NIFFLAGS=-debug=warnstd -debug=check -debug=statecheck -debug=strict -debug=verbose 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) CF_OIS=$(shell pkg-config --cflags OGRE OIS)
OGCC=$(CXX) $(CXXFLAGS) $(CF_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) CF_FFMPEG=$(shell pkg-config --cflags libavcodec libavformat)
AVGCC=$(CXX) $(CXXFLAGS) $(CF_FFMPEG) 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 # Ogre C++ files, on the form ogre/cpp_X.cpp. Only the first file is
# passed to the compiler, the rest are dependencies. # passed to the compiler, the rest are dependencies.
ogre_cpp=ogre framelistener interface overlay bsaarchive 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. # FFmpeg files, in the form sound/cpp_X.cpp.
avcodec_cpp=avcodec 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) ogre_cpp_files=$(ogre_cpp:%=ogre/cpp_%.cpp)
avcodec_cpp_files=$(avcodec_cpp:%=sound/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 # All object files needed by openmw and esmtool
src := $(wildcard */*.d) src := $(wildcard */*.d)
@ -47,7 +55,7 @@ obj_nif := $(src_nif:%.d=nifobjs/%.o)
all: openmw esmtool niftool bsatool bored all: openmw esmtool niftool bsatool bored
# Only build C++ sources. Used when building from DSSS. # 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) cpp_ogre.o: $(ogre_cpp_files)
$(OGCC) -c $< $(OGCC) -c $<
@ -55,6 +63,9 @@ cpp_ogre.o: $(ogre_cpp_files)
cpp_avcodec.o: $(avcodec_cpp_files) cpp_avcodec.o: $(avcodec_cpp_files)
$(AVGCC) -c $< $(AVGCC) -c $<
cpp_bullet.o: $(bullet_cpp_files)
$(BGCC) -c $<
objs/%.o: %.d objs/%.o: %.d
dirname $@ | xargs mkdir -p dirname $@ | xargs mkdir -p
$(DMD) -c $< -of$@ $(DMD) -c $< -of$@
@ -63,8 +74,8 @@ nifobjs/%.o: %.d
dirname $@ | xargs mkdir -p dirname $@ | xargs mkdir -p
$(DMD) $(NIFFLAGS) -c $< -of$@ $(DMD) $(NIFFLAGS) -c $< -of$@
openmw: openmw.d cpp_ogre.o cpp_avcodec.o $(obj) 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 $(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) esmtool: esmtool.d cpp_ogre.o cpp_avcodec.o $(obj)
$(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat $(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat

@ -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);

@ -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(); }

@ -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); assert(ti.bsaFile == -1);
} }
ti.ml = null;
textureLookup[ti.name] = ti; textureLookup[ti.name] = ti;
return ti; return ti;
@ -447,7 +445,6 @@ struct TextureResource
int bsaFile; // If set to -1, the file is in the file system int bsaFile; // If set to -1, the file is in the file system
int bsaIndex; int bsaIndex;
char[] type; // Texture format, eg "tga" or "dds"; char[] type; // Texture format, eg "tga" or "dds";
ManualLoader ml;
public: public:
@ -460,11 +457,13 @@ struct TextureResource
return bsaIndex == -1; return bsaIndex == -1;
} }
/*KILLME
// Returns true if resource is loaded // Returns true if resource is loaded
bool isLoaded() bool isLoaded()
{ {
return ml != null; return ml != null;
} }
*/
} }
// OLD STUFF // OLD STUFF
@ -495,11 +494,5 @@ struct TextureResource
writefln(" Done\n"); writefln(" Done\n");
} }
void killBSAs()
{
foreach(BSAFile f; archives)
delete f;
}
} }
+/ +/

@ -4,7 +4,7 @@
[openmw.d] [openmw.d]
# Add libraries and the two C++ object files # 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 # Make sure the C++ object files are built first
version(Windows) { version(Windows) {
@ -34,7 +34,7 @@ prebuild += dsss clean niftool
[esmtool.d] [esmtool.d]
# Because of interdepencies between the ESM code and the resource # Because of interdepencies between the ESM code and the resource
# manager, we have to include all the C++ stuff. # 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); 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 // These read an entire sub-record, including the header. They also
// adjust and check leftSub and leftRecord variables through calling // adjust and check leftSub and leftRecord variables through calling
// getSubHeader(). // getSubHeader().

@ -123,9 +123,9 @@ struct ExteriorCell
struct ExtCellHash struct ExtCellHash
{ {
// This is a pretty good hash, gives no collisions at all for // This is a pretty good hash, gives no collisions for all of
// Morrowind.esm and a table size of 2048, and very few collisions // Morrowind.esm when the table size is 2048, and it gives very few
// overall. Not that it matters of course. // collisions overall. Not that it matters that much.
static uint hash(uint val) static uint hash(uint val)
{ {
uint res = cast(ushort)val; uint res = cast(ushort)val;
@ -304,8 +304,7 @@ struct Land
// Save file position // Save file position
getContext(context); getContext(context);
// TODO: We don't decode these yet. Se ESLand.h from // Skip these here. Load the actual data when the cell is loaded.
// Morrowindremake for a lot of hints.
if(isNextSub("VNML")) skipHSubSize(12675); if(isNextSub("VNML")) skipHSubSize(12675);
if(isNextSub("VHGT")) skipHSubSize(4232); if(isNextSub("VHGT")) skipHSubSize(4232);
if(isNextSub("WNAM")) skipHSubSize(81); if(isNextSub("WNAM")) skipHSubSize(81);
@ -342,7 +341,8 @@ struct PathGrid
assert(state == LoadState.Unloaded); assert(state == LoadState.Unloaded);
readHNExact(&data, data.sizeof, "DATA"); 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 // Remember this file position
getContext(context); getContext(context);
@ -352,7 +352,7 @@ struct PathGrid
{ {
int size = skipHSub(); int size = skipHSub();
if(size != 16*data.s2) 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 // Size varies. Path grid chances? Connections? Multiples of 4

@ -33,6 +33,8 @@ import core.config;
import scene.soundlist; import scene.soundlist;
import scene.player; import scene.player;
import bullet.bindings;
import ogre.bindings; import ogre.bindings;
import input.keys; import input.keys;
@ -246,6 +248,10 @@ void initializeInput()
{ {
cpp_moveCamera(position[0], position[1], position[2], cpp_moveCamera(position[0], position[1], position[2],
rotation[0], rotation[1], rotation[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 // 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; if(pause) return 1;
const float moveSpeed = 900; const float moveSpeed = 900;
float speed = moveSpeed * time;
// Check if the movement keys are pressed // Check if the movement keys are pressed
float moveX = 0, moveY = 0, moveZ = 0; float moveX = 0, moveY = 0, moveZ = 0;
float x, y, z;
if(isPressed(Keys.MoveLeft)) moveX -= moveSpeed; if(isPressed(Keys.MoveLeft)) moveX -= speed;
if(isPressed(Keys.MoveRight)) moveX += moveSpeed; if(isPressed(Keys.MoveRight)) moveX += speed;
if(isPressed(Keys.MoveForward)) moveZ -= moveSpeed; if(isPressed(Keys.MoveForward)) moveZ -= speed;
if(isPressed(Keys.MoveBackward)) moveZ += moveSpeed; if(isPressed(Keys.MoveBackward)) moveZ += speed;
if(isPressed(Keys.MoveUp)) moveY += moveSpeed; if(isPressed(Keys.MoveUp)) moveY += speed;
if(isPressed(Keys.MoveDown)) moveY -= moveSpeed; if(isPressed(Keys.MoveDown)) moveY -= speed;
// Move camera. We only support "ghost-mode" at the moment, so we // Move the player. This is a temporary hack, we should do this more
// move without physics or collision detection. // efficiently in C++.
cpp_moveCameraRel(moveX*time, moveY*time, moveZ*time); 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; sndCumTime += time;
if(sndCumTime > sndRefresh) if(sndCumTime > sndRefresh)
{ {
float x, y, z;
float fx, fy, fz; float fx, fy, fz;
float ux, uy, uz; float ux, uy, uz;
cpp_getCameraPos(&x, &y, &z);
cpp_getCameraOrientation(&fx, &fy, &fz, &ux, &uy, &uz); cpp_getCameraOrientation(&fx, &fy, &fz, &ux, &uy, &uz);
soundScene.update(x,y,z,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; 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. // these directly in D code, only pass them back to the C++ code.
typedef void* NodePtr; typedef void* NodePtr;
// Pointer to a manual loader class in C++.
typedef void* ManualLoader;
extern(C): extern(C):
// Do engine configuration. Returns 0 if we should continue, 1 if // 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! // Do some debug action. Check the menu for today's specials!
void cpp_debug(int i); 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]; *uz = up[1];
} }
// Move and rotate camera in place. Transforms Morrowind coordinates // Move and rotate camera in place.
// to OGRE coordinates.
extern "C" void cpp_moveCamera(float x, float y, float z, extern "C" void cpp_moveCamera(float x, float y, float z,
float r1, float r2, float r3) 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)); mCamera->setPosition(Vector3(x,z,-y));
// Rotation is probably not correct, but for now I have no reference // Rotation is probably not correct, but for now I have no reference

@ -56,3 +56,23 @@ SceneNode *root;
#include "cpp_bsaarchive.cpp" #include "cpp_bsaarchive.cpp"
#include "cpp_interface.cpp" #include "cpp_interface.cpp"
#include "cpp_overlay.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);
}

@ -31,6 +31,8 @@ import std.file;
import ogre.ogre; import ogre.ogre;
import ogre.bindings; import ogre.bindings;
import bullet.bullet;
import scene.celldata; import scene.celldata;
import scene.soundlist; import scene.soundlist;
@ -219,10 +221,13 @@ void main(char[][] args)
{ {
// Warm up OGRE // Warm up OGRE
setupOgre(); setupOgre();
// Clean up ogre when we're finished.
scope(exit) cleanupOgre(); scope(exit) cleanupOgre();
// Set up Bullet
initBullet();
scope(exit) cleanupBullet();
if(cd.inCell) if(cd.inCell)
{ {
setAmbient(cd.ambi.ambient, cd.ambi.sunlight, setAmbient(cd.ambi.ambient, cd.ambi.sunlight,

@ -39,7 +39,8 @@ import sound.audio;
import scene.player; import scene.player;
// Base properties common to all live objects. Currently extremely // 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 struct LiveObjectBase
{ {
// Should this stuff be in here? // Should this stuff be in here?
@ -92,7 +93,7 @@ struct LiveObjectBase
// ?? // ??
byte unam; byte unam;
// Don't even get me started on script-related issues // TODO: Scripts
} }
// Generic version of a "live" object // Generic version of a "live" object
@ -223,6 +224,21 @@ class CellData
loadReferences(); 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; const float cellWidth = 8192;
// TODO/FIXME: This is temporary // TODO/FIXME: This is temporary
@ -243,7 +259,7 @@ class CellData
esFile.restoreContext(inCell.context, reg); 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")) if(esFile.isNextSub("INTV") || esFile.isNextSub("WHGT"))
water = esFile.getHInt(); water = esFile.getHInt();
//writefln("Water height: ", water); //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]; if(next) return list[--next];
// Since these are reused, there's no waste in allocating on the // Since these are reused, there's no waste in allocating on the
// stack here. Also, this is only semi-runtime (executed when // heap here. Also, this is only semi-runtime (executed when
// loading a cell), thus a rare GC slow down is non-critical. // loading a cell), thus an occational GC slow down is not
// critical.
return new CellData(new RegionManager("CELL")); return new CellData(new RegionManager("CELL"));
} }

Loading…
Cancel
Save