/**
 * Calculate the end of the directonal marker line.
 *
 * This is done by calculating the scale we need to multiply the directional marker by to
 * reach each of the three sides of the bounding box, then take the smallest of these,
 * because that is the side it will intersect. Finally, multiply by an overall scale factor.
 */
CC3Vector CC3DirectionMarkerNode::calculateLineEnd()
{
	CC3Box pbb = getParentBoundingBox();
	CC3Vector md = getMarkerDirection();
	
	CC3Vector pbbDirScale = cc3v(calcScale( md.x, pbb.minimum.x, pbb.maximum.x ),
								 calcScale( md.y, pbb.minimum.y, pbb.maximum.y ),
								 calcScale( md.z, pbb.minimum.z, pbb.maximum.z ));
	//CC3_PUSH_NOSHADOW
	GLfloat dirScale = MIN(pbbDirScale.x, MIN(pbbDirScale.y, pbbDirScale.z));
	dirScale = dirScale * getDirectionMarkerScale();
	//CC3_POP_NOSHADOW

	// Ensure that the direction marker has the minimum length specified by directionMarkerMinimumLength
	if (directionMarkerMinimumLength) {
		GLfloat gblUniScale = getGlobalScale().length() / CC3Vector::kCC3VectorUnitCubeLength;
		GLfloat minScale = directionMarkerMinimumLength / gblUniScale;
		dirScale = MAX(dirScale, minScale);
	}

	CC3Vector lineEnd = md.scaleUniform( dirScale );
	//LogTrace(@"%@ calculated line end %@ from pbb scale %@ and dir scale %.3f and min global length: %.3f", self,
	//		 NSStringFromCC3Vector(lineEnd), NSStringFromCC3Vector(pbbDirScale), dirScale, directionMarkerMinimumLength);
	return lineEnd;
}
示例#2
0
void CC3Matrix::populateToLookAt( const CC3Vector& targetLocation, const CC3Vector& eyeLocation, const CC3Vector& upDirection )
{
	CC3Vector fwdDir = targetLocation.difference( eyeLocation );
	populateToPointTowards( fwdDir, upDirection );
	transpose();		
	translateBy( eyeLocation.negate() );
	m_isIdentity = false;
	m_isRigid = true;
}
/** 
 * Overridden to establish a default parent bounding box for parents that have no bounding
 * box, such as cameras and lights. The default parent box is calculated as 5% of the size
 * of the entire scene.
 */
CC3Box CC3DirectionMarkerNode::getParentBoundingBox()
{
	CC3Box pbb = super::getParentBoundingBox();
	if ( !pbb.isZero() )
		return pbb;

	CC3Vector bbDim = CC3Vector::kCC3VectorZero;
	CC3Scene* pScene = getScene();
	if ( pScene )
		bbDim = getScene()->getBoundingBox().getSize().scaleUniform( 0.05f );
		
	return CC3Box( bbDim.negate(), bbDim );
}
示例#4
0
void CC3ActionMoveDirectionallyBy::update( float t )
{
	GLfloat deltaTime = t - m_prevTime;
	GLfloat deltaDist = m_distance * deltaTime;
	CC3Vector moveDir = getTargetDirection().normalize();
	CC3Vector prevLoc = getTargetNode()->getLocation();
	getTargetNode()->setLocation( prevLoc.add( moveDir.scaleUniform(deltaDist) ) );
	m_prevTime = t;
	
	/*LogTrace(@"%@: time: %.3f, delta time: %.3f, delta dist: %.3f, was at: %@, now at: %@",
				  self, t, deltaTime, deltaDist,
				  NSStringFromCC3Vector(prevLoc),
				  NSStringFromCC3Vector(self.targetCC3Node.location));*/
}
示例#5
0
// Short-circuit the identity transform. isRigid unchanged under translation.
void CC3Matrix::translateBy( const CC3Vector& aTranslation )
{
	if ( !aTranslation.isZero() ) 
	{
		implTranslateBy( aTranslation );
		m_isIdentity = false;
	}
}
示例#6
0
// Short-circuit the identity transform
void CC3Matrix::scaleBy( const CC3Vector& aScale )
{
	if ( !aScale.equals( CC3Vector::kCC3VectorUnitCube ) ) 
	{
		implScaleBy( aScale );
		m_isIdentity = false;
		m_isRigid = false;
	}
}
示例#7
0
void CC3Matrix::populateFromTranslation( const CC3Vector& aTranslation ){
	if ( aTranslation.isZero() ) {
		populateIdentity();
	} else {
		implPopulateFromTranslation( aTranslation );
		m_isIdentity = false;
		m_isRigid = true;
	}
}
示例#8
0
void CC3Matrix::populateFromScale( const CC3Vector& aScale ) 
{
	if ( aScale.equals( CC3Vector::kCC3VectorUnitCube )) {
		populateIdentity();
	} else {
		implPopulateFromScale( aScale );
		m_isIdentity = false;
		m_isRigid = false;
	}
}
示例#9
0
CC3Vector CC3Camera::getProjectLocation( const CC3Vector& a3DLocation )
{
    // Convert specified location to a 4D homogeneous location vector
    // and transform it using the modelview and projection matrices.
    CC3Vector4 hLoc;
    hLoc.fromLocation(a3DLocation);
    hLoc = getViewMatrix()->transformHomogeneousVector( hLoc );
    hLoc = getProjectionMatrix()->transformHomogeneousVector( hLoc );

    // Convert projected 4D vector back to 3D.
    CC3Vector projectedLoc = hLoc.homogenizedCC3Vector();

    // The projected vector is in a projection coordinate space between -1 and +1 on all axes.
    // Normalize the vector so that each component is between 0 and 1 by calculating ( v = (v + 1) / 2 ).
    projectedLoc = projectedLoc.average( CC3Vector::kCC3VectorUnitCube );

    CCAssert(_viewport.h > 0 && _viewport.w > 0, "%CC3Camera does not have a valid viewport");

    // Map the X & Y components of the projected location (now between 0 and 1) to display coordinates.
    GLfloat g2p = 1.0f / CCDirector::sharedDirector()->getContentScaleFactor();
    projectedLoc.x *= ((GLfloat)_viewport.w * g2p);
    projectedLoc.y *= ((GLfloat)_viewport.h * g2p);

    // Using the vector from the camera to the 3D location, determine whether or not the
    // 3D location is in front of the camera by using the dot-product of that vector and
    // the direction the camera is pointing. Set the Z-component of the projected location
    // to be the signed distance from the camera to the 3D location, with a positive sign
    // indicating the location is in front of the camera, and a negative sign indicating
    // the location is behind the camera.
    CC3Vector camToLocVector = a3DLocation - getGlobalLocation();
    GLfloat camToLocDist = camToLocVector.length();
    GLfloat frontOrBack = (GLfloat)SIGN( camToLocVector.dot( getGlobalForwardDirection() ) );
    projectedLoc.z = frontOrBack * camToLocDist;

    //LogTrace(@"%@ projecting location %@ to %@ and orienting with device to %@ using viewport %@",
    //		 self, NSStringFromCC3Vector(a3DLocation), NSStringFromCC3Vector(projectedLoc),
    //		 NSStringFromCC3Vector(orientedLoc), NSStringFromCC3Viewport(_viewport));
    return projectedLoc;
}
示例#10
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);
}
示例#11
0
void CC3Camera::moveWithDuration( float t, CC3Node* aNode, const CC3Vector& targetLoc, const CC3Vector& aDirection, GLfloat padding, bool checkScene )
{
    CC3Vector newLoc = calculateLocationToShowAllOf( aNode, targetLoc, aDirection, padding, checkScene );
    CC3Vector newFwdDir = aDirection.negate();
    //LogInfo(@"%@ \n\tmoving to: %@ \n\tpointing towards: %@ \n\tnear clipping distance: %.3f"
    //		 @"\n\tfar clipping distance: %.3f \n\tto show all of: %@",
    //		 self, NSStringFromCC3Vector(newLoc), NSStringFromCC3Vector(newFwdDir),
    //		 self.nearClippingDistance, self.farClippingDistance, aNode);

    ensureAtRootAncestor();
    if (t > 0.0f)
    {
        runAction( CC3ActionMoveTo::actionWithDuration( t, newLoc ) );
        runAction( CC3ActionRotateToLookTowards::actionWithDuration( t, newFwdDir ));
    }
    else
    {
        setLocation( newLoc );
        setForwardDirection( newFwdDir );
    }
}
示例#12
0
// Short-circuit the identity transform. isRigid unchanged under rotation.
void CC3Matrix::rotateBy( const CC3Vector& aRotation ) {
	if ( !aRotation.isZero() ) {
		implRotateBy( aRotation );
		m_isIdentity = false;
	}
}
void CC3DirectionMarkerNode::setMarkerDirection( const CC3Vector& aDirection )
{
	m_markerDirection = aDirection.normalize(); 
}
示例#14
0
void CC3ActionRotateToLookTowards::initWithDuration( float t, const CC3Vector& aDirection )	/// forwardDirection
{
	return super::initWithDuration( t, aDirection.normalize() );
}
示例#15
0
void CC3PointParticle::pointNormalAt( const CC3Vector& camLoc )
{
	setNormal( camLoc.difference( getLocation() ).normalize() );
}
示例#16
0
CC3Vector CC3Camera::calculateLocationToShowAllOf( CC3Node* aNode, const CC3Vector& targLoc, const CC3Vector& aDirection, GLfloat padding, bool checkScene )
{
    ensureSceneUpdated( checkScene );

    // Complementary unit vectors pointing towards camera from node, and vice versa
    CC3Vector camDir = aDirection.normalize();
    CC3Vector viewDir = camDir.negate();

    // The camera's new forward direction will be viewDir. Use a matrix to detrmine
    // the camera's new up and right directions assuming the same scene up direction.
    CC3Matrix3x3 rotMtx;
    CC3Matrix3x3PopulateToPointTowards(&rotMtx, viewDir, getReferenceUpDirection());
    CC3Vector upDir = CC3Matrix3x3ExtractUpDirection(&rotMtx);
    CC3Vector rtDir = CC3Matrix3x3ExtractRightDirection(&rotMtx);

    // Determine the eight vertices, of the node's bounding box, in the global coordinate system
    CC3Box gbb = aNode->getGlobalBoundingBox();

    CC3Vector targetLoc = targLoc;
    // If a target location has not been specified, use the center of the node's global bounding box
    if ( targetLoc.isNull() )
        targetLoc = gbb.getCenter();

    CC3Vector bbMin = gbb.minimum;
    CC3Vector bbMax = gbb.maximum;
    CC3Vector bbVertices[8];
    bbVertices[0] = cc3v(bbMin.x, bbMin.y, bbMin.z);
    bbVertices[1] = cc3v(bbMin.x, bbMin.y, bbMax.z);
    bbVertices[2] = cc3v(bbMin.x, bbMax.y, bbMin.z);
    bbVertices[3] = cc3v(bbMin.x, bbMax.y, bbMax.z);
    bbVertices[4] = cc3v(bbMax.x, bbMin.y, bbMin.z);
    bbVertices[5] = cc3v(bbMax.x, bbMin.y, bbMax.z);
    bbVertices[6] = cc3v(bbMax.x, bbMax.y, bbMin.z);
    bbVertices[7] = cc3v(bbMax.x, bbMax.y, bbMax.z);

    // Express the camera's FOV in terms of ratios of the near clip bounds to
    // the near clip distance, so we can determine distances using similar triangles.
    CCSize fovRatios = getFovRatios();

    // Iterate through all eight vertices of the node's bounding box, and calculate
    // the largest distance required to place the camera away from the center of the
    // node in order to fit all eight vertices within the camera's frustum.
    // Simultaneously, calculate the extra distance from the center of the node to
    // the vertex that will be farthest from the camera, so we can ensure that all
    // vertices will fall within the frustum's far end.
    GLfloat maxCtrDist = 0;
    GLfloat maxVtxDeltaDist = 0;
    GLfloat minVtxDeltaDist = 0;
    for (int i = 0; i < 8; i++)
    {
        // Get a vector from the target location to the vertex
        CC3Vector relVtx = bbVertices[i] - targetLoc;

        // Project that vector onto each of the camera's new up and right directions,
        // and use similar triangles to determine the distance at which to place the
        // camera so that the vertex will fit in both the up and right directions.
        GLfloat vtxDistUp = fabs(relVtx.dot( upDir ) / fovRatios.height);
        GLfloat vtxDistRt = fabs(relVtx.dot( rtDir ) / fovRatios.width);
        GLfloat vtxDist = MAX(vtxDistUp, vtxDistRt);

        // Calculate how far along the view direction the vertex is from the center
        GLfloat vtxDeltaDist = relVtx.dot( viewDir );
        GLfloat ctrDist = vtxDist - vtxDeltaDist;

        // Accumulate the maximum distance from the node's center to the camera
        // required to fit all eight points, and the distance from the node's
        // center to the vertex that will be farthest away from the camera.
        maxCtrDist = MAX(maxCtrDist, ctrDist);
        maxVtxDeltaDist = MAX(maxVtxDeltaDist, vtxDeltaDist);
        minVtxDeltaDist = MIN(minVtxDeltaDist, vtxDeltaDist);
    }

    // Add some padding so we will have a bit of space around the node when it fills the view.
    maxCtrDist *= (1 + padding);

    // Determine if we need to move the far end of the camera frustum farther away
    GLfloat farClip = viewDir.scaleUniform(maxCtrDist + maxVtxDeltaDist).length();
    farClip *= (GLfloat)(1 + kCC3FrustumFitPadding);		// Include a little bit of padding
    if (farClip > getFarClippingDistance())
        setFarClippingDistance( farClip );

    // Determine if we need to move the near end of the camera frustum closer
    GLfloat nearClip = viewDir.scaleUniform(maxCtrDist + minVtxDeltaDist).length();
    nearClip *= (GLfloat)(1 - kCC3FrustumFitPadding);		// Include a little bit of padding
    if (nearClip < getNearClippingDistance())
        setNearClippingDistance( nearClip );

    //LogTrace(@"%@ moving to %@ to show %@ at %@ within %@ with new farClip: %.3f", self,
    //			  NSStringFromCC3Vector(CC3VectorAdd(targLoc, CC3VectorScaleUniform(camDir, maxCtrDist))),
    //			  aNode, NSStringFromCC3Vector(targLoc), _frustum, self.farClippingDistance);

    // Return the new location of the camera,
    return targetLoc.add( camDir.scaleUniform( maxCtrDist ) );
}