Example #1
0
Camera::Camera(const PxVec3 &eye, const PxVec3& dir)
{
	mEye = eye;
	mDir = dir.getNormalized();
	mMouseX = 0;
	mMouseY = 0;
}
Example #2
0
void PxFlyBall::move()
{
	time++;
	
	if (time % 3000 < 1600) {
		PxVec3 v = pxActor->getLinearVelocity();
		if (fabs(v.x)< 0.0001 && fabs(v.z)<0.0001) {
			GLfloat angle = (rand() % 360) / 360.0*PxPi;
			pxActor->addForce(PxVec3(PxSin(angle) * 50, 0, PxCos(angle) * 50), PxForceMode::eACCELERATION);
		}
		else {
			if (fabs(v.x) < 50 && fabs(v.z) < 50) {
				PxVec3 nmvec = v.getNormalized();
				pxActor->addForce(PxVec3(nmvec.x*50.0, 0, nmvec.z*50.0), PxForceMode::eACCELERATION);
			}
		}
		PxTransform t = pxActor->getGlobalPose();
		if(t.p.y<300)
			pxActor->addForce(PxVec3(0, rand()%200, 0.0), PxForceMode::eACCELERATION);
		if (particleTime == 0) {
			addCPSS();
		}
	}
	//particleTime++;
	//particleTime = particleTime > 5 ? 0 : particleTime;
	time = time > 3000 ? 0 : time;
}
bool PhysxScene::CheckReachable(physx::PxVec3 src, physx::PxVec3 dst) {
    PxVec3 dir = dst - src;
    PxReal max_distance = sqrt(dir.x*dir.x + dir.y*dir.y + dir.z*dir.z);
    PxRaycastBuffer hit;
    bool is_hit = px_scene_->raycast(src, dir.getNormalized(), max_distance, hit);

    return !is_hit;
}
Example #4
0
void PxMoveBall::move()
{
	PxVec3 v = pxActor->getLinearVelocity();
	if (fabs(v.x - 0.0)<0.0001 && fabs(v.z-0.0)<0.0001) {
		GLfloat angle = (rand() % 360) / 360.0*PxPi;
		pxActor->addForce(PxVec3(PxSin(angle)*50, 0, PxCos(angle)*50),PxForceMode::eACCELERATION);
	}
	else {
		PxReal speed = v.magnitude();
		if (speed <= maxspeed) {
			PxVec3 nmvec = v.getNormalized();
			pxActor->addForce(PxVec3(nmvec.x*50.0, 0, nmvec.z*50.0),PxForceMode::eACCELERATION);
		}
	}
}
Example #5
0
void PxFlyBall::addCPSS()
{
	PxVec3 v = pxActor->getLinearVelocity();
	PxTransform trans = pxActor->getGlobalPose();
	PxVec3 pos = trans.p;
	PxVec3 vn = v.getNormalized();
	extern GLuint pCPS;
	extern CircleParticleSys circleParticleSyses[CIRCLE_PARTICLESYS_NUM];
	Color4f white(1.0, 1.0, 1.0, 1.0);
	GLuint tgt = pCPS%CIRCLE_PARTICLESYS_NUM;
	Vector3f pvn(-v.x, -v.y, -v.z);
	circleParticleSyses[tgt].init(1.2,white, Vector3f(pos.x, pos.y, pos.z), pvn * 0.2, pvn * 0.4, 0, 3, 1, 2, 1.2, 1.4);
	circleParticleSyses[tgt].initCircle(2,4, 1.8, 2, PI , PI / 2, 1.2, 1.2);
	pCPS = pCPS + 1;
	//pCPS = pCPS == CIRCLE_PARTICLESYS_NUM ? 0 : pCPS;
}
Example #6
0
void ApplyInverseSquareGravity(PxRigidActor* actor, PxVec3 source, PxReal power)
{
    PxVec3 dir;
    PxReal distSquared;
    PxVec3 norm;
    PxVec3 force;
    int objectNum = boxes.size();

    for(int i = 0; i < objectNum; i++)
    {
        //Disables the scene gravity so we can apply our own
        DisableGravity(boxes[i]->actor);

        dir = source - boxes[i]->actor->getGlobalPose().p;

        distSquared = dir.magnitudeSquared();
        distSquared = (distSquared < 10) ? 10000 : distSquared;

        norm = dir.getNormalized();
        force = (norm * power) / distSquared;

        boxes[i]->actor->isRigidBody()->addForce(force, PxForceMode::eACCELERATION);
    }
}
static FVector FindConvexMeshOpposingNormal(const PxLocationHit& PHit, const FVector& TraceDirectionDenorm, const FVector InNormal)
{
	if (IsInvalidFaceIndex(PHit.faceIndex))
	{
		return InNormal;
	}

	PxConvexMeshGeometry PConvexMeshGeom;
	bool bSuccess = PHit.shape->getConvexMeshGeometry(PConvexMeshGeom);
	check(bSuccess);	//should only call this function when we have a convex mesh

	if (PConvexMeshGeom.convexMesh)
	{
		check(PHit.faceIndex < PConvexMeshGeom.convexMesh->getNbPolygons());

		const PxU32 PolyIndex = PHit.faceIndex;
		PxHullPolygon PPoly;
		bool bSuccessData = PConvexMeshGeom.convexMesh->getPolygonData(PolyIndex, PPoly);
		if (bSuccessData)
		{
			// Account for non-uniform scale in local space normal.
			const PxVec3 PPlaneNormal(PPoly.mPlane[0], PPoly.mPlane[1], PPoly.mPlane[2]);
			const PxVec3 PLocalPolyNormal = TransformNormalToShapeSpace(PConvexMeshGeom.scale, PPlaneNormal.getNormalized());

			// Convert to world space
			const PxTransform PShapeWorldPose = PxShapeExt::getGlobalPose(*PHit.shape, *PHit.actor);
			const PxVec3 PWorldPolyNormal = PShapeWorldPose.rotate(PLocalPolyNormal);
			const FVector OutNormal = P2UVector(PWorldPolyNormal);

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
			if (!OutNormal.IsNormalized())
			{
				UE_LOG(LogPhysics, Warning, TEXT("Non-normalized Normal (Hit shape is ConvexMesh): %s (LocalPolyNormal:%s)"), *OutNormal.ToString(), *P2UVector(PLocalPolyNormal).ToString());
				UE_LOG(LogPhysics, Warning, TEXT("WorldTransform \n: %s"), *P2UTransform(PShapeWorldPose).ToString());
			}
#endif
			return OutNormal;
		}
	}

	return InNormal;
}
bool PxFabricCookerImpl::cook(const PxClothMeshDesc& desc, PxVec3 gravity, bool useGeodesicTether)
{	
	if(!desc.isValid())
	{
		shdfnd::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
			"PxFabricCookerImpl::cook: desc.isValid() failed!");
		return false;
	}

	gravity = gravity.getNormalized();

	mNumParticles = desc.points.count;

	// assemble points
	shdfnd::Array<PxVec4> particles;
	particles.reserve(mNumParticles);
	PxStrideIterator<const PxVec3> pIt((const PxVec3*)desc.points.data, desc.points.stride);
	PxStrideIterator<const PxReal> wIt((const PxReal*)desc.invMasses.data, desc.invMasses.stride);
	for(PxU32 i=0; i<mNumParticles; ++i)
		particles.pushBack(PxVec4(*pIt++, wIt.ptr() ? *wIt++ : 1.0f));

	// build adjacent vertex list
	shdfnd::Array<PxU32> valency(mNumParticles+1, 0);
	shdfnd::Array<PxU32> adjacencies;
	if(desc.flags & PxMeshFlag::e16_BIT_INDICES)
		gatherAdjacencies<PxU16>(valency, adjacencies, desc.triangles, desc.quads);
	else
		gatherAdjacencies<PxU32>(valency, adjacencies, desc.triangles, desc.quads);

	// build unique neighbors from adjacencies
	shdfnd::Array<PxU32> mark(valency.size(), 0);
	shdfnd::Array<PxU32> neighbors; neighbors.reserve(adjacencies.size());
	for(PxU32 i=1, j=0; i<valency.size(); ++i)
	{
		for(; j<valency[i]; ++j)
		{
			PxU32 k = adjacencies[j];
			if(mark[k] != i)
			{
				mark[k] = i;
				neighbors.pushBack(k);
			}
		}
		valency[i] = neighbors.size();
	}

	// build map of unique edges and classify
	shdfnd::HashMap<Pair, Edge> edges;
	for(PxU32 i=0; i<mNumParticles; ++i)
	{
		PxReal wi = particles[i].w;
		// iterate all neighbors
		PxU32 jlast = valency[i+1];
		for(PxU32 j=valency[i]; j<jlast; ++j)
		{
			// add 1-ring edge
			PxU32 m = neighbors[j];
			if(wi + particles[m].w > 0.0f)
				edges[Pair(PxMin(i, m), PxMax(i, m))].classify();

			// iterate all neighbors of neighbor
			PxU32 klast = valency[m+1];
			for(PxU32 k=valency[m]; k<klast; ++k)
			{
				PxU32 n = neighbors[k];
				if(n != i && wi + particles[n].w > 0.0f)
				{
					// add 2-ring edge
					edges[Pair(PxMin(i, n), PxMax(i, n))].classify(
						particles[i], particles[m], particles[n]);
				}
			}
		}
	}

	// copy classified edges to constraints array
	// build histogram of constraints per vertex
	shdfnd::Array<Entry> constraints; 	
	constraints.reserve(edges.size());
	valency.resize(0); valency.resize(mNumParticles+1, 0);

	const PxReal sqrtHalf = PxSqrt(0.4f);
	for(shdfnd::HashMap<Pair, Edge>::Iterator eIt = edges.getIterator(); !eIt.done(); ++eIt)
	{
		const Edge& edge = eIt->second;
		const Pair& pair = eIt->first;
		if((edge.mStretching + edge.mBending + edge.mShearing) > 0.0f)
		{	
			PxClothFabricPhaseType::Enum type = PxClothFabricPhaseType::eINVALID;
			if(edge.mBending > PxMax(edge.mStretching, edge.mShearing))
				type = PxClothFabricPhaseType::eBENDING;
			else if(edge.mShearing > PxMax(edge.mStretching, edge.mBending))
				type = PxClothFabricPhaseType::eSHEARING;
			else 
			{
				PxVec4 diff = particles[pair.first]-particles[pair.second];
				PxReal dot = gravity.dot(reinterpret_cast<const PxVec3&>(diff).getNormalized());
				type = fabsf(dot) < sqrtHalf ? PxClothFabricPhaseType::eHORIZONTAL : PxClothFabricPhaseType::eVERTICAL;
			}
			++valency[pair.first];
			++valency[pair.second];
			constraints.pushBack(Entry(pair, type));
		}
	} 

	prefixSum(valency.begin(), valency.end(), valency.begin());

	PxU32 numConstraints = constraints.size();

	// build adjacent constraint list
	adjacencies.resize(0); adjacencies.resize(valency.back(), 0);
	for(PxU32 i=0; i<numConstraints; ++i)
	{
		adjacencies[--valency[constraints[i].first.first]] = i;
		adjacencies[--valency[constraints[i].first.second]] = i;
	}
	
	shdfnd::Array<PxU32>::ConstIterator aFirst = adjacencies.begin();
	shdfnd::Array<PxU32> colors(numConstraints, numConstraints); // constraint -> color, initialily not colored
	mark.resize(0); mark.resize(numConstraints+1, PX_MAX_U32); // color -> constraint index
	shdfnd::Array<PxU32> adjColorCount(numConstraints, 0); // # of neighbors that are already colored

	shdfnd::Array<ConstraintGraphColorCount> constraintHeap; 
	constraintHeap.reserve(numConstraints); // set of constraints to color (added in edge distance order)

	// Do graph coloring based on edge distance.
	// For each constraint, we add its uncolored neighbors to the heap
	// ,and we pick the constraint with most colored neighbors from the heap.
	while (1)
	{
		PxU32 constraint = 0;
		while ( (constraint < numConstraints) && (colors[constraint] != numConstraints))
			constraint++; // start with the first uncolored constraint
	
		if (constraint >= numConstraints)
			break;

		constraintHeap.clear();
		pushHeap(constraintHeap, ConstraintGraphColorCount((int)constraint, (int)adjColorCount[constraint]));
		PxClothFabricPhaseType::Enum type = constraints[constraint].second;
		
		while (!constraintHeap.empty())
		{		
			ConstraintGraphColorCount heapItem = popHeap(constraintHeap);
			constraint = heapItem.constraint;
			if (colors[constraint] != numConstraints)
				continue; // skip if already colored 

			const Pair& pair = constraints[constraint].first;			
			for(PxU32 j=0; j<2; ++j)
			{
				PxU32 index = j ? pair.first : pair.second;
				if(particles[index].w == 0.0f)
					continue; // don't mark adjacent particles if attached

				for(shdfnd::Array<PxU32>::ConstIterator aIt = aFirst + valency[index], aEnd = aFirst + valency[index+1]; aIt != aEnd; ++aIt)
				{				
					PxU32 adjacentConstraint = *aIt;
					if ((constraints[adjacentConstraint].second != type) || (adjacentConstraint == constraint))
						continue;

					mark[colors[adjacentConstraint]] = constraint; 
					++adjColorCount[adjacentConstraint];
					pushHeap(constraintHeap, ConstraintGraphColorCount((int)adjacentConstraint, (int)adjColorCount[adjacentConstraint]));
				}
			}

			// find smallest color with matching type
			PxU32 color = 0;
			while((color < mPhases.size() && mPhases[color].phaseType != type) || mark[color] == constraint)
				++color;

			// create a new color set
			if(color == mPhases.size())
			{
				PxClothFabricPhase phase(type, mPhases.size());
				mPhases.pushBack(phase);
				mSets.pushBack(0);
			}

			colors[constraint] = color;
			++mSets[color];
		} 
	}

#if 0 // PX_DEBUG
	printf("set[%u] = ", mSets.size());
	for(PxU32 i=0; i<mSets.size(); ++i)
		printf("%u ", mSets[i]);
#endif

	prefixSum(mSets.begin(), mSets.end(), mSets.begin());

#if 0 // PX_DEBUG
	printf(" = %u\n", mSets.back());
#endif

	// write indices and rest lengths
	// convert mSets to exclusive sum
	PxU32 back = mSets.back();
	mSets.pushBack(back);
	mIndices.resize(numConstraints*2);
	mRestvalues.resize(numConstraints);
	for(PxU32 i=0; i<numConstraints; ++i)
	{
		PxU32 first = constraints[i].first.first;
		PxU32 second = constraints[i].first.second;

		PxU32 index = --mSets[colors[i]];

		mIndices[2*index  ] = first;
		mIndices[2*index+1] = second;

		PxVec4 diff = particles[second] - particles[first];
		mRestvalues[index] = reinterpret_cast<
			const PxVec3&>(diff).magnitude();
	} 
	
	// reorder constraints and rest values for more efficient cache access (linear)
	shdfnd::Array<PxU32> newIndices(mIndices.size());
	shdfnd::Array<PxF32> newRestValues(mRestvalues.size());

	// sort each constraint set in vertex order
	for (PxU32 i=0; i < mSets.size()-1; ++i)
	{
		// create a re-ordering list
		shdfnd::Array<PxU32> reorder(mSets[i+1]-mSets[i]);

		for (PxU32 r=0; r < reorder.size(); ++r)
			reorder[r] = r;

		const PxU32 indicesOffset = mSets[i]*2;
		const PxU32 restOffset = mSets[i];

		ConstraintSorter predicate(&mIndices[indicesOffset]);
		shdfnd::sort(&reorder[0], reorder.size(), predicate);
		
		for (PxU32 r=0; r < reorder.size(); ++r)
		{
			newIndices[indicesOffset + r*2] = mIndices[indicesOffset + reorder[r]*2];
			newIndices[indicesOffset + r*2+1] = mIndices[indicesOffset + reorder[r]*2+1];
			newRestValues[restOffset + r] = mRestvalues[restOffset + reorder[r]];
		}
	}

	mIndices = newIndices;
	mRestvalues = newRestValues;

	PX_ASSERT(mIndices.size() == mRestvalues.size()*2);
	PX_ASSERT(mRestvalues.size() == mSets.back());

