Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,567 @@
|
||||
#include "munga.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "caminst.h"
|
||||
#include "notation.h"
|
||||
|
||||
//##########################################################################
|
||||
//############################# CameraInstance #######################
|
||||
//##########################################################################
|
||||
|
||||
//##########################################################################
|
||||
// Construction and Destruction
|
||||
//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
CameraInstance::CameraInstance(
|
||||
int camera_ID,
|
||||
const Origin &camera_origin,
|
||||
Enumeration camera_type
|
||||
)
|
||||
{
|
||||
Str_Copy(cameraName, "camera", sizeof(cameraName));
|
||||
itoa(camera_ID, cameraName+6, 10);
|
||||
cameraID = camera_ID;
|
||||
cameraDataType = camera_type;
|
||||
SetLocalOrigin(camera_origin);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
CameraInstance::CameraInstance(StreamedInstance *model)
|
||||
{
|
||||
cameraID = model->cameraID;
|
||||
localOrigin = model->localOrigin;
|
||||
cameraToWorld = localOrigin;
|
||||
cameraDataType = model->cameraType;
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
clampValues[i] = model->clampValues[i];
|
||||
}
|
||||
Str_Copy(cameraName, "camera", sizeof(cameraName));
|
||||
itoa(cameraID, cameraName+6, 10);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
#define READ_CAMERA_ENTRY(name,value)\
|
||||
if (\
|
||||
!cam_file->GetEntry(\
|
||||
camera_page_name,\
|
||||
name,\
|
||||
&value\
|
||||
)\
|
||||
)\
|
||||
{ \
|
||||
DEBUG_STREAM << camera_page_name << " missing " name "!\n" << std::flush;\
|
||||
Fail("Bad cameras!");\
|
||||
}
|
||||
|
||||
CameraInstance::CameraInstance(
|
||||
NotationFile *cam_file,
|
||||
const char *camera_page_name
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(cam_file);
|
||||
Check_Pointer(camera_page_name);
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// PageName represents the cameraName
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Str_Copy(cameraName, camera_page_name, sizeof(cameraName));
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read in the position
|
||||
//~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
READ_CAMERA_ENTRY("tranx", localOrigin.linearPosition.x);
|
||||
READ_CAMERA_ENTRY("trany", localOrigin.linearPosition.y);
|
||||
READ_CAMERA_ENTRY("tranz", localOrigin.linearPosition.z);
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read in the Orientation
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
READ_CAMERA_ENTRY("quatx", localOrigin.angularPosition.x);
|
||||
READ_CAMERA_ENTRY("quaty", localOrigin.angularPosition.y);
|
||||
READ_CAMERA_ENTRY("quatz", localOrigin.angularPosition.z);
|
||||
READ_CAMERA_ENTRY("quatw", localOrigin.angularPosition.w);
|
||||
cameraToWorld = localOrigin;
|
||||
|
||||
//
|
||||
//---------------------
|
||||
// Read in camera clamp
|
||||
//---------------------
|
||||
//
|
||||
clampValues[0] = -PI;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"minYawClamp",
|
||||
&clampValues[0].angle
|
||||
);
|
||||
clampValues[1] = PI;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"maxYawClamp",
|
||||
&clampValues[1].angle
|
||||
);
|
||||
clampValues[2] = -PI_OVER_2;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"minPitchClamp",
|
||||
&clampValues[2].angle
|
||||
);
|
||||
clampValues[3] = PI_OVER_2;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"maxPitchClamp",
|
||||
&clampValues[3].angle
|
||||
);
|
||||
|
||||
//
|
||||
// Overwrite default cameraID
|
||||
//
|
||||
const char *camera_data_entry;
|
||||
if(
|
||||
!cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"cameraType",
|
||||
&camera_data_entry
|
||||
)
|
||||
)
|
||||
{
|
||||
cameraDataType = DefaultCameraType;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Pointer(camera_data_entry);
|
||||
cameraDataType = FindCameraType(camera_data_entry);
|
||||
}
|
||||
|
||||
READ_CAMERA_ENTRY("cameraID", cameraID);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
CameraInstance::~CameraInstance()
|
||||
{
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
// Data Access Funtions
|
||||
//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
int
|
||||
CameraInstance::FindCameraType(const char *camera_data_type)
|
||||
{
|
||||
|
||||
if(strcmp("DefaultCameraType", camera_data_type) == 0)
|
||||
{
|
||||
return DefaultCameraType;
|
||||
}
|
||||
else if(strcmp("AlwaysSeesCameraType", camera_data_type) == 0)
|
||||
{
|
||||
return AlwaysSeesCameraType;
|
||||
}
|
||||
return ErrorCameraType;
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
|
||||
void
|
||||
CameraInstance::GetCameraTypeString(char *camera_type_string)
|
||||
{
|
||||
switch(cameraDataType)
|
||||
{
|
||||
case DefaultCameraType:
|
||||
Str_Copy(
|
||||
camera_type_string,
|
||||
"DefaultCameraType",
|
||||
(sizeof(char) * 128)
|
||||
);
|
||||
break;
|
||||
case AlwaysSeesCameraType:
|
||||
Str_Copy(
|
||||
camera_type_string,
|
||||
"AlwaysSeesCameraType",
|
||||
(sizeof(char) * 128)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
Tell(cameraDataType);
|
||||
Warn(" Invalid cameraType !\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
CameraInstance::CalculateCameraRotation(
|
||||
YawPitchRoll *result,
|
||||
const Point3D &world
|
||||
)
|
||||
{
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Given a Vector this function finds a rotation involving only
|
||||
// pitch and yaw, roll will not be affected. In addition the rotation
|
||||
// chosed will always be in the direction of least rotation
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Check(this);
|
||||
Check(result);
|
||||
Check(&world);
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// find the vector from where we are to where we want to point
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Point3D local;
|
||||
local.MultiplyByInverse(world, cameraToWorld);
|
||||
if (Small_Enough(local.LengthSquared()))
|
||||
{
|
||||
*result = YawPitchRoll::Identity;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~
|
||||
// Calculate the angles
|
||||
//~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
result->yaw = Radian::Normalize(Arctan(-local.x, -local.z));
|
||||
Scalar xz_direction = Sqrt((local.x * local.x) + (local.z *local.z));
|
||||
result->pitch = Radian::Normalize(Arctan(local.y, xz_direction));
|
||||
result->roll = 0.0f;
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
CameraInstance::SetLocalOrigin(
|
||||
const Origin &new_origin
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(&new_origin);
|
||||
|
||||
YawPitchRoll ypr;
|
||||
ypr = new_origin.angularPosition;
|
||||
clampValues[0] = clampValues[1] = 0.0f;
|
||||
clampValues[2] = clampValues[3] = ypr.pitch;
|
||||
ypr.pitch = 0.0f;
|
||||
localOrigin.linearPosition = new_origin.linearPosition;
|
||||
localOrigin.angularPosition = ypr;
|
||||
cameraToWorld = localOrigin;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
CameraInstance::LookAt(
|
||||
Origin *result,
|
||||
const Point3D &world_point
|
||||
)
|
||||
{
|
||||
result->linearPosition = localOrigin.linearPosition;
|
||||
YawPitchRoll first,local;
|
||||
first = localOrigin.angularPosition;
|
||||
CalculateCameraRotation(&local, world_point);
|
||||
Clamp(local.yaw, clampValues[0], clampValues[1]);
|
||||
Clamp(local.pitch, clampValues[2], clampValues[3]);
|
||||
first.yaw += local.yaw;
|
||||
first.pitch = local.pitch;
|
||||
result->angularPosition = first;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
CameraInstance::AllowLookingAt(const Point3D &world)
|
||||
{
|
||||
YawPitchRoll local;
|
||||
CalculateCameraRotation(&local, world);
|
||||
if (local.yaw < clampValues[0])
|
||||
{
|
||||
clampValues[0] = local.yaw;
|
||||
}
|
||||
else if (local.yaw > clampValues[1])
|
||||
{
|
||||
clampValues[1] = local.yaw;
|
||||
}
|
||||
if (local.pitch < clampValues[2])
|
||||
{
|
||||
clampValues[2] = local.pitch;
|
||||
}
|
||||
else if (local.pitch > clampValues[3])
|
||||
{
|
||||
clampValues[3] = local.pitch;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
#define YAW_SLOP (PI/12.0)
|
||||
#define PITCH_SLOP (0.75*(YAW_SLOP))
|
||||
|
||||
Logical
|
||||
CameraInstance::CanCameraSee(const Point3D &world_point)
|
||||
{
|
||||
YawPitchRoll ypr;
|
||||
CalculateCameraRotation(&ypr, world_point);
|
||||
return
|
||||
clampValues[0]-YAW_SLOP <= ypr.yaw
|
||||
&& clampValues[1]+YAW_SLOP >= ypr.yaw
|
||||
&& clampValues[2]-PITCH_SLOP <= ypr.pitch
|
||||
&& clampValues[3]+PITCH_SLOP >= ypr.pitch;
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
// Test Support
|
||||
//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
CameraInstance::TestInstance() const
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
// Tool Support
|
||||
//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
CameraInstance::WriteNotationPage(NotationFile *camera_stream)
|
||||
{
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Output this camera's information to the given notation file
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Check(this);
|
||||
Check(camera_stream);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"cameraID",
|
||||
cameraID
|
||||
);
|
||||
|
||||
char camera_type[128];
|
||||
GetCameraTypeString(camera_type);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"cameraType",
|
||||
camera_type
|
||||
);
|
||||
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"tranx",
|
||||
localOrigin.linearPosition.x
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"trany",
|
||||
localOrigin.linearPosition.y
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"tranz",
|
||||
localOrigin.linearPosition.z
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"quatx",
|
||||
localOrigin.angularPosition.x
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"quaty",
|
||||
localOrigin.angularPosition.y
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"quatz",
|
||||
localOrigin.angularPosition.z
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"quatw",
|
||||
localOrigin.angularPosition.w
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"minYawClamp",
|
||||
clampValues[0]
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"maxYawClamp",
|
||||
clampValues[1]
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"minPitchClamp",
|
||||
clampValues[2]
|
||||
);
|
||||
camera_stream->SetEntry(
|
||||
cameraName,
|
||||
"maxPitchClamp",
|
||||
clampValues[3]
|
||||
);
|
||||
camera_stream->AppendEntry(cameraName, NULL, (char *)NULL);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
#undef READ_CAMERA_ENTRY
|
||||
#define READ_CAMERA_ENTRY(name,value)\
|
||||
if (\
|
||||
!cam_file->GetEntry(\
|
||||
camera_page_name,\
|
||||
name,\
|
||||
&value\
|
||||
)\
|
||||
)\
|
||||
{ \
|
||||
DEBUG_STREAM << camera_page_name << " missing " name "!\n" << std::flush;\
|
||||
return False;\
|
||||
}
|
||||
|
||||
Logical
|
||||
CameraInstance::CreateStreamedInstance(
|
||||
StreamedInstance *model,
|
||||
NotationFile *cam_file,
|
||||
const char *camera_page_name
|
||||
)
|
||||
{
|
||||
Check_Pointer(model);
|
||||
Check(cam_file);
|
||||
Check_Pointer(camera_page_name);
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read in the position
|
||||
//~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
READ_CAMERA_ENTRY("tranx", model->localOrigin.linearPosition.x);
|
||||
READ_CAMERA_ENTRY("trany", model->localOrigin.linearPosition.y);
|
||||
READ_CAMERA_ENTRY("tranz", model->localOrigin.linearPosition.z);
|
||||
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Read in the Orientation
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
READ_CAMERA_ENTRY("quatx", model->localOrigin.angularPosition.x);
|
||||
READ_CAMERA_ENTRY("quaty", model->localOrigin.angularPosition.y);
|
||||
READ_CAMERA_ENTRY("quatz", model->localOrigin.angularPosition.z);
|
||||
READ_CAMERA_ENTRY("quatw", model->localOrigin.angularPosition.w);
|
||||
|
||||
//
|
||||
//---------------------
|
||||
// Read in camera clamp
|
||||
//---------------------
|
||||
//
|
||||
model->clampValues[0] = -PI;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"minYawClamp",
|
||||
&model->clampValues[0].angle
|
||||
);
|
||||
model->clampValues[1] = PI;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"maxYawClamp",
|
||||
&model->clampValues[1].angle
|
||||
);
|
||||
model->clampValues[2] = -PI_OVER_2;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"minPitchClamp",
|
||||
&model->clampValues[2].angle
|
||||
);
|
||||
model->clampValues[3] = PI_OVER_2;
|
||||
cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"maxPitchClamp",
|
||||
&model->clampValues[3].angle
|
||||
);
|
||||
|
||||
//
|
||||
// Overwrite default cameraID
|
||||
//
|
||||
const char *camera_data_entry;
|
||||
if(
|
||||
!cam_file->GetEntry(
|
||||
camera_page_name,
|
||||
"cameraType",
|
||||
&camera_data_entry
|
||||
)
|
||||
)
|
||||
{
|
||||
model->cameraType = DefaultCameraType;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Pointer(camera_data_entry);
|
||||
model->cameraType = FindCameraType(camera_data_entry);
|
||||
}
|
||||
|
||||
READ_CAMERA_ENTRY("cameraID", model->cameraID);
|
||||
|
||||
model->instanceSize = sizeof(*model);
|
||||
return True;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
AlwaysSeesCameraInstance::AlwaysSeesCameraInstance(
|
||||
int camera_ID,
|
||||
const Origin &camera_origin,
|
||||
Enumeration camera_type
|
||||
):
|
||||
CameraInstance(camera_ID, camera_origin, camera_type)
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
AlwaysSeesCameraInstance::AlwaysSeesCameraInstance(StreamedInstance *model):
|
||||
CameraInstance(model)
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
AlwaysSeesCameraInstance::AlwaysSeesCameraInstance(
|
||||
NotationFile *cam_file,
|
||||
const char *camera_page_name
|
||||
):
|
||||
CameraInstance(cam_file, camera_page_name)
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
AlwaysSeesCameraInstance::CanCameraSee(const Point3D &)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
Reference in New Issue
Block a user