| 223 | | for (int i = 0; i < ControlPoints.GetSize() - 1; i++) |
| 224 | | { |
| 225 | | Vector3 p0, p1, p2, p3; |
| 226 | | |
| 227 | | if (i == 0) |
| 228 | | { |
| 229 | | p0 = Vector3(ControlPoints[0]); |
| 230 | | p1 = Vector3(ControlPoints[0]); |
| 231 | | p2 = Vector3(ControlPoints[1]); |
| 232 | | p3 = Vector3(ControlPoints[2]); |
| 233 | | } |
| 234 | | else if (i == ControlPoints.GetSize() - 2) |
| 235 | | { |
| 236 | | p0 = Vector3(ControlPoints[i-1]); |
| 237 | | p1 = Vector3(ControlPoints[i]); |
| 238 | | p2 = Vector3(ControlPoints[i+1]); |
| 239 | | p3 = Vector3(ControlPoints[i+1]); |
| 240 | | } |
| | 224 | lcFlexiblePiecePoint* PrevPoint = (lcFlexiblePiecePoint*)m_Children; |
| | 225 | lcFlexiblePiecePoint* Point = (lcFlexiblePiecePoint*)m_Children; |
| | 226 | lcFlexiblePiecePoint* NextPoint = (lcFlexiblePiecePoint*)m_Children->m_Next; |
| | 227 | int Segment = 0; |
| | 228 | |
| | 229 | while (NextPoint) |
| | 230 | { |
| | 231 | Matrix33 StartMat, EndMat; |
| | 232 | |
| | 233 | Vector3 p0 = PrevPoint->m_ParentPosition; |
| | 234 | Vector3 p1 = Point->m_ParentPosition; |
| | 235 | Vector3 p2 = NextPoint->m_ParentPosition; |
| | 236 | Vector3 p3 = NextPoint->m_Next ? NextPoint->m_Next->m_ParentPosition : NextPoint->m_ParentPosition; |
| | 237 | |
| | 238 | // Calculate the start and end orientation for this curve segment. |
| | 239 | if (Point->IsFlagged(LC_FLEXPIECE_POINT_TANGENT)) |
| | 240 | StartMat = LastMat; |
| 242 | | { |
| 243 | | p0 = Vector3(ControlPoints[i-1]); |
| 244 | | p1 = Vector3(ControlPoints[i]); |
| 245 | | p2 = Vector3(ControlPoints[i+1]); |
| 246 | | p3 = Vector3(ControlPoints[i+2]); |
| 247 | | } |
| | 242 | StartMat = Point->m_ModelParent; |
| | 243 | |
| | 244 | if (NextPoint->IsFlagged(LC_FLEXPIECE_POINT_TANGENT)) |
| | 245 | { |
| | 246 | // Make the tangent at this point be parallel to a vector between the point before and after it. |
| | 247 | Vector3 Tan = p3 - p1; |
| | 248 | |
| | 249 | Tan.Normalize(); |
| | 250 | float Dot = Dot3(StartMat[2], Tan); |
| | 251 | |
| | 252 | if (Dot < 0.999f) |
| | 253 | { |
| | 254 | Vector3 Axis = Cross3(StartMat[2], Tan); |
| | 255 | float Angle = acosf(Dot); |
| | 256 | |
| | 257 | Matrix33 Rot = MatrixFromAxisAngle(Axis, Angle); |
| | 258 | EndMat = Mul(StartMat, Rot); |
| | 259 | } |
| | 260 | else |
| | 261 | EndMat = StartMat; |
| | 262 | } |
| | 263 | else |
| | 264 | EndMat = NextPoint->m_ModelParent; |
| | 265 | |
| | 266 | float Dot = Dot3(StartMat[2], EndMat[2]); |
| | 267 | Vector3 Axis; |
| | 268 | float Angle; |
| | 269 | |
| | 270 | if (Dot < 0.999f) |
| | 271 | { |
| | 272 | Axis = Cross3(StartMat[2], EndMat[2]); |
| | 273 | Angle = acosf(Dot); |
| | 274 | } |
| | 275 | else |
| | 276 | { |
| | 277 | Axis = Vector3(0, 0, 1); |
| | 278 | Angle = 0; |
| | 279 | } |
| | 280 | |
| | 281 | // Calculate the coefficients of a bezier curve that passes through the 2 end points |
| | 282 | // for this segment and has the tangent vectors calculated above. |
| | 283 | p0 = p1; |
| | 284 | p3 = p2; |
| | 285 | |
| | 286 | float Len = Length(p1-p2) * 0.5f; |
| | 287 | p1 = p1 + StartMat[2] * Len; |
| | 288 | p2 = p2 - EndMat[2] * Len; |
| | 289 | |
| | 290 | Matrix44 Points = Matrix44(Vector4(p0, 1), Vector4(p1, 1), Vector4(p2, 1), Vector4(p3, 1)); |
| | 294 | static Matrix44 Blend(Vector4(-1, 3, -3, 1), Vector4(3, -6, 3, 0), Vector4(-3, 3, 0, 0), Vector4(1, 0, 0, 0)); |
| | 295 | static Matrix44 Tangent(Vector4(0, 0, 0, 0), Vector4(-3, 9, -9, 3), Vector4(6,-12, 6, 0), Vector4(-3, 3, 0, 0)); |
| | 296 | |
| 252 | | float t2 = t * t; |
| 253 | | float t3 = t2 * t; |
| 254 | | |
| 255 | | Vector3 Pos = 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); |
| 256 | | Vector3 Tan = 0.5f * ((-p0 + p2) + 2 * (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t + 3 * (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t2); |
| | 298 | |
| | 299 | Vector3 Pos = Vector3(Mul4(Mul4(Vector4(t*t*t,t*t,t,1), Blend), Points)); |
| | 300 | Vector3 Tan = Vector3(Mul4(Mul4(Vector4(0,t*t,t,1), Tangent), Points)); |
| 281 | | MeshEdit.AddIndex(j * NumSlices + k); |
| 282 | | MeshEdit.AddIndex(j * NumSlices + k + 1); |
| 283 | | MeshEdit.AddIndex((j+1) * NumSlices + k); |
| 284 | | MeshEdit.AddIndex(j * NumSlices + k + 1); |
| 285 | | MeshEdit.AddIndex((j+1) * NumSlices + k + 1); |
| 286 | | MeshEdit.AddIndex((j+1) * NumSlices + k); |
| | 327 | MeshEdit.AddIndex(IndexOffset + j * NumSlices + k); |
| | 328 | MeshEdit.AddIndex(IndexOffset + j * NumSlices + k + 1); |
| | 329 | MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); |
| | 330 | MeshEdit.AddIndex(IndexOffset + j * NumSlices + k + 1); |
| | 331 | MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k + 1); |
| | 332 | MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); |
| 290 | | MeshEdit.AddIndex(j * NumSlices + k); |
| 291 | | MeshEdit.AddIndex(j * NumSlices); |
| 292 | | MeshEdit.AddIndex((j+1) * NumSlices + k); |
| 293 | | MeshEdit.AddIndex(j * NumSlices); |
| 294 | | MeshEdit.AddIndex((j+1) * NumSlices); |
| 295 | | MeshEdit.AddIndex((j+1) * NumSlices + k); |
| | 336 | MeshEdit.AddIndex(IndexOffset + j * NumSlices + k); |
| | 337 | MeshEdit.AddIndex(IndexOffset + j * NumSlices); |
| | 338 | MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); |
| | 339 | MeshEdit.AddIndex(IndexOffset + j * NumSlices); |
| | 340 | MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices); |
| | 341 | MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); |