#if 0 // PX_DEBUG
	for (PxU32 i = 1; i < mSets.size(); i++)
	{
		PxClothFabricPhase phase = mPhases[i-1];
		printf("%d : type %d, size %d\n", 
			i-1, phase.phaseType, mSets[i] - mSets[i-1]);
	}
#endif

	if (useGeodesicTether)
	{
		PxClothGeodesicTetherCooker tetherCooker(desc);
		if (tetherCooker.getCookerStatus() == 0)
		{
			PxU32 numTethersPerParticle = tetherCooker.getNbTethersPerParticle();
			PxU32 tetherSize = mNumParticles * numTethersPerParticle;
			mTetherAnchors.resize(tetherSize);
			mTetherLengths.resize(tetherSize);
			tetherCooker.getTetherData(mTetherAnchors.begin(), mTetherLengths.begin());
		}
		else
			useGeodesicTether = false;
	}

	if (!useGeodesicTether)
	{
		PxClothSimpleTetherCooker tetherCooker(desc);
		mTetherAnchors.resize(mNumParticles);
		mTetherLengths.resize(mNumParticles);
		tetherCooker.getTetherData(mTetherAnchors.begin(), mTetherLengths.begin());
	}

	return true;
}
void Gu::TriangleMesh::debugVisualize(
	Cm::RenderOutput& out, const PxTransform& pose, const PxMeshScale& scaling, const PxBounds3& cullbox,
	const PxU64 mask, const PxReal fscale, const PxU32 numMaterials) const 
{
	PX_UNUSED(numMaterials);

	//bool cscale = !!(mask & ((PxU64)1 << PxVisualizationParameter::eCULL_BOX));
	const PxU64 cullBoxMask = PxU64(1) << PxVisualizationParameter::eCULL_BOX;
	bool cscale = ((mask & cullBoxMask) == cullBoxMask);

	const PxMat44 midt(PxIdentity);
	const Cm::Matrix34 absPose(PxMat33(pose.q) * scaling.toMat33(), pose.p);

	PxU32 nbTriangles = getNbTrianglesFast();
	const PxU32 nbVertices = getNbVerticesFast();
	const PxVec3* vertices = getVerticesFast();
	const void* indices = getTrianglesFast();

	const PxDebugColor::Enum colors[] = 
	{
		PxDebugColor::eARGB_BLACK,		
		PxDebugColor::eARGB_RED,		
		PxDebugColor::eARGB_GREEN,		
		PxDebugColor::eARGB_BLUE,		
		PxDebugColor::eARGB_YELLOW,	
		PxDebugColor::eARGB_MAGENTA,	
		PxDebugColor::eARGB_CYAN,		
		PxDebugColor::eARGB_WHITE,		
		PxDebugColor::eARGB_GREY,		
		PxDebugColor::eARGB_DARKRED,	
		PxDebugColor::eARGB_DARKGREEN,	
		PxDebugColor::eARGB_DARKBLUE,	
	};

	const PxU32 colorCount = sizeof(colors)/sizeof(PxDebugColor::Enum);

	if(cscale)
	{
		const Gu::Box worldBox(
			(cullbox.maximum + cullbox.minimum)*0.5f,
			(cullbox.maximum - cullbox.minimum)*0.5f,
			PxMat33(PxIdentity));
		
		// PT: TODO: use the callback version here to avoid allocating this huge array
		PxU32* results = reinterpret_cast<PxU32*>(PX_ALLOC_TEMP(sizeof(PxU32)*nbTriangles, "tmp triangle indices"));
		LimitedResults limitedResults(results, nbTriangles, 0);
		Midphase::intersectBoxVsMesh(worldBox, *this, pose, scaling, &limitedResults);
		nbTriangles = limitedResults.mNbResults;

		if (fscale)
		{
			const PxU32 fcolor = PxU32(PxDebugColor::eARGB_DARKRED);

			for (PxU32 i=0; i<nbTriangles; i++)
			{
				const PxU32 index = results[i];
				PxVec3 wp[3];
				getTriangle(*this, index, wp, vertices, indices, absPose, has16BitIndices());

				const PxVec3 center = (wp[0] + wp[1] + wp[2]) / 3.0f;
				PxVec3 normal = (wp[0] - wp[1]).cross(wp[0] - wp[2]);
				PX_ASSERT(!normal.isZero());
				normal = normal.getNormalized();

				out << midt << fcolor <<
						Cm::DebugArrow(center, normal * fscale);
			}
		}

		if (mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_SHAPES))
		{
			const PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA);

			out << midt << scolor;	// PT: no need to output this for each segment!

			PxDebugLine* segments = out.reserveSegments(nbTriangles*3);
			for(PxU32 i=0; i<nbTriangles; i++)
			{
				const PxU32 index = results[i];
				PxVec3 wp[3];
				getTriangle(*this, index, wp, vertices, indices, absPose, has16BitIndices());
				segments[0] = PxDebugLine(wp[0], wp[1], scolor);
				segments[1] = PxDebugLine(wp[1], wp[2], scolor);
				segments[2] = PxDebugLine(wp[2], wp[0], scolor);
				segments+=3;
			}
		}

		if ((mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_EDGES)) && mExtraTrigData)
			visualizeActiveEdges(out, *this, nbTriangles, results, absPose, midt);

		PX_FREE(results);
	}
	else
	{
		if (fscale)
		{
			const PxU32 fcolor = PxU32(PxDebugColor::eARGB_DARKRED);

			for (PxU32 i=0; i<nbTriangles; i++)
			{
				PxVec3 wp[3];
				getTriangle(*this, i, wp, vertices, indices, absPose, has16BitIndices());

				const PxVec3 center = (wp[0] + wp[1] + wp[2]) / 3.0f;
				PxVec3 normal = (wp[0] - wp[1]).cross(wp[0] - wp[2]);
				PX_ASSERT(!normal.isZero());
				normal = normal.getNormalized();

				out << midt << fcolor <<
						Cm::DebugArrow(center, normal * fscale);
			}
		}

		if (mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_SHAPES))
		{
			PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA);

			out << midt << scolor;	// PT: no need to output this for each segment!

			PxVec3* transformed = reinterpret_cast<PxVec3*>(PX_ALLOC(sizeof(PxVec3)*nbVertices, "PxVec3"));
			for(PxU32 i=0;i<nbVertices;i++)
				transformed[i] = absPose.transform(vertices[i]);

			PxDebugLine* segments = out.reserveSegments(nbTriangles*3);
			for (PxU32 i=0; i<nbTriangles; i++)
			{
				PxVec3 wp[3];
				getTriangle(*this, i, wp, transformed, indices, has16BitIndices());
				const PxU32 localMaterialIndex = getTriangleMaterialIndex(i);
				scolor = colors[localMaterialIndex % colorCount];
				
				segments[0] = PxDebugLine(wp[0], wp[1], scolor);
				segments[1] = PxDebugLine(wp[1], wp[2], scolor);
				segments[2] = PxDebugLine(wp[2], wp[0], scolor);
				segments+=3;
			}

			PX_FREE(transformed);
		}

		if ((mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_EDGES)) && mExtraTrigData)
			visualizeActiveEdges(out, *this, nbTriangles, NULL, absPose, midt);
	}
}
void Gu::TriangleMesh::debugVisualize(
	Cm::RenderOutput& out, const Cm::Matrix34& absPose, const PxBounds3& cullbox,
	const PxU64 mask, const PxReal fscale)	const
{
	bool cscale = !!(mask & ((PxU64)1 << PxVisualizationParameter::eCULL_BOX));

	const PxMat44 midt = PxMat44::createIdentity();

	const PxU32 nbTriangles = mesh.getNumTriangles();
	const PxU32 nbVertices = mesh.getNumVertices();
	const PxVec3* vertices = mesh.getVertices();
	const void* indices = getTrianglesFast();

	const bool has16BitIndices = mesh.has16BitIndices();

	if (fscale)
	{
		const PxU32 fcolor = PxDebugColor::eARGB_DARKRED;

		for (PxU32 i=0; i<nbTriangles; i++)
		{
			PxVec3 wp[3];
			getTriangle(*this, i, wp, vertices, indices, absPose, has16BitIndices);

			const PxVec3 center = (wp[0] + wp[1] + wp[2]) / 3.0f;
			PxVec3 normal = (wp[0] - wp[1]).cross(wp[0] - wp[2]);
			PX_ASSERT(!normal.isZero());
			normal = normal.getNormalized();

			if (!cscale || cullbox.contains(center))
				out << midt << fcolor <<
					Cm::DebugArrow(center, normal * fscale);
		}
	}

	if (mask & ((PxU64)1 << PxVisualizationParameter::eCOLLISION_SHAPES))
	{
		const PxU32 scolor = PxDebugColor::eARGB_MAGENTA;

		out << midt << scolor;	// PT: no need to output this for each segment!

		// PT: transform vertices only once
		PxVec3* transformed = (PxVec3*)PX_ALLOC(sizeof(PxVec3)*nbVertices);
		for(PxU32 i=0;i<nbVertices;i++)
			transformed[i] = absPose.transform(vertices[i]);

		for (PxU32 i=0; i<nbTriangles; i++)
		{
			PxVec3 wp[3];
			getTriangle(*this, i, wp, transformed, indices, has16BitIndices);

			if (!cscale || (cullbox.contains(wp[0]) && cullbox.contains(wp[1]) && cullbox.contains(wp[2])))
			{
				out.outputSegment(wp[0], wp[1]);
				out.outputSegment(wp[1], wp[2]);
				out.outputSegment(wp[2], wp[0]);
			}
		}

		PX_FREE(transformed);
	}

	if (mask & ((PxU64)1 << PxVisualizationParameter::eCOLLISION_EDGES))
	{
		const PxU32 ecolor = PxDebugColor::eARGB_YELLOW;

		for (PxU32 i=0; i<nbTriangles; i++)
		{
			PxVec3 wp[3];
			getTriangle(*this, i, wp, vertices, indices, absPose, has16BitIndices);

			const PxU32 flags = mesh.getTrigSharedEdgeFlags(i);

			if(flags & Gu::ETD_CONVEX_EDGE_01)
			{
				if (!cscale || (cullbox.contains(wp[0]) && cullbox.contains(wp[1])))
					out << midt << ecolor << Cm::RenderOutput::LINES << wp[0] << wp[1];
			}
			if(flags & Gu::ETD_CONVEX_EDGE_12)
			{
				if (!cscale || (cullbox.contains(wp[1]) && cullbox.contains(wp[2])))
					out << midt << ecolor << Cm::RenderOutput::LINES << wp[1] << wp[2];
			}
			if(flags & Gu::ETD_CONVEX_EDGE_20)
			{
				if (!cscale || (cullbox.contains(wp[0]) && cullbox.contains(wp[2])))
					out << midt << ecolor << Cm::RenderOutput::LINES << wp[0] << wp[2];
			}
		}
	}
}
Example #11
0
void Enemy::Update(float dT)
{
	UpdateBullets(dT);
	obj->Update(dT);
	if(!isDead)
	{
		currentMoveTime += dT;
		if(currentMoveTime > movementSwitchTime)
		{
			currentMoveTime = 0;
			float xspeed = rand()% (int)ceil(movementSpeed); //getal van 0 tot 10
			float xfSpeed = xspeed - (int)ceil(movementSpeed)/2; // getal van -5 tot 5
			float zspeed = rand()%(int)ceil(movementSpeed); //getal van 0 tot 10
			float zfSpeed = zspeed -(int)ceil( movementSpeed)/2; // getal van -5 tot 5
			
			moveDir = D3DXVECTOR3(xfSpeed, 0, zfSpeed);
		}
		PxVec3 pos = actor->getGlobalPose().p;
		PxVec3 pDir = (playerPos - pos);
		pDir.y = 0;
		pDir.normalize();
		PxVec3 target = PxVec3(moveDir.x,0,moveDir.z);
		float angle = 90 - (90 * pDir.dot(target.getNormalized())) - 90; //mapping range 1 to -1 into 0-180 if desirable
		playerRight.y = 0;
		float direction = playerRight.dot(target.getNormalized());
		if(direction < 0 && angle > -45 && angle < 45)
		{
			angle = -angle;		
		}
		Object2D::Animation* cAnim = obj->GetCurrentAnim();
		Object2D::Animation anim;
		if(angle < -45)
		{
			cMState = MovementState::Forward; 
			anim = obj->GetAnimation("WalkForward");
			if(anim.isFinished || cAnim->AnimationName.compare(anim.AnimationName) != 0)
			{
				obj->PlayAnimation("WalkForward");
			}	
		}
		if(angle > -45 && angle < 0 && direction < 0)
		{
			cMState = MovementState::Left;
			anim = obj->GetAnimation("WalkLeft");
			if(anim.isFinished || cAnim->AnimationName.compare(anim.AnimationName) != 0)
			{
				obj->PlayAnimation("WalkLeft");
			}
		}
		else if(angle > 0 && angle < 45 && direction > 0)
		{
			cMState = MovementState::Right; 
			anim = obj->GetAnimation("WalkRight");
			if(anim.isFinished || cAnim->AnimationName.compare(anim.AnimationName) != 0)
			{
				obj->PlayAnimation("WalkRight");
			}
		}
		if(angle > -45 && angle < 0 && direction > 0)
		{
			cMState = MovementState::Right; 
			anim = obj->GetAnimation("WalkRight");
			if(anim.isFinished || cAnim->AnimationName.compare(anim.AnimationName) != 0)
			{
				obj->PlayAnimation("WalkRight");
			}
		}
		else if(angle > 0 && angle < 45 && direction < 0)
		{
			cMState = MovementState::Left;
			anim = obj->GetAnimation("WalkLeft");
			if(anim.isFinished || cAnim->AnimationName.compare(anim.AnimationName) != 0)
			{
				obj->PlayAnimation("WalkLeft");
			}
		}
		if(angle > 45)
		{
			cMState = MovementState::Back;
			anim = obj->GetAnimation("WalkBack");
			if(anim.isFinished || cAnim->AnimationName.compare(anim.AnimationName) != 0)
			{
				obj->PlayAnimation("WalkBack");
			}		
		}
		CheckShooting(30,dT*1.2f);
		if(sawPlayer)
		{
			cState = Enemy::Moving;
			int i = 0;
			CheckFutureCollision(i);
			Move(moveDir,dT*movementSpeed);
		}
	}
}
Example #12
0
void RenderPhysX3Debug::addConeExt(float r0, float r1, const PxVec3& p0, const PxVec3& p1 , const RendererColor& color, PxU32 renderFlags)
{
	PxVec3 axis = p1 - p0;
	PxReal length = axis.magnitude();
	PxReal rdiff = r0 - r1;
	PxReal sinAngle = rdiff / length;
	PxReal x0 = r0 * sinAngle;
	PxReal x1 = r1 * sinAngle;
	PxVec3 center = 0.5f * (p0 + p1);

	if (length < fabs(rdiff))
		return;

	PxReal r0p = sqrt(r0 * r0 - x0 * x0);
	PxReal r1p = sqrt(r1 * r1 - x1 * x1);

	if (length == 0.0f)
		axis = PxVec3(1,0,0);
	else
		axis.normalize();

	PxVec3 axis1(0.0f);
	axis1[minArgument(abs(axis))] = 1.0f;
	axis1 = axis1.cross(axis);
	axis1.normalize();

	PxVec3 axis2 = axis.cross(axis1);
	axis2.normalize();

	PxMat44 m;
	m.column0 = PxVec4(axis, 0.0f);
	m.column1 = PxVec4(axis1, 0.0f);
	m.column2 = PxVec4(axis2, 0.0f);
	m.column3 = PxVec4(center, 1.0f);

	PxTransform tr(m);

#define NUM_CONE_VERTS 72
	const PxU32 nbVerts = NUM_CONE_VERTS;

	PxVec3 pts0[NUM_CONE_VERTS] ;
	PxVec3 pts1[NUM_CONE_VERTS];
	PxVec3 normals[NUM_CONE_VERTS] ;

	const float step = PxTwoPi / float(nbVerts);
	for (PxU32 i = 0; i < nbVerts; i++)
	{
		const float angle = float(i) * step;
		const float x = cosf(angle);
		const float y = sinf(angle);

		PxVec3 p = PxVec3(0.0f, x, y);

		pts0[i] = tr.transform(r0p * p + PxVec3(-0.5f * length + x0,0,0));
		pts1[i] = tr.transform(r1p * p + PxVec3(0.5f * length + x1, 0, 0));

		normals[i] = tr.q.rotate(p.getNormalized());
		normals[i] = x0 * axis + r0p * normals[i];
		normals[i].normalize();
	}
#undef NUM_CONE_VERTS

	if(renderFlags & RENDER_DEBUG_WIREFRAME)
	{
		for(PxU32 i=0;i<nbVerts;i++)
		{
			addLine(pts1[i], pts0[i], color);
		}
	}

	if(renderFlags & RENDER_DEBUG_SOLID)
	{
		for(PxU32 i=0;i<nbVerts;i++)
		{
			const PxU32 j = (i+1) % nbVerts;
			addTriangle(pts0[i], pts1[j], pts0[j], normals[i], normals[j], normals[j], color);
			addTriangle(pts0[i], pts1[i], pts1[j], normals[i], normals[i], normals[j], color);
		}
	}

}
Example #13
0
void CurrentApp::Update(float dt)
{
	//Update the camera for movement
	m_camera->Update(dt);
	m_particleEmitter->update(dt);

	glm::vec3 pos = glm::vec3(100 * cos(CurrentTime() * 0.05f) + 150, 80, 100 * sin(CurrentTime() * 0.05f) + 150);
	m_fairyEmitter->SetPosition(pos);
	m_light->SetPosition(pos);

	for (int i = 0; i < 5; ++i)
	{
		m_AI[i]->update(dt);
	}

	Input* IM = Input::GetInstance();

	glm::mat4 cameraWorld = m_camera->GetTransform();
	PxVec3 displacement = PxVec3(0, 0, 0);
	bool notZero = false;
	bool m_canFly = false;

	if (IM->IsKeyDown('W'))
	{
		displacement -= PxVec3(cameraWorld[2].x, (m_canFly ? cameraWorld[2].y : 0), cameraWorld[2].z);
		notZero = true;
	}
	if (IM->IsKeyDown('A'))
	{
		displacement -= PxVec3(cameraWorld[0].x, (m_canFly ? cameraWorld[0].y : 0), cameraWorld[0].z);
		notZero = true;
	}
	if (IM->IsKeyDown('S'))
	{
		displacement += PxVec3(cameraWorld[2].x, (m_canFly ? cameraWorld[2].y : 0), cameraWorld[2].z);
		notZero = true;
	}
	if (IM->IsKeyDown('D'))
	{
		displacement += PxVec3(cameraWorld[0].x, (m_canFly ? cameraWorld[0].y : 0), cameraWorld[0].z);
		notZero = true;
	}

	if (notZero)
		displacement = displacement.getNormalized();

	if (m_verticleSpeed > -10.0f && !m_canFly || m_verticleSpeed > 0 && m_canFly)
		m_verticleSpeed -= dt;

	displacement.y += m_verticleSpeed;

	PxControllerFilters filters;
	g_PlayerController->move(displacement, 0.01f, dt, filters);

	PxExtendedVec3 playerPos = g_PlayerController->getPosition();
	PxExtendedVec3 footPos = g_PlayerController->getFootPosition();
	//I do these calculations individually inside this vector constructor because PxEtendedVec3 doesn't contain some of the necessary operators to do this.
	vec3 endPos = vec3(2.0f * playerPos.x - footPos.x, 2.0f * playerPos.y - footPos.y, 2.0f * playerPos.z - footPos.z);
	m_camera->SetPosition(endPos);

	//Freeze the physics
	if (m_freezePhysics == false) 
	{ 
		UpdatePhysx(dt); 
	}
	else 
	{ 
		UpdatePhysx(0); 
	}

	//Generate new map
	if (Input::GetInstance()->IsKeyPressed('R'))
	{
		m_terrain->GenerateFromPerlin();
		m_terrain->AddPhysicsShape(g_PhysicsScene, g_Physics);
		m_nodeMap->GenerateFromTerrain(m_terrain);
		m_world->Generate();

		for (unsigned int i = 0; i < g_PhysXActors.size(); ++i)
		{
			PxTransform transform(PxVec3(150, 5 + (1.1f * i), 150));
			g_PhysXActors[i]->setGlobalPose(transform);
		}
	}

	if (Input::GetInstance()->IsKeyPressed('N'))
	{
		m_nodeMap->GenerateFromTerrain(m_terrain);
		m_nodeMap->Draw();
	}

	//Freeze Physics
	if (Input::GetInstance()->IsKeyPressed(GLFW_KEY_PAUSE)) { m_freezePhysics = !m_freezePhysics; }

	//Hide/Show Cursor
	if (Input::GetInstance()->IsKeyPressed(KEY_ESCAPE)) { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); }
	if (Input::GetInstance()->IsMousePressed(MOUSE_BUTTON_LEFT)) { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); }

	//Deffered/Forward
	if (Input::GetInstance()->IsKeyPressed(KEY_F5)) { m_isDeffered = !m_isDeffered; }
	if (Input::GetInstance()->IsKeyPressed(KEY_F6)) { m_drawDebug = !m_drawDebug; }
}