⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlr_i_pmesh.cpp

📁 机甲指挥官2源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	Scalar u1v0, u0v1;

	int up=0, down=0, right=0, left=0;

	for(k0=0;k0<stride;k0++)
	{
		if((*lightMapUVs)[k0][1] > 0.5f)
		{
			up++;
		}
		if((*lightMapUVs)[k0][1] < -0.5f)
		{
			down++;
		}
		if((*lightMapUVs)[k0][0] > 0.5f)
		{
			right++;
		}
		if((*lightMapUVs)[k0][0] < -0.5f)
		{
			left++;
		}
	}

	if(up==stride || down==stride || left==stride || right==stride)
	{
		errorColor = RGBAColor(0.5f, 0.5f, 0.0f, 1.0f);
		return false;
	}

#if 1
	Scalar sign = -1.0f;
	if( 
		((*lightMapUVs)[1][0]-(*lightMapUVs)[0][0]) * ((*lightMapUVs)[stride-1][1]-(*lightMapUVs)[0][1]) >
		((*lightMapUVs)[1][1]-(*lightMapUVs)[0][1]) * ((*lightMapUVs)[stride-1][0]-(*lightMapUVs)[0][0])
		)
	{
		sign = 1.0f;
	}
#endif

	for(k0=0;k0<stride;k0++)
	{
		k1 = (k0+1<stride) ? k0+1 : 0;

		u1v0 = 	(*lightMapUVs)[k1][0] * (*lightMapUVs)[k0][1];
		u0v1 = 	(*lightMapUVs)[k0][0] * (*lightMapUVs)[k1][1];

		if( sign*(u1v0 - u0v1) < 0.0f )
//		if( (u1v0 - u0v1) < 0.0f )
		{
			continue;
		}

		if(
			(
				((*lightMapUVs)[k1][0]*(*lightMapUVs)[k1][0] - 2.0f*(*lightMapUVs)[k1][0]*(*lightMapUVs)[k0][0] + (*lightMapUVs)[k0][0]*(*lightMapUVs)[k0][0]) +
				((*lightMapUVs)[k1][1]*(*lightMapUVs)[k1][1] - 2.0f*(*lightMapUVs)[k1][1]*(*lightMapUVs)[k0][1] + (*lightMapUVs)[k0][1]*(*lightMapUVs)[k0][1])
			) 	<	(2.0f*(u1v0*u1v0 - 2.0f*u1v0*u0v1 + u0v1*u0v1))
		)
		{
#if UV_TEST
			DEBUG_STREAM << k0 << endl;
			for(int i=0;i<stride;i++)
			{
				DEBUG_STREAM << (*lightMapUVs)[i][0] << " " << (*lightMapUVs)[i][1] << endl;
			}
			DEBUG_STREAM << endl;
#endif
			errorColor = RGBAColor(0.0f, 0.5f, 0.0f, 1.0f);
			return false;
		}
	}
	return true;
}

