| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- //
- // Urho3D Engine
- // Copyright (c) 2008-2012 Lasse Öörni
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #include "Precompiled.h"
- #include "GeometryUtils.h"
- #include "Plane.h"
- inline void ClipEdge(float* output, float* v0, float* v1, float d0, float d1, unsigned components)
- {
- float t = d0 / (d0 - d1);
-
- for (unsigned i = 0; i < components; ++i)
- output[i] = v0[i] + t * (v1[i] - v0[i]);
- }
- inline void CopyVertex(float* output, float* input, unsigned components)
- {
- for (unsigned i = 0; i < components; ++i)
- output[i] = input[i];
- }
- unsigned ClipPolygon(float* input, float* output, unsigned vertexCount, unsigned vertexSize, const Plane& plane, float* clip, unsigned* clipVertexCount)
- {
- unsigned components = vertexSize / sizeof(float);
- unsigned outVertexCount = 0;
- float* lastVertex = input;
- float lastDistance = 0.0f;
-
- if (clipVertexCount)
- *clipVertexCount = 0;
-
- for (unsigned i = 0; i < vertexCount; ++i)
- {
- float* vertex = input + i * components;
- const Vector3& position = *((Vector3*)vertex);
- float distance = plane.Distance(position);
- if (distance >= 0.0f)
- {
- if (lastDistance < 0.0f)
- {
- ClipEdge(output, lastVertex, vertex, lastDistance, distance, components);
- if (clip && clipVertexCount)
- {
- CopyVertex(clip, output, components);
- clip += components;
- ++(*clipVertexCount);
- }
- output += components;
- ++outVertexCount;
- }
-
- for (unsigned j = 0; j < components; ++j)
- output[j] = vertex[j];
- output += components;
- ++outVertexCount;
- }
- else
- {
- if (lastDistance >= 0.0f && i != 0)
- {
- ClipEdge(output, lastVertex, vertex, lastDistance, distance, components);
- if (clip && clipVertexCount)
- {
- CopyVertex(clip, output, components);
- clip += components;
- ++(*clipVertexCount);
- }
- output += components;
- ++outVertexCount;
- }
- }
-
- lastVertex = vertex;
- lastDistance = distance;
- }
-
- // Recheck the distances of the last and first vertices and add the final clipped vertex if applicable
- {
- float* vertex = input;
- const Vector3& position = *((Vector3*)vertex);
- float distance = plane.Distance(position);
- if ((lastDistance < 0.0f && distance >= 0.0f) || (lastDistance >= 0.0f && distance < 0.0f))
- {
- ClipEdge(output, lastVertex, vertex, lastDistance, distance, components);
- if (clip && clipVertexCount)
- {
- CopyVertex(clip, output, components);
- clip += components;
- ++(*clipVertexCount);
- }
- output += components;
- ++outVertexCount;
- }
- }
-
- return outVertexCount;
- }
|