Exemplo n.º 1
0
void CC3MeshNode::addShadowVolumesForLight( CC3Light* aLight )
{
	// If I shouldn't cast a shadow, or if I already have a shadow volume, just leave.
	if ( !shouldCastShadows() || getShadowVolumeForLight( aLight ) )
		return;

#pragma _NOTE_TODO( "CC3MeshNode::addShadowVolumesForLight( CC3Light* aLight )" )
	std::string svName = CC3String::stringWithFormat( "%s-SV-%s", getName().c_str(), aLight->getName().c_str() );
	CC3ShadowVolumeMeshNode* sv = CC3ShadowVolumeMeshNode::nodeWithName( svName );
	sv->selectShaders();

	// Retain data required to build shadow volume mesh
	retainVertexLocations();
	retainVertexIndices();
	setShouldCacheFaces( true );

	prewarmForShadowVolumes();		// Force heavy face calcs now instead of lazily during drawing.

	// Set the active camera to infinite depth of field to accomodate infinite shadow volumes
	getActiveCamera()->setHasInfiniteDepthOfField( true );

	aLight->addShadow( sv );			// Add to light before notifying scene a descendant has been added
	addChild( sv );			// The last thing we do is add the SV to the scene...
	// ...because we might be doing this on a background thread.
	//LogTrace(@"Added shadow volume %@ to %@", sv, self);

	super::addShadowVolumesForLight( aLight );
}
Exemplo n.º 2
0
void Plane::draw(std::shared_ptr< FrameEventArgs > args) {
	auto scene = this->getGameObjectSet().lock()->getOwner();
	auto camera = scene->getActiveCamera();
	auto cameraTransform = camera->getComponents()->getSingleByClass<Transform>();

	this->recalculateForPositionAndTime(cameraTransform->getPosition(), args->getTotalSeconds());

	if(this->axesVisible) {
		drawAxes(50);
	}

	Vertex* base = this->vertices.get();
	Vertex* v1 = 0;
	Vertex* v2 = 0;
	Vertex* v3 = 0;
	Vertex* v4 = 0;

		
	this->setupMaterial();

	glBegin(GL_TRIANGLES);

	for(int xsegment = 0; xsegment < this->segments; ++xsegment) {
		for(int zsegment = 0; zsegment < this->segments; ++zsegment) {
			v1 = base + this->vertexIndex(xsegment, zsegment);
			v2 = base + this->vertexIndex(xsegment + 1, zsegment);
			v3 = base + this->vertexIndex(xsegment + 1, zsegment + 1);
			v4 = base + this->vertexIndex(xsegment, zsegment + 1);

			// These normals are here only to show lighting effect, they're not proper normals

			glNormal3fv(v1->normal);
			glTexCoord2fv(v1->texcoord);
			glVertex3fv(v1->position);

			glNormal3fv(v2->normal);
			glTexCoord2fv(v2->texcoord);
			glVertex3fv(v2->position);

			glNormal3fv(v4->normal);
			glTexCoord2fv(v4->texcoord);
			glVertex3fv(v4->position);


			glNormal3fv(v2->normal);
			glTexCoord2fv(v2->texcoord);
			glVertex3fv(v2->position);

			glNormal3fv(v3->normal);
			glTexCoord2fv(v3->texcoord);
			glVertex3fv(v3->position);

			glNormal3fv(v4->normal);
			glTexCoord2fv(v4->texcoord);
			glVertex3fv(v4->position);
		}
	}
		
	glEnd();
	glDisable(GL_TEXTURE_2D);

	if(this->normalsVisible) {
		this->drawNormals();
	}
}
Exemplo n.º 3
0
/**
 * Returns a 4D directional vector which can be added to each vertex when creating
 * the shadow volume vertices from the corresponding shadow caster vertices.
 *
 * The returned vector is in the local coordinate system of the shadow caster.
 *
 * The returned directional vector is a small offset vector in the direction away
 * from the light. A unit vector in that direction is scaled by both the distance
 * from the center of the shadow casting node to the camera and the
 * shadowVolumeVertexOffsetFactor property. Hence, if the shadow caster is farther
 * away from the camera, the returned value will be larger, to reduce the chance
 * of Z-fighting between the faces of the shadow volume and the shadow caster.
 */
CC3Vector4 CC3ShadowVolumeMeshNode::getShadowVolumeVertexOffsetForLightAt( const CC3Vector4& localLightPos )
{
	CC3Vector scLoc = getShadowCaster()->getLocalContentCenterOfGeometry();
	CC3Vector lgtLoc = localLightPos.cc3Vector();
	CC3Vector camLoc = getShadowCaster()->getGlobalTransformMatrixInverted()->transformLocation( getActiveCamera()->getGlobalLocation() );	

	// Get a unit offset vector in the direction away from the light
	CC3Vector offsetDir = (_light->isDirectionalOnly()
												? lgtLoc.negate() 
												: scLoc.difference( lgtLoc )).normalize();

	// Get the distance from the shadow caster CoG and the camera, and scale the
	// unit offset vector by that distance and the shadowVolumeVertexOffsetFactor
	GLfloat camDist = scLoc.distance( camLoc );
	CC3Vector offset = offsetDir.scaleUniform( camDist * _shadowVolumeVertexOffsetFactor );
	CC3_TRACE("CC3ShadowVolumeMeshNode nudging vertices by %s", offset.stringfy().c_str());

	// Create and return a 4D directional vector from the offset
	return CC3Vector4().fromDirection(offset);
}