//---------------------------------------------------------------------------
//
void
	MLR_I_PMesh::LightMapLighting(MLRLight *light)
{
	if(!gEnableLightMaps)
	{
		return;
	}

	unsigned short stride;
	int i, j, k, len = lengths.GetLength();
	LinearMatrix4D matrix = LinearMatrix4D::Identity;
	Point3D lightPosInShape, hitPoint;
	UnitVector3D up, left, forward;
	bool lm;
	Scalar f, rhf, falloff = 1.0f, distance;

	MLRLightMap *lightMap = light->GetLightMap();

	if( (!lightMap)  || (!gEnableLightMaps) )
	{
		return;
	}

	switch(light->GetLightType())
	{
		case MLRLight::PointLight:
		{
			lightMap->AddState(referenceState.GetPriority()+1);
			
			light->GetInShapePosition(lightPosInShape);

			for(i=0,j=0,k=0;i<len;i++,j += stride)
			{
				stride = lengths[i];

				if(testList[i] == 0)
				{
					continue;
				}

				f = facePlanes[i].GetDistanceTo(lightPosInShape);
				
				lm = false;

				if(f>0.0f && Cast_Object(MLRInfiniteLightWithFalloff*, light)->GetFalloff(f, falloff) == true)
				{
					rhf = 1.0f/f;

					matrix = LinearMatrix4D::Identity;
					matrix.AlignLocalAxisToWorldVector(facePlanes[i].normal, Z_Axis, Y_Axis, X_Axis);
					matrix.GetWorldLeftInLocal(&left);
					matrix.GetWorldUpInLocal(&up);
					matrix.GetWorldForwardInLocal(&forward);
					Verify(Small_Enough(up*left));

		#if defined(_ARMOR)
					Scalar diff = forward*left;
					Verify(Small_Enough(diff));
					diff = up*forward;
					Verify(Small_Enough(diff));
		#endif

					Check_Object(&forward);
					hitPoint.Multiply(forward, -f);
					hitPoint+=lightPosInShape;

					for(k=0;k<stride;k++)
					{
						Vector3D vec(coords[index[k+j]]);
						vec-=hitPoint;

						(*lightMapUVs)[k][0] = -(left*vec)*rhf;
						(*lightMapUVs)[k][1] = -(up*vec)*rhf;

						if(
							(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
							(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f

						) 
						{
							lm = true;
						}
					}
				}
				else
				{
					continue;
				}

				if(lm == true || CheckForBigTriangles(lightMapUVs, stride) == true)
				{
					lightMap->SetPolygonMarker(0);
					lightMap->AddUShort(stride);

					Scalar sq_falloff
						= falloff*falloff*light->GetIntensity();
					RGBAColor color(sq_falloff, sq_falloff, sq_falloff, 1.0f);

					lightMap->AddColor(color);
					for(k=0;k<stride;k++)
					{
						lightMap->AddCoord(coords[index[k+j]]);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddUVs((*lightMapUVs)[k][0]+0.5f, (*lightMapUVs)[k][1]+0.5f);
		//				DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
					}
				}
			}
		}
		break;
		case MLRLight::SpotLight:
		{
			int behindCount = 0, falloffCount = 0;

			lightMap->AddState(referenceState.GetPriority()+1);
			
			light->GetInShapePosition(matrix);
			lightPosInShape = matrix;

			Scalar tanSpeadAngle = Cast_Object(MLRSpotLight*, light)->GetTanSpreadAngle();

			matrix.GetLocalLeftInWorld(&left);
			matrix.GetLocalUpInWorld(&up);
			matrix.GetLocalForwardInWorld(&forward);

			Verify(Small_Enough(up*left));

			for(i=0,j=0,k=0;i<len;i++,j += stride)
			{
				behindCount = 0;
				falloffCount = 0;
				stride = lengths[i];

				if(testList[i] == 0)
				{
					continue;
				}

				lm = false;

				if(!facePlanes[i].IsSeenBy(lightPosInShape))
				{
					continue;
				}

				int tooBig = 0;
				for(k=0;k<stride;k++)
				{
					Vector3D vec;
					vec.Subtract(coords[index[k+j]], lightPosInShape);

					distance = (vec*forward);

					if(distance > SMALL)
					{
						if(Cast_Object(MLRInfiniteLightWithFalloff*, light)->GetFalloff(distance, falloff) == false)
						{
							falloffCount++;
						}
						(*lightMapSqFalloffs)[k] = falloff*falloff*light->GetIntensity();
					}
					else
					{
						behindCount++;
						break;
					}

					(*lightMapUVs)[k][0] = (left*vec)/(2.0f*distance*tanSpeadAngle);
					(*lightMapUVs)[k][1] = -(up*vec)/(2.0f*distance*tanSpeadAngle);

					if(
						(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
						(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f

					) 
					{
						lm = true;
					}
					if(
						(*lightMapUVs)[k][0] < -1.5f || (*lightMapUVs)[k][0] > 1.5f ||
						(*lightMapUVs)[k][1] < -1.5f && (*lightMapUVs)[k][1] > 1.5f

					) 
					{
						tooBig++;
					}
				}

#if 1
				if(	
					tooBig == 0 &&
					behindCount == 0 && 
					falloffCount < stride &&
					(lm == true || CheckForBigTriangles(lightMapUVs, stride) == true)
					)
				{
					lightMap->SetPolygonMarker(1);
					lightMap->AddUShort(stride);

					for(k=0;k<stride;k++)
					{
						lightMap->AddCoord(coords[index[k+j]]);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddColor((*lightMapSqFalloffs)[k], (*lightMapSqFalloffs)[k], (*lightMapSqFalloffs)[k], 1.0f);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddUVs((*lightMapUVs)[k][0]+0.5f, (*lightMapUVs)[k][1]+0.5f);
		//				DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
					}
				}
#else
				if(tooBig != 0)
				{
					lightMap->SetPolygonMarker(1);
					lightMap->AddUShort(stride);

					for(k=0;k<stride;k++)
					{
						lightMap->AddCoord(coords[index[k+j]]);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddColor(RGBAColor(0.0f, 0.0f, 0.5f, 1.0f));
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddUVs(0.5f, 0.5f);
		//				DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
					}
				} 
				else if(behindCount != 0)
				{
					lightMap->SetPolygonMarker(1);
					lightMap->AddUShort(stride);

					for(k=0;k<stride;k++)
					{
						lightMap->AddCoord(coords[index[k+j]]);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddColor(RGBAColor(0.5f, 0.0f, 0.0f, 1.0f));
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddUVs(0.5f, 0.5f);
		//				DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
					}
				} 
				else	if(behindCount == 0 && (lm == true || CheckForBigTriangles(&lightMapUVs, stride) == true) )
				{
					lightMap->SetPolygonMarker(1);
					lightMap->AddUShort(stride);

					for(k=0;k<stride;k++)
					{
						lightMap->AddCoord(coords[index[k+j]]);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddColor(lightMapSqFalloffs[k], lightMapSqFalloffs[k], lightMapSqFalloffs[k], 1.0f);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddUVs(lightMapUVs[k][0]+0.5f, lightMapUVs[k][1]+0.5f);
		//				DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
					}

				}
				else if(CheckForBigTriangles(&lightMapUVs, stride) == false)
				{
					lightMap->SetPolygonMarker(1);
					lightMap->AddUShort(stride);

					for(k=0;k<stride;k++)
					{
						lightMap->AddCoord(coords[index[k+j]]);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddColor(errorColor);
					}
					for(k=0;k<stride;k++)
					{
						lightMap->AddUVs(0.5f, 0.5f);
		//				DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
					}
				}
#endif
			}
		}
		break;
		default:
			STOP(("MLR_I_PMesh::LightMapLighting: What you want me to do ?"));
		break;
	}
}

//---------------------------------------------------------------------------
//
bool
	MLR_I_PMesh::CastRay(
		Line3D *line,
		Normal3D *normal
	)
{
	Check_Object(this);
	Check_Object(line);
	Check_Pointer(normal);

	//
	//---------------------------------------------------------------------
	// We have to spin through each of the polygons stored in the shape and
	// collide the ray against each
	//---------------------------------------------------------------------
	//
	int poly_start = 0, numPrimitives = GetNumPrimitives();
	bool hit = false;
	for (int polygon=0; polygon<numPrimitives; ++polygon)
	{
		int stride = lengths[polygon];
		Verify(stride>2);

		//
		//---------------------------------
		// See if the line misses the plane
		//---------------------------------
		//
		Scalar product;
		const Plane *plane = &facePlanes[polygon];
		Check_Object(plane);
		Scalar distance = line->GetDistanceTo(*plane, &product);
		if (distance < 0.0f || distance > line->length)
		{
			poly_start += stride;
			continue;
		}
		bool negate = false;
		if (product > -SMALL)
		{
			if (GetCurrentState().GetBackFaceMode() == MLRState::BackFaceOnMode)
			{
				poly_start += stride;
				continue;
			}
			negate = true;
		}

		//
		//-------------------------------------------
		// Figure out where on the plane the line hit
		//-------------------------------------------
		//
		Point3D impact;
		line->Project(distance, &impact);

		//
		//-------------------------------------------------------------------
		// We now need to find out which cardinal plane we should project the
		// triangle onto
		//-------------------------------------------------------------------
		//
		int s,t;
		Scalar nx = Abs(plane->normal.x);
		Scalar ny = Abs(plane->normal.y);
		Scalar nz = Abs(plane->normal.z);
		if (nx > ny)
		{
			if (nx > nz)
			{
				s = Y_Axis;
				t = Z_Axis;
			}
			else
			{
				s = X_Axis;
				t = Y_Axis;
			}
		}
		else if (ny > nz)
		{
			s = Z_Axis;
			t = X_Axis;
		}
		else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -