📄 splines.cpp
字号:
Com_UngetToken();
// read the control point
idVec3_t point;
Com_Parse1DMatrix( text, 3, point );
addPoint(point.x, point.y, point.z);
} while (1);
//Com_UngetToken();
//Com_MatchToken( text, "}" );
dirty = true;
}
void idSplineList::write(fileHandle_t file, const char *p) {
idStr s = va("\t\t%s {\n", p);
FS_Write(s.c_str(), s.length(), file);
//s = va("\t\tname %s\n", name.c_str());
//FS_Write(s.c_str(), s.length(), file);
s = va("\t\t\tgranularity %f\n", granularity);
FS_Write(s.c_str(), s.length(), file);
int count = controlPoints.Num();
for (int i = 0; i < count; i++) {
s = va("\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z);
FS_Write(s.c_str(), s.length(), file);
}
s = "\t\t}\n";
FS_Write(s.c_str(), s.length(), file);
}
void idCameraDef::getActiveSegmentInfo(int segment, idVec3_t &origin, idVec3_t &direction, float *fov) {
#if 0
if (!cameraSpline.validTime()) {
buildCamera();
}
double d = (double)segment / numSegments();
getCameraInfo(d * totalTime * 1000, origin, direction, fov);
#endif
/*
if (!cameraSpline.validTime()) {
buildCamera();
}
origin = *cameraSpline.getSegmentPoint(segment);
idVec3_t temp;
int numTargets = getTargetSpline()->controlPoints.Num();
int count = cameraSpline.splineTime.Num();
if (numTargets == 0) {
// follow the path
if (cameraSpline.getActiveSegment() < count - 1) {
temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1];
}
} else if (numTargets == 1) {
temp = *getTargetSpline()->controlPoints[0];
} else {
temp = *getTargetSpline()->getSegmentPoint(segment);
}
temp -= origin;
temp.Normalize();
direction = temp;
*/
}
bool idCameraDef::getCameraInfo(long time, idVec3_t &origin, idVec3_t &direction, float *fv) {
if ((time - startTime) / 1000 > totalTime) {
return false;
}
for (int i = 0; i < events.Num(); i++) {
if (time >= startTime + events[i]->getTime() && !events[i]->getTriggered()) {
events[i]->setTriggered(true);
if (events[i]->getType() == idCameraEvent::EVENT_TARGET) {
setActiveTargetByName(events[i]->getParam());
getActiveTarget()->start(startTime + events[i]->getTime());
//Com_Printf("Triggered event switch to target: %s\n",events[i]->getParam());
} else if (events[i]->getType() == idCameraEvent::EVENT_TRIGGER) {
//idEntity *ent = NULL;
//ent = level.FindTarget( ent, events[i]->getParam());
//if (ent) {
// ent->signal( SIG_TRIGGER );
// ent->ProcessEvent( &EV_Activate, world );
//}
} else if (events[i]->getType() == idCameraEvent::EVENT_FOV) {
//*fv = fov = atof(events[i]->getParam());
} else if (events[i]->getType() == idCameraEvent::EVENT_STOP) {
return false;
}
}
}
origin = *cameraPosition->getPosition(time);
*fv = fov.getFOV(time);
idVec3_t temp = origin;
int numTargets = targetPositions.Num();
if (numTargets == 0) {
/*
// follow the path
if (cameraSpline.getActiveSegment() < count - 1) {
temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1];
if (temp == origin) {
int index = cameraSpline.getActiveSegment() + 2;
while (temp == origin && index < count - 1) {
temp = *cameraSpline.splinePoints[index++];
}
}
}
*/
} else {
temp = *getActiveTarget()->getPosition(time);
}
temp -= origin;
temp.Normalize();
direction = temp;
return true;
}
bool idCameraDef::waitEvent(int index) {
//for (int i = 0; i < events.Num(); i++) {
// if (events[i]->getSegment() == index && events[i]->getType() == idCameraEvent::EVENT_WAIT) {
// return true;
// }
//}
return false;
}
#define NUM_CCELERATION_SEGS 10
#define CELL_AMT 5
void idCameraDef::buildCamera() {
int i;
//int lastSwitch = 0;
idList<float> waits;
idList<int> targets;
totalTime = baseTime;
cameraPosition->setTime(totalTime * 1000);
// we have a base time layout for the path and the target path
// now we need to layer on any wait or speed changes
for (i = 0; i < events.Num(); i++) {
//idCameraEvent *ev = events[i];
events[i]->setTriggered(false);
switch (events[i]->getType()) {
case idCameraEvent::EVENT_TARGET : {
targets.Append(i);
break;
}
case idCameraEvent::EVENT_WAIT : {
waits.Append(atof(events[i]->getParam()));
cameraPosition->addVelocity(events[i]->getTime(), atof(events[i]->getParam()) * 1000, 0);
break;
}
case idCameraEvent::EVENT_TARGETWAIT : {
//targetWaits.Append(i);
break;
}
case idCameraEvent::EVENT_SPEED : {
/*
// take the average delay between up to the next five segments
float adjust = atof(events[i]->getParam());
int index = events[i]->getSegment();
total = 0;
count = 0;
// get total amount of time over the remainder of the segment
for (j = index; j < cameraSpline.numSegments() - 1; j++) {
total += cameraSpline.getSegmentTime(j + 1) - cameraSpline.getSegmentTime(j);
count++;
}
// multiply that by the adjustment
double newTotal = total * adjust;
// what is the difference..
newTotal -= total;
totalTime += newTotal / 1000;
// per segment difference
newTotal /= count;
int additive = newTotal;
// now propogate that difference out to each segment
for (j = index; j < cameraSpline.numSegments(); j++) {
cameraSpline.addSegmentTime(j, additive);
additive += newTotal;
}
break;
*/
}
default: break; // FIXME: what about other idCameraEvent?
}
}
for (i = 0; i < waits.Num(); i++) {
totalTime += waits[i];
}
// on a new target switch, we need to take time to this point ( since last target switch )
// and allocate it across the active target, then reset time to this point
long timeSoFar = 0;
long total = (int)(totalTime * 1000);
for (i = 0; i < targets.Num(); i++) {
long t;
if (i < targets.Num() - 1) {
t = events[targets[i+1]]->getTime();
} else {
t = total - timeSoFar;
}
// t is how much time to use for this target
setActiveTargetByName(events[targets[i]]->getParam());
getActiveTarget()->setTime(t);
timeSoFar += t;
}
}
void idCameraDef::startCamera(long t) {
buildCamera();
cameraPosition->start(t);
//for (int i = 0; i < targetPositions.Num(); i++) {
// targetPositions[i]->
//}
startTime = t;
cameraRunning = true;
}
void idCameraDef::parse(const char *(*text) ) {
const char *token;
do {
token = Com_Parse( text );
if ( !token[0] ) {
break;
}
if ( !Q_stricmp (token, "}") ) {
break;
}
if (Q_stricmp(token, "time") == 0) {
baseTime = Com_ParseFloat(text);
}
if (Q_stricmp(token, "camera_fixed") == 0) {
cameraPosition = new idFixedPosition();
cameraPosition->parse(text);
}
if (Q_stricmp(token, "camera_interpolated") == 0) {
cameraPosition = new idInterpolatedPosition();
cameraPosition->parse(text);
}
if (Q_stricmp(token, "camera_spline") == 0) {
cameraPosition = new idSplinePosition();
cameraPosition->parse(text);
}
if (Q_stricmp(token, "target_fixed") == 0) {
idFixedPosition *pos = new idFixedPosition();
pos->parse(text);
targetPositions.Append(pos);
}
if (Q_stricmp(token, "target_interpolated") == 0) {
idInterpolatedPosition *pos = new idInterpolatedPosition();
pos->parse(text);
targetPositions.Append(pos);
}
if (Q_stricmp(token, "target_spline") == 0) {
idSplinePosition *pos = new idSplinePosition();
pos->parse(text);
targetPositions.Append(pos);
}
if (Q_stricmp(token, "fov") == 0) {
fov.parse(text);
}
if (Q_stricmp(token, "event") == 0) {
idCameraEvent *event = new idCameraEvent();
event->parse(text);
addEvent(event);
}
} while (1);
Com_UngetToken();
Com_MatchToken( text, "}" );
}
qboolean idCameraDef::load(const char *filename) {
char *buf;
const char *buf_p;
//int length =
FS_ReadFile( filename, (void **)&buf );
if ( !buf ) {
return qfalse;
}
clear();
Com_BeginParseSession( filename );
buf_p = buf;
parse(&buf_p);
Com_EndParseSession();
FS_FreeFile( buf );
return qtrue;
}
void idCameraDef::save(const char *filename) {
fileHandle_t file = FS_FOpenFileWrite(filename);
if (file) {
int i;
idStr s = "cameraPathDef { \n";
FS_Write(s.c_str(), s.length(), file);
s = va("\ttime %f\n", baseTime);
FS_Write(s.c_str(), s.length(), file);
cameraPosition->write(file, va("camera_%s",cameraPosition->typeStr()));
for (i = 0; i < numTargets(); i++) {
targetPositions[i]->write(file, va("target_%s", targetPositions[i]->typeStr()));
}
for (i = 0; i < events.Num(); i++) {
events[i]->write(file, "event");
}
fov.write(file, "fov");
s = "}\n";
FS_Write(s.c_str(), s.length(), file);
}
FS_FCloseFile(file);
}
int idCameraDef::sortEvents(const void *p1, const void *p2) {
idCameraEvent *ev1 = (idCameraEvent*)(p1);
idCameraEvent *ev2 = (idCameraEvent*)(p2);
if (ev1->getTime() > ev2->getTime()) {
return -1;
}
if (ev1->getTime() < ev2->getTime()) {
return 1;
}
return 0;
}
void idCameraDef::addEvent(idCameraEvent *event) {
events.Append(event);
//events.Sort(&sortEvents);
}
void idCameraDef::addEvent(idCameraEvent::eventType t, const char *param, long time) {
addEvent(new idCameraEvent(t, param, time));
buildCamera();
}
const char *idCameraEvent::eventStr[] = {
"NA",
"WAIT",
"TARGETWAIT",
"SPEED",
"TARGET",
"SNAPTARGET",
"FOV",
"SCRIPT",
"TRIGGER",
"STOP"
};
void idCameraEvent::parse(const char *(*text) ) {
const char *token;
Com_MatchToken( text, "{" );
do {
token = Com_Parse( text );
if ( !token[0] ) {
break;
}
if ( !strcmp (token, "}") ) {
break;
}
// here we may have to jump over brush epairs ( only used in editor )
do {
// if token is not a brace, it is a key for a key/value pair
if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) {
break;
}
Com_UngetToken();
idStr key = Com_ParseOnLine(text);
const char *token = Com_Parse(text);
if (Q_stricmp(key.c_str(), "type") == 0) {
type = static_cast<idCameraEvent::eventType>(atoi(token));
} else if (Q_stricmp(key.c_str(), "param") == 0) {
paramStr = token;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -