/*
================
DialogAFConstraintHinge::SaveConstraint
================
*/
void DialogAFConstraintHinge::SaveConstraint( void ) {
	int s1, s2;
	CString str;

	if ( !file || !constraint ) {
		return;
	}
	UpdateData( TRUE );

	// save anchor to the current idDeclAF_Constraint
	GetSafeComboBoxSelection( &m_comboAnchorJoint, str, -1 );
	constraint->anchor.joint1 = str;
	constraint->anchor.ToVec3().x = m_anchor_x;
	constraint->anchor.ToVec3().y = m_anchor_y;
	constraint->anchor.ToVec3().z = m_anchor_z;

	// hinge axis
	if ( constraint->axis.type == idAFVector::VEC_BONEDIR ) {
		s1 = GetSafeComboBoxSelection( &m_comboAxisJoint1, str, -1 );
		constraint->axis.joint1 = str;
		s2 = GetSafeComboBoxSelection( &m_comboAxisJoint2, str, s1 );
		constraint->axis.joint2 = str;
	}
	else {
		constraint->axis.ToVec3() = idAngles( m_axisPitch, m_axisYaw, 0.0f ).ToForward();
	}

	// hinge limit
	constraint->limitAngles[0] = m_limitAngle1;
	constraint->limitAngles[1] = m_limitAngle2;
	constraint->limitAngles[2] = m_limitAngle3;

	AFDialogSetFileModified();
}
/*
============
idAASBuild::AddBrushesForMapEntity
============
*/
idBrushList idAASBuild::AddBrushesForMapEntity( const idMapEntity *mapEnt, int entityNum, idBrushList brushList ) {
	int i;
	idVec3 origin;
	idMat3 axis;
	if( mapEnt->GetNumPrimitives() < 1 ) {
		return brushList;
	}
	mapEnt->epairs.GetVector( "origin", "0 0 0", origin );
	if( !mapEnt->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) {
		float angle = mapEnt->epairs.GetFloat( "angle" );
		if( angle != 0.0f ) {
			axis = idAngles( 0.0f, angle, 0.0f ).ToMat3();
		} else {
			axis.Identity();
		}
	}
	for( i = 0; i < mapEnt->GetNumPrimitives(); i++ ) {
		idMapPrimitive	*mapPrim;
		mapPrim = mapEnt->GetPrimitive( i );
		if( mapPrim->GetType() == idMapPrimitive::TYPE_BRUSH ) {
			brushList = AddBrushesForMapBrush( static_cast<idMapBrush *>( mapPrim ), origin, axis, entityNum, i, brushList );
			continue;
		}
		if( mapPrim->GetType() == idMapPrimitive::TYPE_PATCH ) {
			if( aasSettings->usePatches ) {
				brushList = AddBrushesForMapPatch( static_cast<idMapPatch *>( mapPrim ), origin, axis, entityNum, i, brushList );
			}
			continue;
		}
	}
	return brushList;
}
Beispiel #3
0
/*
=============
idVec3::ToAngles
=============
*/
idAngles idVec3::ToAngles( void ) const {
	float forward;
	float yaw;
	float pitch;
	
	if ( ( x == 0.0f ) && ( y == 0.0f ) ) {
		yaw = 0.0f;
		if ( z > 0.0f ) {
			pitch = 90.0f;
		} else {
			pitch = 270.0f;
		}
	} else {
		yaw = RAD2DEG( idMath::ATan( y, x ) );
		if ( yaw < 0.0f ) {
			yaw += 360.0f;
		}

		forward = ( float )idMath::Sqrt( x * x + y * y );
		pitch = RAD2DEG( idMath::ATan( z, forward ) );
		if ( pitch < 0.0f ) {
			pitch += 360.0f;
		}
	}

	return idAngles( -pitch, yaw, 0.0f );
}
Beispiel #4
0
/*
================
idTarget_EndLevel::Draw
================
*/
void idTarget_EndLevel::Draw() {

	if (noGui) {
		return;
	}

	renderView_t			renderView;

	memset( &renderView, 0, sizeof( renderView ) );

	renderView.width = SCREEN_WIDTH;
	renderView.height = SCREEN_HEIGHT;
	renderView.x = 0;
	renderView.y = 0;

	renderView.fov_x = 90;
	renderView.fov_y = gameLocal.CalcFovY( renderView.fov_x );
	renderView.time = gameLocal.time;

#if 0
	renderView.vieworg = initialViewOrg;
	renderView.viewaxis = idAngles(initialViewAngles).toMat3();
#else
	renderView.vieworg = renderEntity.origin;
	renderView.viewaxis = renderEntity.axis;
#endif

	gameRenderWorld->RenderScene( &renderView );

	// draw the gui on top of the 3D view
	gui->Redraw(gameLocal.time);
}
Beispiel #5
0
void CDialogSound::OnBtnDrop()
{
	idStr		classname;
	idStr		key;
	idStr		value;
	idVec3		org;
	idDict		args;
	idAngles	viewAngles;


	gameEdit->PlayerGetViewAngles( viewAngles );
	gameEdit->PlayerGetEyePosition( org );
	org += idAngles( 0, viewAngles.yaw, 0 ).ToForward() * 80 + idVec3( 0, 0, 1 );
	args.Set("origin", org.ToString());
	args.Set("classname", "speaker");
	args.Set("angle", va( "%f", viewAngles.yaw + 180 ));
	args.Set("s_shader", strShader);
	args.Set("s_looping", "1" );
	args.Set("s_shakes", "0" );


	idStr name = gameEdit->GetUniqueEntityName( "speaker" );
	bool nameValid = false;
	while (!nameValid) {
		DialogName dlg("Name Speaker", this);
		dlg.m_strName = name;
		if (dlg.DoModal() == IDOK) {
			idEntity *gameEnt = gameEdit->FindEntity(dlg.m_strName);
			if (gameEnt) {
				if (MessageBox("Please choose another name", "Duplicate Entity Name!", MB_OKCANCEL) == IDCANCEL) {
					return;
				}
			} else {
				nameValid = true;
				name = dlg.m_strName;
			}
		}
	}

	args.Set("name", name.c_str());

	idEntity *ent = NULL;
	gameEdit->SpawnEntityDef( args, &ent );
	if (ent) {
		gameEdit->EntityUpdateChangeableSpawnArgs( ent, NULL );
		gameEdit->ClearEntitySelection();
		gameEdit->AddSelectedEntity( ent );
	}

	gameEdit->MapAddEntity( &args );
	const idDict *dict = gameEdit->MapGetEntityDict( args.GetString( "name" ) );
	Set( dict );
	AddGroups();
	AddSpeakers();
}
Beispiel #6
0
idAngles Aimbot::Main( float fov, float ping, bool humanize, float smoothMultiplier, float smoothTransposition )
{
#define FRAME_TIME_SECONDS 0.008f
		Ping = ping;
	FOV = fov;
	_Muzzle = ImportExport::User->EyePosition() + ImportExport::User->ViewAngles().ToMat3()[0]*14.0f + EvaluatePath(idVec3(0,0,0), 
		ImportExport::User->Velocity(), FRAME_TIME_SECONDS);
	if ( ScanForTarget() )
	{
		idAngles angles = AimAt( TargetOrigin() );
		return humanize ? Humanize( smoothMultiplier, smoothTransposition, angles ) : angles;
	}
	return idAngles(0, 0, 0);
}
/*
================
DialogAFConstraintBallAndSocket::SaveConstraint
================
*/
void DialogAFConstraintBallAndSocket::SaveConstraint( void ) {
	int s1, s2;
	CString str;
	idAngles angles;

	if ( !file || !constraint ) {
		return;
	}
	UpdateData( TRUE );

	// anchor
	GetSafeComboBoxSelection( &m_comboAnchorJoint, str, -1 );
	constraint->anchor.joint1 = str;
	constraint->anchor.ToVec3().x = m_anchor_x;
	constraint->anchor.ToVec3().y = m_anchor_y;
	constraint->anchor.ToVec3().z = m_anchor_z;

	// limit
	if ( constraint->limit == idDeclAF_Constraint::LIMIT_CONE ) {
		constraint->limitAngles[0] = m_coneAngle;
	}
	else {
		constraint->limitAngles[0] = m_pyramidAngle1;
	}
	constraint->limitAngles[1] = m_pyramidAngle2;
	constraint->limitAngles[2] = m_limitRoll;
	angles.pitch = m_limitPitch;
	angles.yaw = m_limitYaw;
	angles.roll = 0.0f;
	constraint->limitAxis.ToVec3() = angles.ToForward();
	s1 = GetSafeComboBoxSelection( &m_comboLimitJoint1, str, -1 );
	constraint->limitAxis.joint1 = str;
	s2 = GetSafeComboBoxSelection( &m_comboLimitJoint2, str, s1 );
	constraint->limitAxis.joint2 = str;

	// limit axis
	if ( constraint->shaft[0].type == idAFVector::VEC_BONEDIR ) {
		s1 = GetSafeComboBoxSelection( &m_comboLimitAxisJoint1, str, -1 );
		constraint->shaft[0].joint1 = str;
		s2 = GetSafeComboBoxSelection( &m_comboLimitAxisJoint2, str, s1 );
		constraint->shaft[0].joint2 = str;
	}
	else {
		constraint->shaft[0].ToVec3() = idAngles( m_limitAxisPitch, m_limitAxisYaw, 0.0f ).ToForward();
	}

	AFDialogSetFileModified();
}
void idRenderWindow::Render( int time ) {
	rLight.origin = lightOrigin.ToVec3();
	rLight.shaderParms[SHADERPARM_RED] = lightColor.x();
	rLight.shaderParms[SHADERPARM_GREEN] = lightColor.y();
	rLight.shaderParms[SHADERPARM_BLUE] = lightColor.z();
	world->UpdateLightDef(lightDef, &rLight);
	if ( worldEntity.hModel ) {
		if (updateAnimation) {
			BuildAnimation(time);
		}
		if (modelAnim) {
			if (time > animEndTime) {
				animEndTime = time + animLength;
			}
			gameEdit->ANIM_CreateAnimFrame(worldEntity.hModel, modelAnim, worldEntity.numJoints, worldEntity.joints, animLength - (animEndTime - time), vec3_origin, false );
		}
		worldEntity.axis = idAngles(modelRotate.x(), modelRotate.y(), modelRotate.z()).ToMat3();
		world->UpdateEntityDef(modelDef, &worldEntity);
	}
}
Beispiel #9
0
END_CLASS

void idEntity_Leaf::Spawn() {
	liveTime		= spawnArgs.GetFloat( "leaf_liveTime" );	// in seconds. Keep this low to prevent too many leaves in the map at a time. each leaf is an entity! Try to make each leaf live at least until it touches the ground. Some leaves will slide along the ground if they live long enough. default: 8
	moveSpeed		= spawnArgs.GetFloat( "leaf_moveSpeed" );	// from 1-10. How fast the leaves move regardless of wind. Keep this high. default: 10
	spread			= spawnArgs.GetFloat( "leaf_spread" );	// from 1-10. Affects how far apart leafs speread apart when falling. default: 10
	windPower		= spawnArgs.GetFloat( "leaf_windPower" );	// from 1-10. How strong the wind is on the leaves. default: 1
	windDir			= spawnArgs.GetVector( "leaf_windDir" );	// Wind direction. default: '0 1 0'
	gravity			= spawnArgs.GetVector( "leaf_gravity" );	// Gravity of the leaf. Keep this pretty low, or accept the default. default: '0 0 -20'
	origin			= spawnArgs.GetVector( "leaf_origin" );
	ang				= GetAngles();
	dieTime			= gameLocal.time + liveTime * 1000;
	if( moveSpeed == 0 ) {
		moveSpeed = 1;
	}
	if( origin != idVec3( 0, 0, 0 ) ) {
		SetOrigin( origin );
	}
	spread = spread / 20; //max spread is 0.5
	dir = gameLocal.random.RandomInt( 3 );
	if( dir < 1 ) {
		spreadX = spread;
	} else if( dir < 2 && dir > 1 ) {
		spreadX = 0;
	} else {
		spreadX = -spread;
	}
	dir = gameLocal.random.RandomInt( 3 );
	if( dir < 1 ) {
		spreadY = spread;
	} else if( dir < 2 && dir > 1 ) {
		spreadY = 0;
	} else {
		spreadY = -spread;
	}
	SetAngles( idAngles( gameLocal.random.CRandomFloat() * 360, gameLocal.random.CRandomFloat() * 360, gameLocal.random.CRandomFloat() * 360 ) );
	GetPhysics()->SetLinearVelocity( idVec3( 0, 0, 0 ) );
	GetPhysics()->SetGravity( idVec3( 0, 0, 0 ) ); //gravity - if we set zero gravity, the leaves stop when they hit the ground. dont know why, but it's cool!
	curVel = GetPhysics()->GetLinearVelocity();
	nextAngles = 0;
}
Beispiel #10
0
/*
============
idAASLocal::ShowFloorTrace
============
*/
void idAASLocal::ShowFloorTrace( const idVec3 &origin ) const {
	idPlayer *player;

	player = gameLocal.GetLocalPlayer();
	if ( !player ) {
		return;
	}
	idMat3 playerAxis = idAngles( 0.0f, player->GetViewAngles().yaw, 0.0f ).ToMat3();

	idVec3 org = origin;
	int areaNum = PointReachableAreaNum( org, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() );
	PushPointIntoArea( areaNum, org );

	aasTraceFloor_t trace;
	TraceFloor( trace, org, areaNum, origin + playerAxis[0] * 1024, TFL_WALK|TFL_AIR );

	gameRenderWorld->DebugArrow( colorCyan, org, trace.endpos, 1, 0 );
	idVec3 up = trace.endpos + playerAxis[2] * 64;
	const idVec4 &color = ( trace.fraction >= 1.0f ) ? colorGreen : colorRed;
	gameRenderWorld->DebugArrow( color, trace.endpos, up + playerAxis[1] * 32, 1, 0, true );
	gameRenderWorld->DebugArrow( color, trace.endpos, up - playerAxis[1] * 32, 1, 0, true );
}
/*
================
DialogAFConstraintSlider::SaveConstraint
================
*/
void DialogAFConstraintSlider::SaveConstraint( void ) {
	int s1, s2;
	CString str;

	if ( !file || !constraint ) {
		return;
	}
	UpdateData( TRUE );

	// slider axis
	if ( constraint->axis.type == idAFVector::VEC_BONEDIR ) {
		s1 = GetSafeComboBoxSelection( &m_comboAxisJoint1, str, -1 );
		constraint->axis.joint1 = str;
		s2 = GetSafeComboBoxSelection( &m_comboAxisJoint2, str, s1 );
		constraint->axis.joint2 = str;
	}
	else {
		constraint->axis.ToVec3() = idAngles( m_axisPitch, m_axisYaw, 0.0f ).ToForward();
	}

	AFDialogSetFileModified();
}
Beispiel #12
0
void idGLDrawableModel::draw(int x, int y, int w, int h) {
    if ( !worldModel ) {
        return;
    }
    if ( worldModel->IsDynamicModel() != DM_STATIC ) {
        //return;
    }

    rect.Set( x, y, w, h );

    qglViewport(x, y, w, h);
    qglScissor(x, y, w, h);
    qglMatrixMode(GL_PROJECTION);
    qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
    qglClear(GL_COLOR_BUFFER_BIT);

    if (worldDirty) {
        //InitWorld();
        world->InitFromMap( NULL );
        renderLight_t	parms;
        idDict spawnArgs;
        spawnArgs.Set("classname", "light");
        spawnArgs.Set("name", "light_1");
        spawnArgs.Set("origin", "-128 0 0");
        idStr str;
        sprintf(str, "%f %f %f", light, light, light);
        spawnArgs.Set("_color", str);
        gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms );
        lightDef = world->AddLightDef( &parms );

        renderEntity_t worldEntity;
        memset( &worldEntity, 0, sizeof( worldEntity ) );
        spawnArgs.Clear();
        spawnArgs.Set("classname", "func_static");
        spawnArgs.Set("name", spawnArgs.GetString("model"));
        spawnArgs.Set("origin", "0 0 0");
        if ( skinStr.Length() ) {
            spawnArgs.Set( "skin", skinStr );
        }
        gameEdit->ParseSpawnArgsToRenderEntity(&spawnArgs, &worldEntity);
        worldEntity.hModel = worldModel;

        worldEntity.axis = rotation.ToMat3();

        worldEntity.shaderParms[0] = 1;
        worldEntity.shaderParms[1] = 1;
        worldEntity.shaderParms[2] = 1;
        worldEntity.shaderParms[3] = 1;
        modelDef = world->AddEntityDef( &worldEntity );

        worldDirty = false;
    }

    renderView_t	refdef;
    // render it
    renderSystem->BeginFrame(w, h);
    memset( &refdef, 0, sizeof( refdef ) );
    refdef.vieworg.Set(zOffset, xOffset, -yOffset);

    refdef.viewaxis = idAngles(0,0,0).ToMat3();
    refdef.shaderParms[0] = 1;
    refdef.shaderParms[1] = 1;
    refdef.shaderParms[2] = 1;
    refdef.shaderParms[3] = 1;

    refdef.width = SCREEN_WIDTH;
    refdef.height = SCREEN_HEIGHT;
    refdef.fov_x = 90;
    refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG;

    refdef.time = eventLoop->Milliseconds();

    world->RenderScene( &refdef );
    int frontEnd, backEnd;
    renderSystem->EndFrame( &frontEnd, &backEnd );

    qglMatrixMode( GL_MODELVIEW );
    qglLoadIdentity();
}
Beispiel #13
0
void idGLDrawableMaterial::draw(int x, int y, int w, int h) {
    const idMaterial *mat = material;
    if (mat) {
        qglViewport(x, y, w, h);
        qglScissor(x, y, w, h);
        qglMatrixMode(GL_PROJECTION);
        qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
        qglClear(GL_COLOR_BUFFER_BIT);

        if (worldDirty) {
            InitWorld();
            renderLight_t	parms;
            idDict spawnArgs;
            spawnArgs.Set("classname", "light");
            spawnArgs.Set("name", "light_1");
            spawnArgs.Set("origin", "0 0 0");
            idStr str;
            sprintf(str, "%f %f %f", light, light, light);
            spawnArgs.Set("_color", str);
            gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms );
            lightDef = world->AddLightDef( &parms );

            idImage *img = (mat->GetNumStages() > 0) ? mat->GetStage(0)->texture.image : mat->GetEditorImage();

            if (img == NULL) {
                common->Warning("Unable to load image for preview for %s", mat->GetName());
                return;
            }

            int width = img->uploadWidth;
            int height = img->uploadHeight;

            width *= scale;
            height *= scale;

            srfTriangles_t *tris = worldModel->AllocSurfaceTriangles( 4, 6 );
            tris->numVerts = 4;
            tris->numIndexes = 6;

            tris->indexes[0] = 0;
            tris->indexes[1] = 1;
            tris->indexes[2] = 2;
            tris->indexes[3] = 3;
            tris->indexes[4] = 1;
            tris->indexes[5] = 0;

            tris->verts[0].xyz.x = 64;
            tris->verts[0].xyz.y = -xOffset + 0 - width / 2;
            tris->verts[0].xyz.z = yOffset + 0 - height / 2;
            tris->verts[0].st.x = 1;
            tris->verts[0].st.y = 1;

            tris->verts[1].xyz.x = 64;
            tris->verts[1].xyz.y = -xOffset + width / 2;
            tris->verts[1].xyz.z = yOffset + height / 2;
            tris->verts[1].st.x = 0;
            tris->verts[1].st.y = 0;

            tris->verts[2].xyz.x = 64;
            tris->verts[2].xyz.y = -xOffset + 0 - width / 2;
            tris->verts[2].xyz.z = yOffset + height / 2;
            tris->verts[2].st.x = 1;
            tris->verts[2].st.y = 0;

            tris->verts[3].xyz.x = 64;
            tris->verts[3].xyz.y = -xOffset + width / 2;
            tris->verts[3].xyz.z = yOffset + 0 - height / 2;
            tris->verts[3].st.x = 0;
            tris->verts[3].st.y = 1;

            tris->verts[0].normal = tris->verts[1].xyz.Cross(tris->verts[3].xyz);
            tris->verts[1].normal = tris->verts[2].normal = tris->verts[3].normal = tris->verts[0].normal;
            AddTris(tris, mat);

            worldModel->FinishSurfaces();

            renderEntity_t worldEntity;

            memset( &worldEntity, 0, sizeof( worldEntity ) );
            if ( mat->HasGui() ) {
                worldEntity.gui[ 0 ] = mat->GlobalGui();
            }
            worldEntity.hModel = worldModel;
            worldEntity.axis = mat3_default;
            worldEntity.shaderParms[0] = 1;
            worldEntity.shaderParms[1] = 1;
            worldEntity.shaderParms[2] = 1;
            worldEntity.shaderParms[3] = 1;
            modelDef = world->AddEntityDef( &worldEntity );

            worldDirty = false;
        }

        renderView_t	refdef;
        // render it
        renderSystem->BeginFrame(w, h);
        memset( &refdef, 0, sizeof( refdef ) );
        refdef.vieworg.Set(viewAngle, 0, 0);

        refdef.viewaxis = idAngles(0,0,0).ToMat3();
        refdef.shaderParms[0] = 1;
        refdef.shaderParms[1] = 1;
        refdef.shaderParms[2] = 1;
        refdef.shaderParms[3] = 1;

        refdef.width = SCREEN_WIDTH;
        refdef.height = SCREEN_HEIGHT;
        refdef.fov_x = 90;
        refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG;

        refdef.time = eventLoop->Milliseconds();

        world->RenderScene( &refdef );
        int frontEnd, backEnd;
        renderSystem->EndFrame( &frontEnd, &backEnd );

        qglMatrixMode( GL_MODELVIEW );
        qglLoadIdentity();
    }

}
Beispiel #14
0
/*
==================
FixGlobalTjunctions
==================
*/
void	FixGlobalTjunctions( uEntity_t *e ) {
	mapTri_t	*a;
	int			vert;
	int			i;
	optimizeGroup_t	*group;
	int			areaNum;

	common->Printf( "----- FixGlobalTjunctions -----\n" );

	// clear the hash tables
	memset( hashVerts, 0, sizeof( hashVerts ) );

	numHashVerts = 0;
	numTotalVerts = 0;

	// bound all the triangles to determine the bucket size
	hashBounds.Clear();
	for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) {
		for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) {
			for ( a = group->triList ; a ; a = a->next ) {
				hashBounds.AddPoint( a->v[0].xyz );
				hashBounds.AddPoint( a->v[1].xyz );
				hashBounds.AddPoint( a->v[2].xyz );
			}
		}
	}

	// spread the bounds so it will never have a zero size
	for ( i = 0 ; i < 3 ; i++ ) {
		hashBounds[0][i] = floor( hashBounds[0][i] - 1 );
		hashBounds[1][i] = ceil( hashBounds[1][i] + 1 );
		hashIntMins[i] = hashBounds[0][i] * SNAP_FRACTIONS;

		hashScale[i] = ( hashBounds[1][i] - hashBounds[0][i] ) / HASH_BINS;
		hashIntScale[i] = hashScale[i] * SNAP_FRACTIONS;
		if ( hashIntScale[i] < 1 ) {
			hashIntScale[i] = 1;
		}
	}

	// add all the points to the hash buckets
	for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) {
		for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) {
			// don't touch discrete surfaces
			if ( group->material != NULL && group->material->IsDiscrete() ) {
				continue;
			}

			for ( a = group->triList ; a ; a = a->next ) {
				for ( vert = 0 ; vert < 3 ; vert++ ) {
					a->hashVert[vert] = GetHashVert( a->v[vert].xyz );
				}
			}
		}
	}

	// add all the func_static model vertexes to the hash buckets
	// optionally inline some of the func_static models
	if ( dmapGlobals.entityNum == 0 ) {
		for ( int eNum = 1 ; eNum < dmapGlobals.num_entities ; eNum++ ) {
			uEntity_t *entity = &dmapGlobals.uEntities[eNum];
			const char *className = entity->mapEntity->epairs.GetString( "classname" );
			if ( idStr::Icmp( className, "func_static" ) ) {
				continue;
			}
			const char *modelName = entity->mapEntity->epairs.GetString( "model" );
			if ( !modelName ) {
				continue;
			}
			if ( !strstr( modelName, ".lwo" ) && !strstr( modelName, ".ase" ) && !strstr( modelName, ".ma" ) ) {
				continue;
			}

			idRenderModel	*model = renderModelManager->FindModel( modelName );

//			common->Printf( "adding T junction verts for %s.\n", entity->mapEntity->epairs.GetString( "name" ) );

			idMat3	axis;
			// get the rotation matrix in either full form, or single angle form
			if ( !entity->mapEntity->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) {
				float angle = entity->mapEntity->epairs.GetFloat( "angle" );
				if ( angle != 0.0f ) {
					axis = idAngles( 0.0f, angle, 0.0f ).ToMat3();
				} else {
					axis.Identity();
				}
			}

			idVec3	origin = entity->mapEntity->epairs.GetVector( "origin" );

			for ( i = 0 ; i < model->NumSurfaces() ; i++ ) {
				const modelSurface_t *surface = model->Surface( i );
				const srfTriangles_t *tri = surface->geometry;

				mapTri_t	mapTri;
				memset( &mapTri, 0, sizeof( mapTri ) );
				mapTri.material = surface->shader;
				// don't let discretes (autosprites, etc) merge together
				if ( mapTri.material->IsDiscrete() ) {
					mapTri.mergeGroup = (void *)surface;
				}
				for ( int j = 0 ; j < tri->numVerts ; j += 3 ) {
					idVec3 v = tri->verts[j].xyz * axis + origin;
					GetHashVert( v );
				}
			}
		}
	}



	// now fix each area
	for ( areaNum = 0 ; areaNum < e->numAreas ; areaNum++ ) {
		for ( group = e->areas[areaNum].groups ; group ; group = group->nextGroup ) {
			// don't touch discrete surfaces
			if ( group->material != NULL && group->material->IsDiscrete() ) {
				continue;
			}

			mapTri_t *newList = NULL;
			for ( mapTri_t *tri = group->triList ; tri ; tri = tri->next ) {
				mapTri_t *fixed = FixTriangleAgainstHash( tri );
				newList = MergeTriLists( newList, fixed );
			}
			FreeTriList( group->triList );
			group->triList = newList;
		}
	}


	// done
	FreeTJunctionHash();
}
stateResult_t rvMonsterStroggHover::State_DeathSpiral ( const stateParms_t& parms ) {
	enum { 
		STAGE_INIT,
		STAGE_SPIRAL
	};
	switch ( parms.stage ) {
		case STAGE_INIT:
			{
				disablePain = true;

				// Make sure all animation and attack states stop
				StopAnimState ( ANIMCHANNEL_TORSO );
				StopAnimState ( ANIMCHANNEL_LEGS );

				// Start the crash & burn effects
				for ( int i = 0; i < numHoverJoints; i++ ) {
					if ( jointHover[i] != INVALID_JOINT ) {
						PlayEffect ( "fx_hurt", jointHover[i], false );
						effectHover[i] = PlayEffect ( "fx_crash", jointHover[i], true );
					}
				}
				deathPitch = viewAxis.ToAngles()[0];
				deathRoll = viewAxis.ToAngles()[2];

				deathPitchRate = gameLocal.random.RandomFloat()*0.3f + 0.1f;
				deathYawRate = gameLocal.random.RandomFloat()*2.0f + 1.5f;
				deathRollRate = gameLocal.random.RandomFloat()*3.0f + 1.0f;
				deathSpeed = gameLocal.random.RandomFloat()*300.0f + 500.0f;
				deathGrav = gameLocal.random.RandomFloat()*6.0f + 6.0f;

				strafeRight = (gameLocal.random.RandomFloat()>0.5f);
				StopSound( SND_CHANNEL_HEART, false ); 
				StartSound ( "snd_crash", SND_CHANNEL_HEART, 0, false, NULL );
			}
			return SRESULT_STAGE ( STAGE_SPIRAL );
		case STAGE_SPIRAL:
			{
				move.current_yaw += (strafeRight?-deathYawRate:deathYawRate);
				deathPitch = idMath::ClampFloat( -90.0f, 90.0f, deathPitch+deathPitchRate );
				deathRoll += (strafeRight?deathRollRate:-deathRollRate);
				viewAxis = idAngles( deathPitch, move.current_yaw, deathRoll ).ToMat3();

				idVec3 vel = GetPhysics()->GetLinearVelocity();
				idVec3 strafeVel = viewAxis[0] * deathSpeed;
				strafeVel.z = 0;
				vel += strafeVel;
				vel.Normalize();
				vel *= deathSpeed;
				vel += GetPhysics()->GetGravity()/deathGrav;

				physicsObj.UseVelocityMove( true );

				physicsObj.SetLinearVelocity( vel );

				idSoundEmitter *emitter = soundSystem->EmitterForIndex( SOUNDWORLD_GAME, refSound.referenceSoundHandle );
				if( emitter ) {
					refSound.parms.frequencyShift += 0.025f;
					emitter->ModifySound ( SND_CHANNEL_HEART, &refSound.parms );
				}
			}
			return SRESULT_WAIT;
	}

	return SRESULT_ERROR;
}
/*
================
idTestModel::Think
================
*/
void idTestModel::Think()
{
	idVec3 pos;
	idMat3 axis;
	idAngles ang;
	int	i;
	
	if( thinkFlags & TH_THINK )
	{
		if( anim && ( gameLocal.testmodel == this ) && ( mode != g_testModelAnimate.GetInteger() ) )
		{
			StopSound( SND_CHANNEL_ANY, false );
			if( head.GetEntity() )
			{
				head.GetEntity()->StopSound( SND_CHANNEL_ANY, false );
			}
			switch( g_testModelAnimate.GetInteger() )
			{
				default:
				case 0:
					// cycle anim with origin reset
					if( animator.NumFrames( anim ) <= 1 )
					{
						// single frame animations end immediately, so just cycle it since it's the same result
						animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
						if( headAnim )
						{
							headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
						}
					}
					else
					{
						animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
						if( headAnim )
						{
							headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
							if( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) )
							{
								// loop the body anim when the head anim is longer
								animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
							}
						}
					}
					animator.RemoveOriginOffset( false );
					break;
					
				case 1:
					// cycle anim with fixed origin
					animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( true );
					if( headAnim )
					{
						headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 2:
					// cycle anim with continuous origin
					animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( false );
					if( headAnim )
					{
						headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 3:
					// frame by frame with continuous origin
					animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( false );
					if( headAnim )
					{
						headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 4:
					// play anim once
					animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( false );
					if( headAnim )
					{
						headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
					
				case 5:
					// frame by frame with fixed origin
					animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					animator.RemoveOriginOffset( true );
					if( headAnim )
					{
						headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
					}
					break;
			}
			
			mode = g_testModelAnimate.GetInteger();
		}
		
		if( ( mode == 0 ) && ( gameLocal.time >= starttime + animtime ) )
		{
			starttime = gameLocal.time;
			StopSound( SND_CHANNEL_ANY, false );
			animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
			if( headAnim )
			{
				headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) );
				if( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) )
				{
					// loop the body anim when the head anim is longer
					animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 );
				}
			}
		}
		
		if( headAnimator )
		{
			// copy the animation from the body to the head
			for( i = 0; i < copyJoints.Num(); i++ )
			{
				if( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE )
				{
					idMat3 mat = head.GetEntity()->GetPhysics()->GetAxis().Transpose();
					GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
					pos -= head.GetEntity()->GetPhysics()->GetOrigin();
					headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat );
					headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat );
				}
				else
				{
					animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis );
					headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos );
					headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis );
				}
			}
		}
		
		// update rotation
		RunPhysics();
		
		physicsObj.GetAngles( ang );
		physicsObj.SetAngularExtrapolation( extrapolation_t( EXTRAPOLATION_LINEAR | EXTRAPOLATION_NOSTOP ), gameLocal.time, 0, ang, idAngles( 0, g_testModelRotate.GetFloat() * 360.0f / 60.0f, 0 ), ang_zero );
		
		idClipModel* clip = physicsObj.GetClipModel();
		if( clip != NULL && animator.ModelDef() )
		{
			idVec3 neworigin;
			idMat3 axis;
			jointHandle_t joint;
			
			joint = animator.GetJointHandle( "origin" );
			animator.GetJointTransform( joint, gameLocal.time, neworigin, axis );
			neworigin = ( ( neworigin - animator.ModelDef()->GetVisualOffset() ) * physicsObj.GetAxis() ) + GetPhysics()->GetOrigin();
			clip->Link( gameLocal.clip, this, 0, neworigin, clip->GetAxis() );
		}
	}
	
	UpdateAnimation();
	Present();
	
	if( ( gameLocal.testmodel == this ) && g_showTestModelFrame.GetInteger() && anim )
	{
		gameLocal.Printf( "^5 Anim: ^7%s  ^5Frame: ^7%d/%d  Time: %.3f\n", animator.AnimFullName( anim ), animator.CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
						  animator.CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - animator.CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
		if( headAnim )
		{
			gameLocal.Printf( "^5 Head: ^7%s  ^5Frame: ^7%d/%d  Time: %.3f\n\n", headAnimator->AnimFullName( headAnim ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ),
							  headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) );
		}
		else
		{
			gameLocal.Printf( "\n\n" );
		}
	}
}
Beispiel #17
0
/*
================
idDeclAF::ParseBody
================
*/
bool idDeclAF::ParseBody( idLexer &src ) {
	bool hasJoint = false;
	idToken token;
	idAFVector angles;
	idDeclAF_Body *body = new idDeclAF_Body;

	bodies.Alloc() = body;

	body->SetDefault( this );

	if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ||
			!src.ExpectTokenString( "{" ) ) {
		return false;
	}

	body->name = token;
	if ( !body->name.Icmp( "origin" ) || !body->name.Icmp( "world" ) ) {
		src.Error( "a body may not be named \"origin\" or \"world\"" );
		return false;
	}

	while( src.ReadToken( &token ) ) {

		if ( !token.Icmp( "model" ) ) {
			if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) {
				return false;
			}
			if ( !token.Icmp( "box" ) ) {
				body->modelType = TRM_BOX;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "octahedron" ) ) {
				body->modelType = TRM_OCTAHEDRON;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "dodecahedron" ) ) {
				body->modelType = TRM_DODECAHEDRON;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "cylinder" ) ) {
				body->modelType = TRM_CYLINDER;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( "," ) ) {
					return false;
				}
				body->numSides = src.ParseInt();
				if ( !src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "cone" ) ) {
				body->modelType = TRM_CONE;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( "," ) ) {
					return false;
				}
				body->numSides = src.ParseInt();
				if ( !src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "bone" ) ) {
				body->modelType = TRM_BONE;
				if ( !src.ExpectTokenString( "(" ) ||
					!body->v1.Parse( src ) ||
					!src.ExpectTokenString( "," ) ||
					!body->v2.Parse( src ) ||
					!src.ExpectTokenString( "," ) ) {
					return false;
				}
				body->width = src.ParseFloat();
				if ( !src.ExpectTokenString( ")" ) ) {
					return false;
				}
			} else if ( !token.Icmp( "custom" ) ) {
				src.Error( "custom models not yet implemented" );
				return false;
			} else {
				src.Error( "unkown model type %s", token.c_str() );
				return false;
			}
		} else if ( !token.Icmp( "origin" ) ) {
			if ( !body->origin.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "angles" ) ) {
			if ( !angles.Parse( src ) ) {
				return false;
			}
			body->angles = idAngles( angles.ToVec3().x, angles.ToVec3().y, angles.ToVec3().z );
		} else if ( !token.Icmp( "joint" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
			body->jointName = token;
			hasJoint = true;
		} else if ( !token.Icmp( "mod" ) ) {
			if ( !src.ExpectAnyToken( &token ) ) {
				return false;
			}
			body->jointMod = JointModFromString( token.c_str() );
		} else if ( !token.Icmp( "density" ) ) {
			body->density = src.ParseFloat();
		} else if ( !token.Icmp( "inertiaScale" ) ) {
			src.Parse1DMatrix( 9, body->inertiaScale[0].ToFloatPtr() );
		} else if ( !token.Icmp( "friction" ) ) {
			body->linearFriction = src.ParseFloat();
			src.ExpectTokenString( "," );
			body->angularFriction = src.ParseFloat();
			src.ExpectTokenString( "," );
			body->contactFriction = src.ParseFloat();
		} else if ( !token.Icmp( "contents" ) ) {
			ParseContents( src, body->contents );
		} else if ( !token.Icmp( "clipMask" ) ) {
			ParseContents( src, body->clipMask );
		} else if ( !token.Icmp( "selfCollision" ) ) {
			body->selfCollision = src.ParseBool();
		} else if ( !token.Icmp( "containedjoints" ) ) {
			if ( !src.ExpectTokenType( TT_STRING, 0, &token ) ) {
				return false;
			}
			body->containedJoints = token;
		} else if ( !token.Icmp( "frictionDirection" ) ) {
			if ( !body->frictionDirection.Parse( src ) ) {
				return false;
			}
		} else if ( !token.Icmp( "contactMotorDirection" ) ) {
			if ( !body->contactMotorDirection.Parse( src ) ) {
				return false;
			}
		} else if ( token == "}" ) {
			break;
		} else {
			src.Error( "unknown token %s in body", token.c_str() );
			return false;
		}
	}

	if ( body->modelType == TRM_INVALID ) {
		src.Error( "no model set for body" );
		return false;
	}

	if ( !hasJoint ) {
		src.Error( "no joint set for body" );
		return false;
	}

	body->clipMask |= CONTENTS_MOVEABLECLIP;

	return true;
}
Beispiel #18
0
void idWorldManager::UpdatePlay( int idx )
{
	int currentIndex = records[idx].index;

	if (currentIndex > records[idx].events.Num() - 1)
	{
		return;
	}

	if (records[idx].events[currentIndex].timestamp < gameLocal.time - recordStarttime)
	{
		if (!records[idx].events[currentIndex].frobcommand.IsEmpty() && !records[idx].events[currentIndex].done)
		{
			//FROB EVENT.
			idEntity *frobEnt;
			frobEnt = gameLocal.FindEntity( records[idx].events[currentIndex].frobcommand );
			if (frobEnt)
			{

				if (frobEnt->IsType(idTrigger_Multi::Type))
				{
					static_cast<idTrigger_Multi *>( frobEnt )->TriggerAction(NULL);
				}
				else
				{
					gameLocal.GetLocalPlayer()->DoFrob(frobEnt);
					//common->Printf("frobbing! %d\n", gameLocal.time);
				}
			}
			else
			{
				gameLocal.Warning("WorldManager couldn't find frob ent: %s\n", gameLocal.FindEntity( records[idx].events[currentIndex].frobcommand.c_str()));
			}

			records[idx].events[currentIndex].done = true;
		}
		else if (records[idx].events[currentIndex].recordtype == RECORD_LAUNCHAIM && !records[idx].events[currentIndex].done)
		{
			//event: change launcher aim.
			
			//find the launcher with this id.
			int i;
			int targetEnt = -1;

			for ( i = 0; i < gameLocal.num_entities; i++ )
			{
				if ( !gameLocal.entities[ i ] )
					continue;

				int kk = records[idx].events[currentIndex].entID;

				if (gameLocal.entities[i]->spawnArgs.GetInt("id") != records[idx].events[currentIndex].entID)
				{
					continue;
				}

				targetEnt = i;
				break;
			}

			if (developer.GetBool())
			{
				common->Printf("worldmanager: aiming launcher entity ID %d  \n", records[idx].events[currentIndex].entID);
			}

			if (targetEnt >= 0)
			{
				//legacy.
				gameLocal.entities[targetEnt]->spawnArgs.SetVector("new_launchdir", records[idx].events[currentIndex].position);
				gameLocal.entities[targetEnt]->spawnArgs.SetInt("new_force", records[idx].events[currentIndex].yaw);
				gameLocal.entities[targetEnt]->spawnArgs.SetInt("new_update", 1);

				static_cast<idLauncher *>( gameLocal.entities[i] )->SetLaunchDir(records[idx].events[currentIndex].position, records[idx].events[currentIndex].yaw);
			}

			records[idx].events[currentIndex].done = true;
		}
		else if (!records[idx].events[currentIndex].deckcommand.IsEmpty() && !records[idx].events[currentIndex].done)
		{
			//DECK EVENT.
			gameLocal.RunDeckCommand(records[idx].events[currentIndex].deckcommand.c_str());

			records[idx].events[currentIndex].done = true;
		}
		else if (records[idx].events[currentIndex].recordtype == RECORD_UNSPAWN && !records[idx].events[currentIndex].done)
		{
			//UNSPAWN EVENT.
			//find the ent with this id.
			int i;
			int targetEnt = -1;

			for ( i = 0; i < gameLocal.num_entities; i++ )
			{
				if ( !gameLocal.entities[ i ] )
					continue;

				int kk = records[idx].events[currentIndex].entID;

				if (gameLocal.entities[i]->spawnArgs.GetInt("id") != records[idx].events[currentIndex].entID)
				{
					continue;
				}

				targetEnt = i;
				break;
			}

			if (targetEnt >= 0)
			{
				gameLocal.entities[targetEnt]->PostEventMS( &EV_Remove, 0 );
				//gameLocal.entities[targetEnt]->Event_CallFunction("onPick");
			}

			records[idx].events[currentIndex].done = true;
		}
		else if (records[idx].events[currentIndex].recordtype == RECORD_SPAWN && !records[idx].events[currentIndex].done)
		{
			
			//SPAWN EVENT.

			idEntity	*ent;
			idDict		args;
			idAngles	ang;

			int id = gameLocal.time - recordStarttime;

			if (developer.GetBool())
			{
				common->Printf("worldmanager: spawning entity ID %d  classname %s \n", records[idx].events[currentIndex].entID,
					records[idx].events[currentIndex].spawncommand.c_str());
			}

			args.Set( "classname", records[idx].events[currentIndex].spawncommand );
			args.SetVector( "origin", records[idx].events[currentIndex].position );
			args.SetInt( "id", records[idx].events[currentIndex].entID);
			bool bSpawn = gameLocal.SpawnEntityDef( args, &ent );

			if (ent)
			{
				ent->spawnArgs.SetInt("id", records[idx].events[currentIndex].entID);  //BC 7-21-2016 was crashing here.
			
				ang.pitch = 0;
				ang.yaw = records[idx].events[currentIndex].yaw;
				ang.roll = 0;
				ent->SetAngles( ang );
			}

			if (developer.GetBool())
			{
				common->Printf("worldmanager: spawning success:%d\n",  bSpawn);
				
			}

			records[idx].events[currentIndex].done = true;
		}
		else
		{
			//MOVE EVENT.
			float moveTime = (float)RECORDRATE / 1000;
		
			records[idx].ghost->Event_SetMoveTime(moveTime);
			records[idx].ghost->Event_MoveToPos(records[idx].events[currentIndex].position);
			
			idAngles newAng = idAngles(0, records[idx].events[currentIndex].yaw, 0);
			records[idx].ghost->SetAxis(newAng.ToMat3());

			if (index == -1)
			{
				int lastLineIndex = recordlines[idx].lines.Num() - 1;
				recordline_t newLine;
				newLine.position1 = recordlines[idx].lines[lastLineIndex].position2;
				newLine.position2 = records[idx].events[currentIndex].position;

				recordlines[idx].lines.Append(newLine);
			}

			records[idx].events[currentIndex].done = true;
		}

		
		records[idx].index++;
	}
}
Beispiel #19
0
/*
================
idForce_Field::Evaluate
================
*/
void idForce_Field::Evaluate( int time ) {
	int numClipModels, i;
	idBounds bounds;
	idVec3 force, torque, angularVelocity;
	idClipModel *cm, *clipModelList[ MAX_GENTITIES ];

	assert( clipModel );

	bounds.FromTransformedBounds( clipModel->GetBounds(), clipModel->GetOrigin(), clipModel->GetAxis() );
	numClipModels = gameLocal.clip.ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES );

	for ( i = 0; i < numClipModels; i++ ) {
		cm = clipModelList[ i ];

		if ( !cm->IsTraceModel() ) {
			continue;
		}

		idEntity *entity = cm->GetEntity();

		if ( !entity ) {
			continue;
		}
		
		//bc ignore things.
		if (entity->IsType( idMoveableItem::Type ))
		{
			//int ignoreNum = static_cast<idMoveableItem *>( entity)->forcefieldIgnore.GetEntityNum();
			//int myOwnerNum = this->owner.GetEntityNum();

			if (static_cast<idMoveableItem *>( entity)->forcefieldIgnore.GetEntityNum() == this->owner.GetEntityNum())
			{
				continue;
			}
		}
		


		idPhysics *physics = entity->GetPhysics();

		//bc
		/*
		if (this->owner.IsValid())
		{
			if (gameLocal.GetLocalPlayer()->pickerState >= 2)
			{
				if (gameLocal.GetLocalPlayer()->pickerWeapon.dragEnt.IsValid())
				{
					if( gameLocal.GetLocalPlayer()->pickerWeapon.dragEnt.GetEntity()->IsGrabbed() && physics->IsType( idPhysics_Player::Type ))
					{
						continue;
					}
				}
			}			
		}
		*/


		if ( playerOnly ) {
			if ( !physics->IsType( idPhysics_Player::Type ) ) {
				continue;
			}
		} else if ( monsterOnly ) {
			if ( !physics->IsType( idPhysics_Monster::Type ) ) {
				continue;
			}
		}

		if ( !gameLocal.clip.ContentsModel( cm->GetOrigin(), cm, cm->GetAxis(), -1,
									clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis() ) ) {
			continue;
		}

		switch( type ) {
			case FORCEFIELD_UNIFORM: {
				force = dir;
				break;
			}
			case FORCEFIELD_EXPLOSION: {
				force = cm->GetOrigin() - clipModel->GetOrigin();
				force.Normalize();
				break;
			}
			case FORCEFIELD_IMPLOSION: {
				force = clipModel->GetOrigin() - cm->GetOrigin();
				force.Normalize();
				break;
			}
			default: {
				gameLocal.Error( "idForce_Field: invalid type" );
				break;
			}
		}
		
		if ( randomTorque != 0.0f ) {
			torque[0] = gameLocal.random.CRandomFloat();
			torque[1] = gameLocal.random.CRandomFloat();
			torque[2] = gameLocal.random.CRandomFloat();
			if ( torque.Normalize() == 0.0f ) {
				torque[2] = 1.0f;
			}
		}

		switch( applyType ) {
			case FORCEFIELD_APPLY_FORCE: {
				if ( randomTorque != 0.0f ) {
					entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude );
				}
				else {
					entity->AddForce( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude );
				}
				break;
			}
			case FORCEFIELD_APPLY_VELOCITY:
			{
				//triggered by jumppad. LAUNCHER.


				//ignore objects that are being held by the player.

				if (gameLocal.GetLocalPlayer()->pickerWeapon.dragEnt.IsValid())
				{
					//player is holding onto an object.
					if (gameLocal.GetLocalPlayer()->pickerWeapon.dragEnt.GetEntity() == entity)
					{
						//the thrown object equals the carried object. abort.
						continue;
					}
				}

				if ( entity->IsType( idDoor::Type ) )
					continue;

				if ( entity->IsType( idAFEntity_Generic::Type ))
				{

					physics->SetLinearVelocity( force * magnitude, cm->GetId() );

					continue;
				}

				//BC hack. only launch players when they're reeeaally close, to lessen accidental launches when
				//launch is plopped down near player's feet.
				if ( entity->IsType( idPlayer::Type ) )
				{
					idVec3 playerPos = entity->GetPhysics()->GetOrigin();
					playerPos.z = clipModel->GetOrigin().z;
					idVec3 rawDist = playerPos - clipModel->GetOrigin();
					float finalDist = rawDist.LengthFast();
					

					if (finalDist > 24)
						continue;

					//force *= 0.98f; //BC hack. reduce player boost.

					static_cast<idPlayer *>( entity )->physicsObj.inJump = true;
					


				}				
				else
				{
					
					force *= g_launchermultiplier.GetFloat(); //BC hack. give non-players an extra boost.

					//TODO: figure out why/how physics treats players and objects differently.
					//force *= 1.1f; //was 1.43
					//force *= 1.9f; //was 1.43
					//force *= forceMultiplier;
				}



				//common->Printf("thrown mass is %f\n", 					entity->GetPhysics()->GetMass());

				


				//bc hack: snap the object to the center of the jumppad so jump arc is more consistent.
				if (jumppadTimer < time)
				{
					jumppadTimer = time + 400;

					idVec3 jumppadOrigin = clipModel->GetOrigin();
					//jumppadOrigin.z = physics->GetOrigin().z;  //retain objects' original vertical (z) axis, so that things don't get stuck in the ground.

					//jumppadOrigin.z
					//gameRenderWorld->DebugCircle( colorWhite, jumppadOrigin, idVec3(0,0,1), 32, 12, 5000 );

					//physics->GetAbsBounds()					

					jumppadOrigin.z += 5;
					physics->SetOrigin( jumppadOrigin );



					//BC 10-13-2015 reset object angle to 0,0,0.
					idAngles snapAngle = idAngles(0,0,0);
					physics->SetAxis(snapAngle.ToMat3());



					//common->Printf("tele hack\n");

					//gameRenderWorld->DebugBounds( colorMagenta, physics->GetBounds(), physics->GetOrigin(), 5000 );
					//gameRenderWorld->DebugCircle( colorOrange, physics->GetOrigin(), idVec3(0,0,1), 16, 12, 5000 );
					//gameRenderWorld->DebugCircle( colorWhite, clipModel->GetOrigin(), idVec3(0,0,1), 32, 12, 5000 );

					physics->SetLinearVelocity( force * magnitude, cm->GetId() );
				}				
				
				
				/*
				if ( randomTorque != 0.0f )
				{
					angularVelocity = physics->GetAngularVelocity( cm->GetId() );
					physics->SetAngularVelocity( 0.5f * (angularVelocity + torque * randomTorque), cm->GetId() );
				}
				*/

				//Raven
				if ( !physics->IsType( idPhysics_AF::Type ))					
					lastApplyTime = time;

				break;
			}
			case FORCEFIELD_APPLY_IMPULSE: {
				if ( randomTorque != 0.0f ) {
					entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin() + torque.Cross( dir ) * randomTorque, dir * magnitude );
				}
				else {
					entity->ApplyImpulse( gameLocal.world, cm->GetId(), cm->GetOrigin(), force * magnitude );
				}
				break;
			}
			default: {
				gameLocal.Error( "idForce_Field: invalid apply type" );
				break;
			}
		}
	}
}
Beispiel #20
0
/*
============
TestMath
============
*/
void TestMath() {
	int i;
	TIME_TYPE start, end, bestClocks;

	idLib::common->Printf("====================================\n" );

	float tst = -1.0f;
	float tst2 = 1.0f;
	float testvar = 1.0f;
	idRandom rnd;

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = fabs( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "            fabs( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		int tmp = * ( int * ) &tst;
		tmp &= 0x7FFFFFFF;
		tst = * ( float * ) &tmp;
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "    idMath::Fabs( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = 10.0f + 100.0f * rnd.RandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = sqrt( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * 0.01f;
		tst = 10.0f + 100.0f * rnd.RandomFloat();
	}
	PrintClocks( "            sqrt( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.RandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Sqrt( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.RandomFloat();
	}
	PrintClocks( "    idMath::Sqrt( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.RandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Sqrt16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.RandomFloat();
	}
	PrintClocks( "  idMath::Sqrt16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Sin( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "     idMath::Sin( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Sin16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "   idMath::Sin16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Cos( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "     idMath::Cos( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Cos16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "   idMath::Cos16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		idMath::SinCos( tst, tst, tst2 );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "  idMath::SinCos( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		idMath::SinCos16( tst, tst, tst2 );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "idMath::SinCos16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Tan( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "     idMath::Tan( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Tan16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "   idMath::Tan16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::ASin( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI );
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "    idMath::ASin( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::ASin16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI );
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "  idMath::ASin16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::ACos( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI );
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "    idMath::ACos( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::ACos16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * ( 1.0f / idMath::PI );
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "  idMath::ACos16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::ATan( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "    idMath::ATan( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::ATan16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "  idMath::ATan16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Pow( 2.7f, tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * 0.1f;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "    idMath::Pow( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Pow16( 2.7f, tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * 0.1f;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "  idMath::Pow16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Exp( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * 0.1f;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "    idMath::Exp( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		tst = idMath::Exp16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst * 0.1f;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "  idMath::Exp16( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		tst = fabs( tst ) + 1.0f;
		StartRecordTime( start );
		tst = idMath::Log( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "    idMath::Log( tst )", 1, bestClocks );

	bestClocks = 0;
	tst = rnd.CRandomFloat();
	for ( i = 0; i < NUMTESTS; i++ ) {
		tst = fabs( tst ) + 1.0f;
		StartRecordTime( start );
		tst = idMath::Log16( tst );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
		testvar = ( testvar + tst ) * tst;
		tst = rnd.CRandomFloat();
	}
	PrintClocks( "  idMath::Log16( tst )", 1, bestClocks );

	idLib::common->Printf( "testvar = %f\n", testvar );

	idMat3 resultMat3;
	idQuat fromQuat, toQuat, resultQuat;
	idCQuat cq;
	idAngles ang;

	fromQuat = idAngles( 30, 45, 0 ).ToQuat();
	toQuat = idAngles( 45, 0, 0 ).ToQuat();
	cq = idAngles( 30, 45, 0 ).ToQuat().ToCQuat();
	ang = idAngles( 30, 40, 50 );

	bestClocks = 0;
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		resultMat3 = fromQuat.ToMat3();
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
	}
	PrintClocks( "       idQuat::ToMat3()", 1, bestClocks );

	bestClocks = 0;
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		resultQuat.Slerp( fromQuat, toQuat, 0.3f );
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
	}
	PrintClocks( "        idQuat::Slerp()", 1, bestClocks );

	bestClocks = 0;
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		resultQuat = cq.ToQuat();
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
	}
	PrintClocks( "      idCQuat::ToQuat()", 1, bestClocks );

	bestClocks = 0;
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		resultQuat = ang.ToQuat();
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
	}
	PrintClocks( "     idAngles::ToQuat()", 1, bestClocks );

	bestClocks = 0;
	for ( i = 0; i < NUMTESTS; i++ ) {
		StartRecordTime( start );
		resultMat3 = ang.ToMat3();
		StopRecordTime( end );
		GetBest( start, end, bestClocks );
	}
	PrintClocks( "     idAngles::ToMat3()", 1, bestClocks );
}
/*
============
hhDebrisSpawner::SpawnDebris
============
*/
void hhDebrisSpawner::SpawnDebris() {
	const idKeyValue *	kv = NULL;
	idEntity *			debris;
	idDict				args;
	idStr				debrisEntity;
	idList<idStr>		debrisEntities;
	int					numDebris;
	// For entity sources
	idBounds 			sourceBounds;	
	idVec3				sourceBoundCenter;
	idVec3				debrisOrigin;
	idBounds			searchBounds;
	idVec3				debrisVelocity;
	bool				fit;
	idBounds			afBounds; //rww
	bool				gotAFBounds = false; //rww
	idVec3				defOrigin = vec3_zero;
	idAngles			defAngles = ang_zero;

	// Optimization: if player is far away, don't spawn the chunks
	if (!gameLocal.isMultiplayer) {
		float maxDistance = spawnArgs.GetFloat("max_debris_distance");
		if (maxDistance > 0.0f) {
			float distSquared = (gameLocal.GetLocalPlayer()->GetOrigin() - origin).LengthSqr();
			if (distSquared > maxDistance*maxDistance) {
				return;
			}
		}
	}
	args.SetInt( "nodrop", 1 );
	args.SetVector( "origin", origin );
	args.SetFloat( "duration", duration );

	// Pass along variabes requested
	hhUtils::PassArgs( spawnArgs, args, "pass_" );

	if (useAFBounds && sourceEntity && sourceEntity->IsType(idActor::Type)) { //rww - try for AF bounds
		idActor *actor = static_cast<idActor *>(sourceEntity);
		if (actor->IsActiveAF()) { //they are ragdolling, so we have a chance.
			idPhysics_AF *afPhys = actor->GetAFPhysics();

			if (afPhys) { //got the af physics object, now loop through the bodies and collect an appropriate bounds.
				afBounds.Zero();

				for (int bodyCount = 0; bodyCount < afPhys->GetNumBodies(); bodyCount++) {
					idAFBody *b = afPhys->GetBody(bodyCount);
					if (b) {
						idClipModel *bodyClip = b->GetClipModel();
						if (bodyClip) { //now add the bounds of the clipModel into afBounds
							idBounds bodyBounds = bodyClip->GetBounds();
							idVec3 point = (b->GetWorldOrigin()-origin);

							bodyBounds.AddPoint(point);
							afBounds.AddBounds(bodyBounds);
							gotAFBounds = true;
						}
					}
				}
			}
		}
	}

	// Find all Debris
	while ( GetNextDebrisData( debrisEntities, numDebris, kv, defOrigin, defAngles ) ) {
		int numEntities = debrisEntities.Num();
		for ( int count = 0; count < numDebris; ++count ) {
			// Select a debris to use from the list
			debrisEntity = debrisEntities[ gameLocal.random.RandomInt( numEntities ) ];

			// If we have a bounding box to fill, use that
			if ( fillBounds && ( sourceEntity || hasBounds ) ) {
				if (gotAFBounds) { //rww
					sourceBounds = afBounds;
					//gameRenderWorld->DebugBounds(colorGreen, afBounds, origin, 1000);
				}
				else if ( sourceEntity ) {
					sourceBounds = sourceEntity->GetPhysics()->GetBounds();
				}
				else {
					sourceBounds = bounds;
				}

				fit = false;
				for ( int i = 0; i < 4; i++ ) {
					if ( i == 0 && defOrigin != vec3_zero ) {
						//first try bone origin without random offset
						debrisOrigin = defOrigin;
					} else {
						debrisOrigin = origin + hhUtils::RandomPointInBounds( sourceBounds );
					}
		
					if ( !testBounds || hhUtils::EntityDefWillFit( debrisEntity, debrisOrigin, defAngles.ToMat3(), CONTENTS_SOLID, NULL ) ) {
						fit = true;
						break; // Found a spot for the gib
					}
				}
			
				if ( !fit ) { // Gib didn't fit after 4 attempts, so don't spawn the gib
					//common->Warning( "SpawnDebris: gib didn't fit when spawned (%s)\n", debrisEntity.c_str() );
					defAngles = ang_zero;
					continue;
				}

				args.SetVector( "origin", debrisOrigin );
				if ( sourceEntity ) {
					idMat3 sourceAxis = idAngles( 0, sourceEntity->GetAxis().ToAngles().yaw, 0 ).ToMat3();
					args.SetMatrix( "rotation", defAngles.ToMat3() * sourceAxis );
				} else {
					args.SetMatrix( "rotation", defAngles.ToMat3() );
				}
			}


			if ( duration ) {
				args.SetFloat( "removeTime", duration + duration * gameLocal.random.CRandomFloat() );
			}

			// Spawn the object
			debris = gameLocal.SpawnObject( debrisEntity, &args );
			HH_ASSERT(debris != NULL); // JRM - Nick, I added this because of a crash I got. Hopefully this will catch it sooner

			// mdl:  Added this check to make sure no AFs go through the debris spawner
			if ( debris->IsType( idAFEntity_Base::Type ) ) {
				gameLocal.Warning( "hhDebrisSpawner spawned an articulated entity:  '%s'.", debrisEntity.c_str() );
			}

			if ( nonSolid ) {

				idVec3 origin;
				if ( debris->GetFloorPos( 64.0f, origin ) ) {
					debris->SetOrigin( origin ); // Start on floor, since we're not going to be moving at all
					debris->RunPhysics(); // Make sure any associated effects get updated before we turn collision off
				}

				// Turn off collision
				debris->GetPhysics()->SetContents( 0 );
				debris->GetPhysics()->SetClipMask( 0 );
				debris->GetPhysics()->UnlinkClip();
				debris->GetPhysics()->PutToRest();

			} else {
				// Add in random velocity
				idVec3 randVel( gameLocal.random.RandomInt( power.x ) - power.x / 2,
								gameLocal.random.RandomInt( power.y ) - power.y / 2,
								gameLocal.random.RandomInt( power.z ) - power.z / 2 );

				// Set linear velocity
				debrisVelocity.x = velocity.x * power.x * 0.25;
				debrisVelocity.y = velocity.y * power.y * 0.25;
				debrisVelocity.z = 0.0f;
				debris->GetPhysics()->SetLinearVelocity( debrisVelocity + randVel );

				// Add random angular velocity
				idVec3 aVel;
				aVel.x = spawnArgs.GetFloat( "ang_vel", "90.0" ) * gameLocal.random.CRandomFloat();
				aVel.y = spawnArgs.GetFloat( "ang_vel", "90.0" ) * gameLocal.random.CRandomFloat();
				aVel.z = spawnArgs.GetFloat( "ang_vel", "90.0" ) * gameLocal.random.CRandomFloat();
			
				if ( defAngles == ang_zero ) {
					debris->GetPhysics()->SetAxis( idVec3( 1, 0, 0 ).ToMat3() );
				}
				debris->GetPhysics()->SetAngularVelocity( aVel );
			}
		}
		defAngles = ang_zero;

		// Zero out the list
		debrisEntities.Clear();
	}

	return;
}
/*
=====================
PutPrimitivesInAreas

=====================
*/
void PutPrimitivesInAreas( uEntity_t *e ) {
	uBrush_t		*b;
	int				i;
	side_t			*side;
	primitive_t		*prim;
	mapTri_t		*tri;

	common->Printf( "----- PutPrimitivesInAreas -----\n");

	// allocate space for surface chains for each area
	e->areas = (uArea_t *)Mem_Alloc( e->numAreas * sizeof( e->areas[0] ) );
	memset( e->areas, 0, e->numAreas * sizeof( e->areas[0] ) );

	// for each primitive, clip it to the non-solid leafs
	// and divide it into different areas
	for ( prim = e->primitives ; prim ; prim = prim->next ) {
		b = prim->brush;

		if ( !b ) {
			// add curve triangles
			for ( tri = prim->tris ; tri ; tri = tri->next ) {
				AddMapTriToAreas( tri, e );
			}
			continue;
		}

		// clip in brush sides
		for ( i = 0 ; i < b->numsides ; i++ ) {
			side = &b->sides[i];
			if ( !side->visibleHull ) {
				continue;
			}
			PutWindingIntoAreas_r( e, side->visibleHull, side, e->tree->headnode );
		}
	}


	// optionally inline some of the func_static models
	if ( dmapGlobals.entityNum == 0 ) {
		bool inlineAll = dmapGlobals.uEntities[0].mapEntity->epairs.GetBool( "inlineAllStatics" );

		for ( int eNum = 1 ; eNum < dmapGlobals.num_entities ; eNum++ ) {
			uEntity_t *entity = &dmapGlobals.uEntities[eNum];
			const char *className = entity->mapEntity->epairs.GetString( "classname" );
			if ( idStr::Icmp( className, "func_static" ) ) {
				continue;
			}
			if ( !entity->mapEntity->epairs.GetBool( "inline" ) && !inlineAll ) {
				continue;
			}
			const char *modelName = entity->mapEntity->epairs.GetString( "model" );
			if ( !modelName ) {
				continue;
			}
			idRenderModel	*model = renderModelManager->FindModel( modelName );

			common->Printf( "inlining %s.\n", entity->mapEntity->epairs.GetString( "name" ) );

			idMat3	axis;
			// get the rotation matrix in either full form, or single angle form
			if ( !entity->mapEntity->epairs.GetMatrix( "rotation", "1 0 0 0 1 0 0 0 1", axis ) ) {
				float angle = entity->mapEntity->epairs.GetFloat( "angle" );
				if ( angle != 0.0f ) {
					axis = idAngles( 0.0f, angle, 0.0f ).ToMat3();
				} else {
					axis.Identity();
				}
			}

			idVec3	origin = entity->mapEntity->epairs.GetVector( "origin" );

			for ( i = 0 ; i < model->NumSurfaces() ; i++ ) {
				const modelSurface_t *surface = model->Surface( i );
				const srfTriangles_t *tri = surface->geometry;

				mapTri_t	mapTri;
				memset( &mapTri, 0, sizeof( mapTri ) );
				mapTri.material = surface->shader;
				// don't let discretes (autosprites, etc) merge together
				if ( mapTri.material->IsDiscrete() ) {
					mapTri.mergeGroup = (void *)surface;
				}
				for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) {
					for ( int k = 0 ; k < 3 ; k++ ) {
						idVec3 v = tri->verts[tri->indexes[j+k]].xyz;

						mapTri.v[k].xyz = v * axis + origin;

						mapTri.v[k].normal = tri->verts[tri->indexes[j+k]].normal * axis;
						mapTri.v[k].st = tri->verts[tri->indexes[j+k]].st;
					}
					AddMapTriToAreas( &mapTri, e );
				}
			}
		}
	}
}
Beispiel #23
0
/*
============
idAASLocal::ShowWallEdges
============
*/
void idAASLocal::ShowWallEdges( const idVec3 &origin, int mode, bool showNumbers ) const {
	const int MAX_WALL_EDGES = 1024;
	int edges[MAX_WALL_EDGES];
	float textSize;

	idPlayer *player = gameLocal.GetLocalPlayer();
	if ( player == NULL ) {
		return;
	}

	idMat3 viewAxis = player->GetViewAxis();
	idVec3 viewOrigin = player->GetViewPos();
	idMat3 playerAxis = idAngles( 0.0f, -player->GetViewAngles().yaw, 0.0f ).ToMat3();

	if ( mode == 3 ) {
		textSize = 0.2f;
	} else {
		textSize = 0.1f;
	}

	float radius = file->GetSettings().obstaclePVSRadius;

	int areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), AAS_AREA_REACHABLE_WALK, TravelFlagInvalidForTeam() );
	//int numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( radius ), TFL_WALK, 64.0f, edges, MAX_WALL_EDGES );
	int numEdges = GetObstaclePVSWallEdges( areaNum, edges, MAX_WALL_EDGES );

	// move the wall edges to the start of the list
	int numWallEdges = 0;
	for ( int i = 0; i < numEdges; i++ ) {
		if ( ( file->GetEdge( abs( edges[i] ) ).flags & AAS_EDGE_WALL ) != 0 ) {
			idSwap( edges[numWallEdges++], edges[i] );
		}
	}

	for ( int i = 0; i < numEdges; i++ ) {
		idVec3 start, end;

		GetEdge( edges[i], start, end );

		if ( mode == 2 ) {

			start.z = end.z = origin.z;

		} else if ( mode == 3 ) {

			ProjectTopDown( start, viewOrigin, viewAxis, playerAxis, radius * 2.0f );
			ProjectTopDown( end, viewOrigin, viewAxis, playerAxis, radius * 2.0f );
		}

		if ( ( file->GetEdge( abs( edges[i] ) ).flags & AAS_EDGE_WALL ) != 0 ) {
			gameRenderWorld->DebugLine( colorRed, start, end, 0 );
		} else {
			gameRenderWorld->DebugLine( colorGreen, start, end, 0 );
		}
		if ( showNumbers ) {
			gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, textSize, colorWhite, viewAxis, 1, 0 );
		}
	}

	if ( mode == 3 ) {
		idVec3 box[7] = { origin, origin, origin, origin, origin, origin, origin };

		box[0][0] += radius;
		box[0][1] += radius;

		box[1][0] += radius;
		box[1][1] -= radius;

		box[2][0] -= radius;
		box[2][1] -= radius;

		box[3][0] -= radius;
		box[3][1] += radius;

		box[4][1] += radius;

		box[5][0] += radius * 0.1f;
		box[5][1] += radius - radius * 0.1f;

		box[6][0] -= radius * 0.1f;
		box[6][1] += radius - radius * 0.1f;

		for ( int i = 0; i < 7; i++ ) {
			ProjectTopDown( box[i], viewOrigin, viewAxis, playerAxis, radius * 2.0f );
		}
		for ( int i = 0; i < 4; i++ ) {
			gameRenderWorld->DebugLine( colorCyan, box[i], box[(i+1)&3], 0 );
		}
		gameRenderWorld->DebugLine( colorCyan, box[4], box[5], 0 );
		gameRenderWorld->DebugLine( colorCyan, box[4], box[6], 0 );
	}
}