Beispiel #1
0
/**
 * @brief Slides a door
 *
 * @note Though doors, sliding doors need a very different handling:
 * because it's movement is animated (unlike the rotating door),
 * the final position that is used to calculate the routing data
 * is set once the animation finished (because this recalculation
 * might be very expensive).
 *
 * @param[in,out] le The local entity of the inline model
 * @param[in] speed The speed to slide with - a negative value to close the door
 * @sa Door_SlidingUse
 */
void LET_SlideDoor (le_t* le, int speed)
{
	vec3_t moveAngles, moveDir;

	/* get the movement angle vector */
	GET_SLIDING_DOOR_SHIFT_VECTOR(le->dir, speed, moveAngles);

	/* this origin is only an offset to the absolute mins/maxs for rendering */
	VectorAdd(le->origin, moveAngles, le->origin);

	/* get the direction vector from the movement angles that were set on the entity */
	AngleVectors(moveAngles, moveDir, nullptr, nullptr);
	moveDir[0] = fabsf(moveDir[0]);
	moveDir[1] = fabsf(moveDir[1]);
	moveDir[2] = fabsf(moveDir[2]);
	/* calculate the distance from the movement angles and the entity size */
	const int distance = DotProduct(moveDir, le->size);

	bool endPos = false;
	if (speed > 0) {
		/* check whether the distance the door may slide is slided already
		 * - if so, stop the movement of the door */
		if (fabs(le->origin[le->dir & 3]) >= distance)
			endPos = true;
	} else {
		/* the sliding door has not origin set - except when it is opened. This door type is no
		 * origin brush based bmodel entity. So whenever the origin vector is not the zero vector,
		 * the door is opened. */
		if (VectorEmpty(le->origin))
			endPos = true;
	}

	if (endPos) {
		vec3_t distanceVec;
		/* the door finished its move - either close or open, so make sure to recalc the routing
		 * data and set the mins/maxs for the inline brush model */
		cBspModel_t* model = CM_InlineModel(cl.mapTiles, le->inlineModelName);

		assert(model);

		/* we need the angles vector normalized */
		GET_SLIDING_DOOR_SHIFT_VECTOR(le->dir, (speed < 0) ? -1 : 1, moveAngles);

		/* the bounding box of the door is updated in one step - here is no lerping needed */
		VectorMul(distance, moveAngles, distanceVec);

		model->cbmBox.shift(distanceVec);
		CL_RecalcRouting(le);

		/* reset the think function as the movement finished */
		LE_SetThink(le, nullptr);
	} else
		le->thinkDelay = 1000;
}
Beispiel #2
0
/**
 * @brief Slides a door
 * @note The new door state must already be set
 * @param[in,out] door The entity of the inline model. The aabb of this bmodel will get updated
 * in this function to reflect the new door position in the world
 * @sa LET_SlideDoor
 */
static void Door_SlidingUse (edict_t *door)
{
	const bool open = door->doorState == STATE_OPENED;
	vec3_t moveAngles, moveDir, distanceVec;
	int distance;

	/* get the movement angle vector - a negative speed value will close the door*/
	GET_SLIDING_DOOR_SHIFT_VECTOR(door->dir, open ? 1 : -1, moveAngles);

	/* get the direction vector from the movement angles that were set on the entity */
	AngleVectors(moveAngles, moveDir, NULL, NULL);
	moveDir[0] = fabsf(moveDir[0]);
	moveDir[1] = fabsf(moveDir[1]);
	moveDir[2] = fabsf(moveDir[2]);

	/* calculate the distance from the movement angles and the entity size. This is the
	 * distance the door has to slide to fully open or close */
	distance = DotProduct(moveDir, door->size);

	/* the door is moved in one step on the server side - lerping is not needed here - so we
	 * perform the scalar multiplication with the distance the door must move in order to
	 * fully close/open */
	VectorMul(distance, moveAngles, distanceVec);

	/* set the updated position. The bounding boxes that are used for tracing must be
	 * shifted when the door state changes. As the mins and maxs of the aabb are absolute
	 * world coordinates in the map we have to translate the position by the above
	 * calculated movement vector */
	VectorAdd(door->origin, distanceVec, door->origin);						/* calc new model position */
//	gi.SetInlineModelOrientation(door->model, door->origin, door->angles);	/* move the model out of the way */
}