コード例 #1
0
ファイル: indexUtil.cpp プロジェクト: Longlonc/palabos
IndexCollection operator&&(IndexCollection const& coll1, IndexCollection const& coll2) {
    std::vector<plint> result;
    std::vector<plint> const& ind1 = coll1.get();
    std::vector<plint> const& ind2 = coll2.get();

    std::vector<plint>::const_iterator iter_ind1 = ind1.begin();
    std::vector<plint>::const_iterator iter_ind2 = ind2.begin();

    while(!(iter_ind1==ind1.end() || iter_ind2==ind2.end())) {
        if (*iter_ind1 == *iter_ind2) {
            result.push_back(*iter_ind1);
            ++iter_ind1;
            ++iter_ind2;
        }
        else {
            if (*iter_ind1 < *iter_ind2) {
                ++iter_ind1;
            }
            else {
                ++iter_ind2;
            }
        }
    }
    return IndexCollection(result);
}
コード例 #2
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateTetrahedron( float size /*= 1*/, bool rhcoords /*= true*/)
{
	VertexCollection vertices;
	IndexCollection indices;

	static const XMVECTORF32 verts[4] =
	{
		{ 0.f, 0.f, 1.f },
		{ 2.f*SQRT2 / 3.f, 0.f, -1.f / 3.f },
		{ -SQRT2 / 3.f, SQRT6 / 3.f, -1.f / 3.f },
		{ -SQRT2 / 3.f, -SQRT6 / 3.f, -1.f / 3.f }
	};

	static const uint32_t faces[4 * 3] =
	{
		0, 1, 2,
		0, 2, 3,
		0, 3, 1,
		1, 3, 2,
	};

	for (size_t j = 0; j < _countof(faces); j += 3)
	{
		uint32_t v0 = faces[j];
		uint32_t v1 = faces[j + 1];
		uint32_t v2 = faces[j + 2];

		XMVECTOR normal = XMVector3Cross(verts[v1].v - verts[v0].v,
			verts[v2].v - verts[v0].v);
		normal = XMVector3Normalize(normal);

		size_t base = vertices.size();
		indices.push_back(base);
		indices.push_back(base + 1);
		indices.push_back(base + 2);

		// Duplicate vertices to use face normals
		XMVECTOR position = XMVectorScale(verts[v0], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMZero /* 0, 0 */));

		position = XMVectorScale(verts[v1], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR0 /* 1, 0 */));

		position = XMVectorScale(verts[v2], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR1 /* 0, 1 */));
	}

	assert(vertices.size() == 4 * 3);
	assert(indices.size() == 4 * 3);

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, !rhcoords);

	return primitive;
}
コード例 #3
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
//--------------------------------------------------------------------------------------
// Tetrahedron
//--------------------------------------------------------------------------------------
void DirectX::ComputeTetrahedron(VertexCollection& vertices, IndexCollection& indices, float size, bool rhcoords)
{
    vertices.clear();
    indices.clear();

    static const XMVECTORF32 verts[4] =
    {
        { { {              0.f,          0.f,        1.f, 0 } } },
        { { {  2.f*SQRT2 / 3.f,          0.f, -1.f / 3.f, 0 } } },
        { { {     -SQRT2 / 3.f,  SQRT6 / 3.f, -1.f / 3.f, 0 } } },
        { { {     -SQRT2 / 3.f, -SQRT6 / 3.f, -1.f / 3.f, 0 } } }
    };

    static const uint32_t faces[4 * 3] =
    {
        0, 1, 2,
        0, 2, 3,
        0, 3, 1,
        1, 3, 2,
    };

    for (size_t j = 0; j < _countof(faces); j += 3)
    {
        uint32_t v0 = faces[j];
        uint32_t v1 = faces[j + 1];
        uint32_t v2 = faces[j + 2];

        XMVECTOR normal = XMVector3Cross(
            XMVectorSubtract(verts[v1].v, verts[v0].v),
            XMVectorSubtract(verts[v2].v, verts[v0].v));
        normal = XMVector3Normalize(normal);

        size_t base = vertices.size();
        index_push_back(indices, base);
        index_push_back(indices, base + 1);
        index_push_back(indices, base + 2);

        // Duplicate vertices to use face normals
        XMVECTOR position = XMVectorScale(verts[v0], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMZero /* 0, 0 */));

        position = XMVectorScale(verts[v1], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR0 /* 1, 0 */));

        position = XMVectorScale(verts[v2], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR1 /* 0, 1 */));
    }

    // Built LH above
    if (rhcoords)
        ReverseWinding(indices, vertices);

    assert(vertices.size() == 4 * 3);
    assert(indices.size() == 4 * 3);
}
コード例 #4
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateCone( float diameter /*= 1*/, float height /*= 1*/, size_t tessellation /*= 32*/, bool rhcoords /*= true*/)
{
	VertexCollection vertices;
	IndexCollection indices;

	if (tessellation < 3)
		throw std::out_of_range("tesselation parameter out of range");

	height /= 2;

	XMVECTOR topOffset = g_XMIdentityR1 * height;

	float radius = diameter / 2;
	size_t stride = tessellation + 1;

	// Create a ring of triangles around the outside of the cone.
	for (size_t i = 0; i <= tessellation; i++)
	{
		XMVECTOR circlevec = GetCircleVector(i, tessellation);

		XMVECTOR sideOffset = circlevec * radius;

		float u = (float)i / tessellation;

		XMVECTOR textureCoordinate = XMLoadFloat(&u);

		XMVECTOR pt = sideOffset - topOffset;

		XMVECTOR normal = XMVector3Cross(GetCircleTangent(i, tessellation), topOffset - pt);
		normal = XMVector3Normalize(normal);

		// Duplicate the top vertex for distinct normals
		vertices.push_back(VertexPositionNormalTexture(topOffset, normal, g_XMZero));
		vertices.push_back(VertexPositionNormalTexture(pt, normal, textureCoordinate + g_XMIdentityR1));

		indices.push_back(i * 2);
		indices.push_back((i * 2 + 3) % (stride * 2));
		indices.push_back((i * 2 + 1) % (stride * 2));
	}

	// Create flat triangle fan caps to seal the bottom.
	CreateCylinderCap(vertices, indices, tessellation, height, radius, false);

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, rhcoords);

	return primitive;
}
コード例 #5
0
ファイル: Symtab.cpp プロジェクト: derekmarcotte/freebsd
void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
                                    bool add_demangled, bool add_mangled,
                                    NameToIndexMap &name_to_index_map) const {
  if (add_demangled || add_mangled) {
    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
    Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
    std::lock_guard<std::recursive_mutex> guard(m_mutex);

    // Create the name index vector to be able to quickly search by name
    NameToIndexMap::Entry entry;
    const size_t num_indexes = indexes.size();
    for (size_t i = 0; i < num_indexes; ++i) {
      entry.value = indexes[i];
      assert(i < m_symbols.size());
      const Symbol *symbol = &m_symbols[entry.value];

      const Mangled &mangled = symbol->GetMangled();
      if (add_demangled) {
        entry.cstring = mangled.GetDemangledName(symbol->GetLanguage());
        if (entry.cstring)
          name_to_index_map.Append(entry);
      }

      if (add_mangled) {
        entry.cstring = mangled.GetMangledName();
        if (entry.cstring)
          name_to_index_map.Append(entry);
      }
    }
  }
}
コード例 #6
0
// Initializes a geometric primitive instance that will draw the specified vertex and index data.
void GeometricPrimitive::Impl::Initialize(
    const VertexCollection& vertices,
    const IndexCollection& indices,
    _In_opt_ ID3D12Device* device)
{
    if (vertices.size() >= USHRT_MAX)
        throw std::exception("Too many vertices for 16-bit index buffer");

    if (indices.size() > UINT32_MAX)
        throw std::exception("Too many indices");

    // Vertex data
    uint64_t sizeInBytes = uint64_t(vertices.size()) * sizeof(vertices[0]);
    if (sizeInBytes > uint64_t(D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024u * 1024u))
        throw std::exception("VB too large for DirectX 12");

    auto vertSizeBytes = static_cast<size_t>(sizeInBytes);

    mVertexBuffer = GraphicsMemory::Get(device).Allocate(vertSizeBytes);

    auto verts = reinterpret_cast<const uint8_t*>(vertices.data());
    memcpy(mVertexBuffer.Memory(), verts, vertSizeBytes);

    // Index data
    sizeInBytes = uint64_t(indices.size()) * sizeof(indices[0]);
    if (sizeInBytes > uint64_t(D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024u * 1024u))
        throw std::exception("IB too large for DirectX 12");

    auto indSizeBytes = static_cast<size_t>(sizeInBytes);

    mIndexBuffer = GraphicsMemory::Get(device).Allocate(indSizeBytes);

    auto ind = reinterpret_cast<const uint8_t*>(indices.data());
    memcpy(mIndexBuffer.Memory(), ind, indSizeBytes);

    // Record index count for draw
    mIndexCount = static_cast<UINT>(indices.size());

    // Create views
    mVertexBufferView.BufferLocation = mVertexBuffer.GpuAddress();
    mVertexBufferView.StrideInBytes = static_cast<UINT>(sizeof(VertexCollection::value_type));
    mVertexBufferView.SizeInBytes = static_cast<UINT>(mVertexBuffer.Size());

    mIndexBufferView.BufferLocation = mIndexBuffer.GpuAddress();
    mIndexBufferView.SizeInBytes = static_cast<UINT>(mIndexBuffer.Size());
    mIndexBufferView.Format = DXGI_FORMAT_R16_UINT;
}
コード例 #7
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
//--------------------------------------------------------------------------------------
// Torus
//--------------------------------------------------------------------------------------
void DirectX::ComputeTorus(VertexCollection& vertices, IndexCollection& indices, float diameter, float thickness, size_t tessellation, bool rhcoords)
{
    vertices.clear();
    indices.clear();

    if (tessellation < 3)
        throw std::out_of_range("tesselation parameter out of range");

    size_t stride = tessellation + 1;

    // First we loop around the main ring of the torus.
    for (size_t i = 0; i <= tessellation; i++)
    {
        float u = float(i) / tessellation;

        float outerAngle = i * XM_2PI / tessellation - XM_PIDIV2;

        // Create a transform matrix that will align geometry to
        // slice perpendicularly though the current ring position.
        XMMATRIX transform = XMMatrixTranslation(diameter / 2, 0, 0) * XMMatrixRotationY(outerAngle);

        // Now we loop along the other axis, around the side of the tube.
        for (size_t j = 0; j <= tessellation; j++)
        {
            float v = 1 - float(j) / tessellation;

            float innerAngle = j * XM_2PI / tessellation + XM_PI;
            float dx, dy;

            XMScalarSinCos(&dy, &dx, innerAngle);

            // Create a vertex.
            XMVECTOR normal = XMVectorSet(dx, dy, 0, 0);
            XMVECTOR position = XMVectorScale(normal, thickness / 2);
            XMVECTOR textureCoordinate = XMVectorSet(u, v, 0, 0);

            position = XMVector3Transform(position, transform);
            normal = XMVector3TransformNormal(normal, transform);

            vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinate));

            // And create indices for two triangles.
            size_t nextI = (i + 1) % stride;
            size_t nextJ = (j + 1) % stride;

            index_push_back(indices, i * stride + j);
            index_push_back(indices, i * stride + nextJ);
            index_push_back(indices, nextI * stride + j);

            index_push_back(indices, i * stride + nextJ);
            index_push_back(indices, nextI * stride + nextJ);
            index_push_back(indices, nextI * stride + j);
        }
    }

    // Build RH above
    if (!rhcoords)
        ReverseWinding(indices, vertices);
}
コード例 #8
0
// Helper creates a triangle fan to close the end of a cylinder / cone
static void CreateCylinderCap(VertexCollection& vertices, IndexCollection& indices, size_t tessellation, float height, float radius, bool isTop)
{
	// Create cap indices.
	for (size_t i = 0; i < tessellation - 2; i++)
	{
		size_t i1 = (i + 1) % tessellation;
		size_t i2 = (i + 2) % tessellation;

		if (isTop)
		{
			std::swap(i1, i2);
		}

		size_t vbase = vertices.size();
		indices.push_back(vbase);
		indices.push_back(vbase + i1);
		indices.push_back(vbase + i2);
	}

	// Which end of the cylinder is this?
	XMVECTOR normal = g_XMIdentityR1;
	XMVECTOR textureScale = g_XMNegativeOneHalf;

	if (!isTop)
	{
		normal = -normal;
		textureScale *= g_XMNegateX;
	}

	// Create cap vertices.
	for (size_t i = 0; i < tessellation; i++)
	{
		XMVECTOR circleVector = GetCircleVector(i, tessellation);

		XMVECTOR position = (circleVector * radius) + (normal * height);

		XMVECTOR textureCoordinate = XMVectorMultiplyAdd(XMVectorSwizzle<0, 2, 3, 3>(circleVector), textureScale, g_XMOneHalf);


		vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinate));
	}
}
コード例 #9
0
_Use_decl_annotations_
void GeometricPrimitive::Impl::Initialize(VertexCollection& vertices, IndexCollection& indices, bool rhcoords)
{
	if (vertices.size() >= USHRT_MAX)
		throw std::exception("Too many vertices for 16-bit index buffer");
	ID3D11Device* device = g_objDeviecManager.GetDevice();
	CreateBuffer(device, vertices, D3D11_BIND_VERTEX_BUFFER, &mVertexBuffer);
	CreateBuffer(device, indices, D3D11_BIND_INDEX_BUFFER, &mIndexBuffer);

	mIndexCount = static_cast<UINT>(indices.size());
}
コード例 #10
0
        // Return the maximum buffer size (in bytes) required to process the
        // specified collection of market 'indices'.
//..
// Before showing the implementation of 'processIndices', where the most
// interesting use of our managed allocator takes place, we show the site of
// the call to 'processIndices'.
//
// First, assume that we have been given an 'IndexCollection' that has been
// populated with one or more 'IndexAttributes':
//..
//  IndexCollection indices;  // assume populated
//..
// Next, we calculate the size of the buffer that is needed, allocate the
// memory for the buffer from the default allocator, create our concrete
// managed allocator (namely, an instance of 'my_BufferAllocator'), and call
// 'processIndices':
//..
//  const int bufferSize = calculateMaxBufferSize(indices);
//
//  bslma::Allocator *allocator = bslma::Default::defaultAllocator();
//  char *buffer = static_cast<char *>(allocator->allocate(bufferSize));
//
//  my_BufferAllocator bufferAllocator(buffer, bufferSize);
//
//  processIndices(&bufferAllocator, indices);
//..
// Next, we show the implementation of 'processIndices', within which we
// iterate over the market 'indices' that are passed to it:
//..
    static
    void processIndices(bdlma::ManagedAllocator *managedAllocator,
                        const IndexCollection&   indices)
        // Process the specified market 'indices' using the specified
        // 'managedAllocator' to supply memory.
    {
        for (IndexCollection::const_iterator citer = indices.begin();
                                             citer != indices.end(); ++citer) {

//..
// For each index, the 'SecurityCollection' comprising that index is created.
// All of the memory needs of the 'SecurityCollection' are provided by the
// 'managedAllocator'.  Note that even the memory for the footprint of the
// collection comes from the 'managedAllocator':
//..
            SecurityCollection *securities =
                new (managedAllocator->allocate(sizeof(SecurityCollection)))
                                          SecurityCollection(managedAllocator);

//..
// Next, we call 'loadIndex' to populate 'securities', followed by the call to
// 'processIndex'.  'loadIndex' also uses the 'managedAllocator', the details
// of which are not shown here:
//..
            loadIndex(securities, managedAllocator, *citer);

            processIndex(*securities, *citer);
//..
// After the index is processed, 'release' is called on the managed allocator
// making all of the buffer supplied to the allocator at construction available
// for reuse:
//..
            managedAllocator->release();
        }
//..
// Finally, we let the 'SecurityCollection' used to process the index go out of
// scope intentionally without deleting 'securities'.  The call to 'release'
// renders superfluous the need to call the 'SecurityCollection' destructor as
// well as the destructor of the contained 'my_SecurityAttributes' elements.
//..
    }
コード例 #11
0
// Initializes a geometric primitive instance that will draw the specified vertex and index data.
void GeometricPrimitive::Impl::Initialize(_In_ ID3D11DeviceContext* deviceContext, VertexCollection const& vertices, IndexCollection const& indices)
{
    mResources = sharedResourcesPool.DemandCreate(deviceContext);

    ComPtr<ID3D11Device> device;

    deviceContext->GetDevice(&device);

    CreateBuffer(device.Get(), vertices, D3D11_BIND_VERTEX_BUFFER, &mVertexBuffer);
    CreateBuffer(device.Get(), indices, D3D11_BIND_INDEX_BUFFER, &mIndexBuffer);

    mIndexCount = (UINT)indices.size();
}
コード例 #12
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
// Creates a cone primitive.
void DirectX::ComputeCone(VertexCollection& vertices, IndexCollection& indices, float diameter, float height, size_t tessellation, bool rhcoords)
{
    vertices.clear();
    indices.clear();

    if (tessellation < 3)
        throw std::out_of_range("tesselation parameter out of range");

    height /= 2;

    XMVECTOR topOffset = XMVectorScale(g_XMIdentityR1, height);

    float radius = diameter / 2;
    size_t stride = tessellation + 1;

    // Create a ring of triangles around the outside of the cone.
    for (size_t i = 0; i <= tessellation; i++)
    {
        XMVECTOR circlevec = GetCircleVector(i, tessellation);

        XMVECTOR sideOffset = XMVectorScale(circlevec, radius);

        float u = float(i) / tessellation;

        XMVECTOR textureCoordinate = XMLoadFloat(&u);

        XMVECTOR pt = XMVectorSubtract(sideOffset, topOffset);

        XMVECTOR normal = XMVector3Cross(
            GetCircleTangent(i, tessellation),
            XMVectorSubtract(topOffset, pt));
        normal = XMVector3Normalize(normal);

        // Duplicate the top vertex for distinct normals
        vertices.push_back(VertexPositionNormalTexture(topOffset, normal, g_XMZero));
        vertices.push_back(VertexPositionNormalTexture(pt, normal, XMVectorAdd(textureCoordinate, g_XMIdentityR1)));

        index_push_back(indices, i * 2);
        index_push_back(indices, (i * 2 + 3) % (stride * 2));
        index_push_back(indices, (i * 2 + 1) % (stride * 2));
    }

    // Create flat triangle fan caps to seal the bottom.
    CreateCylinderCap(vertices, indices, tessellation, height, radius, false);

    // Build RH above
    if (!rhcoords)
        ReverseWinding(indices, vertices);
}
コード例 #13
0
ファイル: indexUtil.cpp プロジェクト: Longlonc/palabos
IndexCollection operator!(IndexCollection const& coll) {
    std::vector<plint> result;
    std::vector<plint> const& ind = coll.get();

    std::vector<plint>::const_iterator iter_ind = ind.begin();

    plint negative_ind = 0;
    for (; iter_ind != ind.end(); ++iter_ind) {
        while (negative_ind < *iter_ind) {
            result.push_back(negative_ind++);
        }
        ++negative_ind;
    }
    return IndexCollection(result);
}
コード例 #14
0
// Initializes a geometric primitive instance that will draw the specified vertex and index data.
_Use_decl_annotations_
void GeometricPrimitive::Impl::Initialize(ID3D11DeviceContext* deviceContext, const VertexCollection& vertices, const IndexCollection& indices)
{
    if ( vertices.size() >= USHRT_MAX )
        throw std::exception("Too many vertices for 16-bit index buffer");

    mResources = sharedResourcesPool.DemandCreate(deviceContext);

    ComPtr<ID3D11Device> device;
    deviceContext->GetDevice(&device);

    CreateBuffer(device.Get(), vertices, D3D11_BIND_VERTEX_BUFFER, &mVertexBuffer);
    CreateBuffer(device.Get(), indices, D3D11_BIND_INDEX_BUFFER, &mIndexBuffer);

    mIndexCount = static_cast<UINT>( indices.size() );
}
コード例 #15
0
// Creates a cylinder primitive.
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateCylinder(_In_ ID3D11DeviceContext* deviceContext, float height, float diameter, size_t tessellation)
{
    VertexCollection vertices;
    IndexCollection indices;

    if (tessellation < 3)
        throw std::out_of_range("tesselation parameter out of range");

    height /= 2;

    XMVECTOR topOffset = g_XMIdentityR1 * height;

    float radius = diameter / 2;
    size_t stride = tessellation + 1;

    // Create a ring of triangles around the outside of the cylinder.
    for (size_t i = 0; i <= tessellation; i++)
    {
        XMVECTOR normal = GetCircleVector(i, tessellation);

        XMVECTOR sideOffset = normal * radius;

        float u = (float)i / tessellation;

        XMVECTOR textureCoordinate = XMLoadFloat(&u);

        vertices.push_back(VertexPositionNormalTexture(sideOffset + topOffset, normal, textureCoordinate));
        vertices.push_back(VertexPositionNormalTexture(sideOffset - topOffset, normal, textureCoordinate + g_XMIdentityR1));

        indices.push_back(i * 2);
        indices.push_back((i * 2 + 2) % (stride * 2));
        indices.push_back(i * 2 + 1);

        indices.push_back(i * 2 + 1);
        indices.push_back((i * 2 + 2) % (stride * 2));
        indices.push_back((i * 2 + 3) % (stride * 2));
    }

    // Create flat triangle fan caps to seal the top and bottom.
    CreateCylinderCap(vertices, indices, tessellation, height, radius, true);
    CreateCylinderCap(vertices, indices, tessellation, height, radius, false);

    // Create the primitive object.
    std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());
    
    primitive->pImpl->Initialize(deviceContext, vertices, indices);

    return primitive;
}
コード例 #16
0
// Tessellates the specified bezier patch.
static void TessellatePatch(VertexCollection& vertices, IndexCollection& indices, TeapotPatch const& patch, size_t tessellation, FXMVECTOR scale, bool isMirrored)
{
    // Look up the 16 control points for this patch.
    XMVECTOR controlPoints[16];

    for (int i = 0; i < 16; i++)
    {
        controlPoints[i] = TeapotControlPoints[patch.indices[i]] * scale;
    }

    // Create the index data.
    Bezier::CreatePatchIndices(tessellation, isMirrored, [&](size_t index)
    {
        indices.push_back(vertices.size() + index);
    });

    // Create the vertex data.
    Bezier::CreatePatchVertices(controlPoints, tessellation, isMirrored, [&](FXMVECTOR position, FXMVECTOR normal, FXMVECTOR textureCoordinate)
    {
        vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinate));
    });
}
コード例 #17
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
// Creates a teapot primitive.
void DirectX::ComputeTeapot(VertexCollection& vertices, IndexCollection& indices, float size, size_t tessellation, bool rhcoords)
{
    vertices.clear();
    indices.clear();

    if (tessellation < 1)
        throw std::out_of_range("tesselation parameter out of range");

    XMVECTOR scaleVector = XMVectorReplicate(size);

    XMVECTOR scaleNegateX = XMVectorMultiply(scaleVector, g_XMNegateX);
    XMVECTOR scaleNegateZ = XMVectorMultiply(scaleVector, g_XMNegateZ);
    XMVECTOR scaleNegateXZ = XMVectorMultiply(scaleVector, XMVectorMultiply(g_XMNegateX, g_XMNegateZ));

    for (size_t i = 0; i < _countof(TeapotPatches); i++)
    {
        TeapotPatch const& patch = TeapotPatches[i];

        // Because the teapot is symmetrical from left to right, we only store
        // data for one side, then tessellate each patch twice, mirroring in X.
        TessellatePatch(vertices, indices, patch, tessellation, scaleVector, false);
        TessellatePatch(vertices, indices, patch, tessellation, scaleNegateX, true);

        if (patch.mirrorZ)
        {
            // Some parts of the teapot (the body, lid, and rim, but not the
            // handle or spout) are also symmetrical from front to back, so
            // we tessellate them four times, mirroring in Z as well as X.
            TessellatePatch(vertices, indices, patch, tessellation, scaleNegateZ, true);
            TessellatePatch(vertices, indices, patch, tessellation, scaleNegateXZ, false);
        }
    }

    // Built RH above
    if (!rhcoords)
        ReverseWinding(indices, vertices);
}
コード例 #18
0
void
Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes,
                                bool add_demangled,
                                bool add_mangled,
                                NameToIndexMap &name_to_index_map) const
{
    if (add_demangled || add_mangled)
    {
        Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
        Mutex::Locker locker (m_mutex);

        // Create the name index vector to be able to quickly search by name
        NameToIndexMap::Entry entry;
        const size_t num_indexes = indexes.size();
        for (size_t i=0; i<num_indexes; ++i)
        {
            entry.value = indexes[i];
            assert (i < m_symbols.size());
            const Symbol *symbol = &m_symbols[entry.value];

            const Mangled &mangled = symbol->GetMangled();
            if (add_demangled)
            {
                entry.cstring = mangled.GetDemangledName().GetCString();
                if (entry.cstring && entry.cstring[0])
                    name_to_index_map.Append (entry);
            }
                
            if (add_mangled)
            {
                entry.cstring = mangled.GetMangledName().GetCString();
                if (entry.cstring && entry.cstring[0])
                    name_to_index_map.Append (entry);
            }
        }
    }
}
コード例 #19
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateDodecahedron( float size /*= 1*/, bool rhcoords /*= true*/)
{
	VertexCollection vertices;
	IndexCollection indices;

	static const float a = 1.f / SQRT3;
	static const float b = 0.356822089773089931942f; // sqrt( ( 3 - sqrt(5) ) / 6 )
	static const float c = 0.934172358962715696451f; // sqrt( ( 3 + sqrt(5) ) / 6 );

	static const XMVECTORF32 verts[20] =
	{
		{ a, a, a },
		{ a, a, -a },
		{ a, -a, a },
		{ a, -a, -a },
		{ -a, a, a },
		{ -a, a, -a },
		{ -a, -a, a },
		{ -a, -a, -a },
		{ b, c, 0 },
		{ -b, c, 0 },
		{ b, -c, 0 },
		{ -b, -c, 0 },
		{ c, 0, b },
		{ c, 0, -b },
		{ -c, 0, b },
		{ -c, 0, -b },
		{ 0, b, c },
		{ 0, -b, c },
		{ 0, b, -c },
		{ 0, -b, -c }
	};

	static const uint32_t faces[12 * 5] =
	{
		0, 8, 9, 4, 16,
		0, 16, 17, 2, 12,
		12, 2, 10, 3, 13,
		9, 5, 15, 14, 4,
		3, 19, 18, 1, 13,
		7, 11, 6, 14, 15,
		0, 12, 13, 1, 8,
		8, 1, 18, 5, 9,
		16, 4, 14, 6, 17,
		6, 11, 10, 2, 17,
		7, 15, 5, 18, 19,
		7, 19, 3, 10, 11,
	};

	static const XMVECTORF32 textureCoordinates[5] =
	{
		{ 0.654508f, 0.0244717f },
		{ 0.0954915f, 0.206107f },
		{ 0.0954915f, 0.793893f },
		{ 0.654508f, 0.975528f },
		{ 1.f, 0.5f }
	};

	static const uint32_t textureIndex[12][5] =
	{
		{ 0, 1, 2, 3, 4 },
		{ 2, 3, 4, 0, 1 },
		{ 4, 0, 1, 2, 3 },
		{ 1, 2, 3, 4, 0 },
		{ 2, 3, 4, 0, 1 },
		{ 0, 1, 2, 3, 4 },
		{ 1, 2, 3, 4, 0 },
		{ 4, 0, 1, 2, 3 },
		{ 4, 0, 1, 2, 3 },
		{ 1, 2, 3, 4, 0 },
		{ 0, 1, 2, 3, 4 },
		{ 2, 3, 4, 0, 1 },
	};

	size_t t = 0;
	for (size_t j = 0; j < _countof(faces); j += 5, ++t)
	{
		uint32_t v0 = faces[j];
		uint32_t v1 = faces[j + 1];
		uint32_t v2 = faces[j + 2];
		uint32_t v3 = faces[j + 3];
		uint32_t v4 = faces[j + 4];

		XMVECTOR normal = XMVector3Cross(verts[v1].v - verts[v0].v,
			verts[v2].v - verts[v0].v);
		normal = XMVector3Normalize(normal);

		size_t base = vertices.size();

		indices.push_back(base);
		indices.push_back(base + 1);
		indices.push_back(base + 2);

		indices.push_back(base);
		indices.push_back(base + 2);
		indices.push_back(base + 3);

		indices.push_back(base);
		indices.push_back(base + 3);
		indices.push_back(base + 4);

		// Duplicate vertices to use face normals
		XMVECTOR position = XMVectorScale(verts[v0], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][0]]));

		position = XMVectorScale(verts[v1], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][1]]));

		position = XMVectorScale(verts[v2], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][2]]));

		position = XMVectorScale(verts[v3], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][3]]));

		position = XMVectorScale(verts[v4], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][4]]));
	}

	assert(vertices.size() == 12 * 5);
	assert(indices.size() == 12 * 3 * 3);

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, !rhcoords);

	return primitive;
}
コード例 #20
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
//--------------------------------------------------------------------------------------
// Icosahedron
//--------------------------------------------------------------------------------------
void DirectX::ComputeIcosahedron(VertexCollection& vertices, IndexCollection& indices, float size, bool rhcoords)
{
    vertices.clear();
    indices.clear();

    static const float  t = 1.618033988749894848205f; // (1 + sqrt(5)) / 2
    static const float t2 = 1.519544995837552493271f; // sqrt( 1 + sqr( (1 + sqrt(5)) / 2 ) )

    static const XMVECTORF32 verts[12] =
    {
        { { {    t / t2,  1.f / t2,       0, 0 } } },
        { { {   -t / t2,  1.f / t2,       0, 0 } } },
        { { {    t / t2, -1.f / t2,       0, 0 } } },
        { { {   -t / t2, -1.f / t2,       0, 0 } } },
        { { {  1.f / t2,       0,    t / t2, 0 } } },
        { { {  1.f / t2,       0,   -t / t2, 0 } } },
        { { { -1.f / t2,       0,    t / t2, 0 } } },
        { { { -1.f / t2,       0,   -t / t2, 0 } } },
        { { {       0,    t / t2,  1.f / t2, 0 }  } },
        { { {       0,   -t / t2,  1.f / t2, 0 } } },
        { { {       0,    t / t2, -1.f / t2, 0 } } },
        { { {       0,   -t / t2, -1.f / t2, 0 } } }
    };

    static const uint32_t faces[20 * 3] =
    {
        0, 8, 4,
        0, 5, 10,
        2, 4, 9,
        2, 11, 5,
        1, 6, 8,
        1, 10, 7,
        3, 9, 6,
        3, 7, 11,
        0, 10, 8,
        1, 8, 10,
        2, 9, 11,
        3, 11, 9,
        4, 2, 0,
        5, 0, 2,
        6, 1, 3,
        7, 3, 1,
        8, 6, 4,
        9, 4, 6,
        10, 5, 7,
        11, 7, 5
    };

    for (size_t j = 0; j < _countof(faces); j += 3)
    {
        uint32_t v0 = faces[j];
        uint32_t v1 = faces[j + 1];
        uint32_t v2 = faces[j + 2];

        XMVECTOR normal = XMVector3Cross(
            XMVectorSubtract(verts[v1].v, verts[v0].v),
            XMVectorSubtract(verts[v2].v, verts[v0].v));
        normal = XMVector3Normalize(normal);

        size_t base = vertices.size();
        index_push_back(indices, base);
        index_push_back(indices, base + 1);
        index_push_back(indices, base + 2);

        // Duplicate vertices to use face normals
        XMVECTOR position = XMVectorScale(verts[v0], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMZero /* 0, 0 */));

        position = XMVectorScale(verts[v1], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR0 /* 1, 0 */));

        position = XMVectorScale(verts[v2], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR1 /* 0, 1 */));
    }

    // Built LH above
    if (rhcoords)
        ReverseWinding(indices, vertices);

    assert(vertices.size() == 20 * 3);
    assert(indices.size() == 20 * 3);
}
コード例 #21
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateTorus( float diameter /*= 1*/, float thickness /*= 0.333f*/, size_t tessellation /*= 32*/, bool rhcoords /*= true*/)
{
	VertexCollection vertices;
	IndexCollection indices;

	if (tessellation < 3)
		throw std::out_of_range("tesselation parameter out of range");

	size_t stride = tessellation + 1;

	// First we loop around the main ring of the torus.
	for (size_t i = 0; i <= tessellation; i++)
	{
		float u = (float)i / tessellation;

		float outerAngle = i * XM_2PI / tessellation - XM_PIDIV2;

		// Create a transform matrix that will align geometry to
		// slice perpendicularly though the current ring position.
		XMMATRIX transform = XMMatrixTranslation(diameter / 2, 0, 0) * XMMatrixRotationY(outerAngle);

		// Now we loop along the other axis, around the side of the tube.
		for (size_t j = 0; j <= tessellation; j++)
		{
			float v = 1 - (float)j / tessellation;

			float innerAngle = j * XM_2PI / tessellation + XM_PI;
			float dx, dy;

			XMScalarSinCos(&dy, &dx, innerAngle);

			// Create a vertex.
			XMVECTOR normal = XMVectorSet(dx, dy, 0, 0);
			XMVECTOR position = normal * thickness / 2;
			XMVECTOR textureCoordinate = XMVectorSet(u, v, 0, 0);

			position = XMVector3Transform(position, transform);
			normal = XMVector3TransformNormal(normal, transform);

			vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinate));

			// And create indices for two triangles.
			size_t nextI = (i + 1) % stride;
			size_t nextJ = (j + 1) % stride;

			indices.push_back(i * stride + j);
			indices.push_back(i * stride + nextJ);
			indices.push_back(nextI * stride + j);

			indices.push_back(i * stride + nextJ);
			indices.push_back(nextI * stride + nextJ);
			indices.push_back(nextI * stride + j);
		}
	}

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, rhcoords);

	return primitive;
}
コード例 #22
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateSphere( float diameter /*= 1*/, size_t tessellation /*= 16*/, bool rhcoords /*= true*/)
{
	VertexCollection vertices;
	IndexCollection indices;

	if (tessellation < 3)
		throw std::out_of_range("tesselation parameter out of range");

	size_t verticalSegments = tessellation;
	size_t horizontalSegments = tessellation * 2;

	float radius = diameter / 2;

	// Create rings of vertices at progressively higher latitudes.
	for (size_t i = 0; i <= verticalSegments; i++)
	{
		float v = 1 - (float)i / verticalSegments;

		float latitude = (i * XM_PI / verticalSegments) - XM_PIDIV2;
		float dy, dxz;

		XMScalarSinCos(&dy, &dxz, latitude);

		// Create a single ring of vertices at this latitude.
		for (size_t j = 0; j <= horizontalSegments; j++)
		{
			float u = (float)j / horizontalSegments;

			float longitude = j * XM_2PI / horizontalSegments;
			float dx, dz;

			XMScalarSinCos(&dx, &dz, longitude);

			dx *= dxz;
			dz *= dxz;

			XMVECTOR normal = XMVectorSet(dx, dy, dz, 0);
			XMVECTOR textureCoordinate = XMVectorSet(u, v, 0, 0);

			vertices.push_back(VertexPositionNormalTexture(normal * radius, normal, textureCoordinate));
		}
	}

	// Fill the index buffer with triangles joining each pair of latitude rings.
	size_t stride = horizontalSegments + 1;

	for (size_t i = 0; i < verticalSegments; i++)
	{
		for (size_t j = 0; j <= horizontalSegments; j++)
		{
			size_t nextI = i + 1;
			size_t nextJ = (j + 1) % stride;

			indices.push_back(i * stride + j);
			indices.push_back(nextI * stride + j);
			indices.push_back(i * stride + nextJ);

			indices.push_back(i * stride + nextJ);
			indices.push_back(nextI * stride + j);
			indices.push_back(nextI * stride + nextJ);
		}
	}

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, rhcoords);

	return primitive;
}
コード例 #23
0
int main(int argc, char *argv[])
{
    int test = argc > 1 ? atoi(argv[1]) : 0;
    int verbose = argc > 2;
    int veryVerbose = argc > 3;
    int veryVeryVerbose = argc > 4;

    cout << "TEST " << __FILE__ << " CASE " << test << endl;

    switch (test) { case 0:
      case 2: {
        // --------------------------------------------------------------------
        // USAGE EXAMPLE
        //   Extracted from component header file.
        //
        // Concerns:
        //: 1 The usage example provided in the component header file compiles,
        //:   links, and runs as shown.
        //
        // Plan:
        //: 1 Incorporate usage example from header into test driver, remove
        //:   leading comment characters, and replace 'assert' with 'ASSERT'.
        //:   (C-1)
        //
        // Testing:
        //   USAGE EXAMPLE
        // --------------------------------------------------------------------

        if (verbose) cout << endl
                          << "USAGE EXAMPLE" << endl
                          << "=============" << endl;

        {
            static const struct {
                const char *d_name;  // name of market index
                int         d_size;  // size of the index
            } DATA[] = {
                // NAME              SIZE
                // --------------    ----
                {  "DJIA",            30  },
                {  "S&P 500",        500  },
                {  "Russell 1000",  1000  },
            };
            const int NUM_DATA = sizeof DATA / sizeof *DATA;

            IndexCollection indices;

            indices.reserve(NUM_DATA);
            for (int ti = 0; ti < NUM_DATA; ++ti) {
                indices.push_back(IndexAttributes(DATA[ti].d_name,
                                                  DATA[ti].d_size));
            }

            bslma::TestAllocator         da("default", veryVeryVerbose);
            bslma::DefaultAllocatorGuard dag(&da);

            const int bufferSize = calculateMaxBufferSize(indices);

            bslma::Allocator *allocator = bslma::Default::defaultAllocator();
            char *buffer = static_cast<char *>(
                                              allocator->allocate(bufferSize));

            my_BufferAllocator bufferAllocator(buffer, bufferSize);

            processIndices(&bufferAllocator, indices);

            ASSERT(1 == da.numBlocksTotal());

            allocator->deallocate(buffer);
        }

      }
      break;
      case 1: {
        // --------------------------------------------------------------------
        // PROTOCOL TEST:
        //   Ensure this class is a properly defined protocol.
        //
        // Concerns:
        //: 1 The protocol is abstract: no objects of it can be created.
        //:
        //: 2 The protocol has no data members.
        //:
        //: 3 The protocol has a virtual destructor.
        //:
        //: 4 All methods of the protocol are pure virtual.
        //:
        //: 5 All methods of the protocol are publicly accessible.
        //
        // Plan:
        //: 1 Define a concrete derived implementation, 'ProtocolClassTestImp',
        //:   of the protocol.
        //:
        //: 2 Create an object of the 'bsls::ProtocolTest' class template
        //:   parameterized by 'ProtocolClassTestImp', and use it to verify
        //:   that:
        //:
        //:   1 The protocol is abstract. (C-1)
        //:
        //:   2 The protocol has no data members. (C-2)
        //:
        //:   3 The protocol has a virtual destructor. (C-3)
        //:
        //: 3 Use the 'BSLS_PROTOCOLTEST_ASSERT' macro to verify that
        //:   non-creator methods of the protocol are:
        //:
        //:   1 virtual, (C-4)
        //:
        //:   2 publicly accessible. (C-5)
        //
        // Testing:
        //   virtual void release() = 0;
        // --------------------------------------------------------------------

        if (verbose) cout << endl << "PROTOCOL TEST" << endl
                                  << "=============" << endl;

        if (verbose) cout << "\nCreate a test object.\n";

        bsls::ProtocolTest<ProtocolClassTestImp> testObj(veryVerbose);

        if (verbose) cout << "\nVerify that the protocol is abstract.\n";

        ASSERT(testObj.testAbstract());

        if (verbose) cout << "\nVerify that there are no data members.\n";

        ASSERT(testObj.testNoDataMembers());

        if (verbose) cout << "\nVerify that the destructor is virtual.\n";

        ASSERT(testObj.testVirtualDestructor());

        if (verbose) cout << "\nVerify that methods are public and virtual.\n";

        // 'bslma::Allocator' protocol
        BSLS_PROTOCOLTEST_ASSERT(testObj, allocate(0));
        BSLS_PROTOCOLTEST_ASSERT(testObj, deallocate(0));

        // 'bdlma::ManagedAllocator' protocol
        BSLS_PROTOCOLTEST_ASSERT(testObj, release());

      } break;
      default: {
          cerr << "WARNING: CASE `" << test << "' NOT FOUND." << endl;
          testStatus = -1;
      }
    }

    if (testStatus > 0) {
        cerr << "Error, non-zero test status = " << testStatus << "." << endl;
    }
    return testStatus;
}
コード例 #24
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
//--------------------------------------------------------------------------------------
// Cube (aka a Hexahedron) or Box
//--------------------------------------------------------------------------------------
void DirectX::ComputeBox(VertexCollection& vertices, IndexCollection& indices, const XMFLOAT3& size, bool rhcoords, bool invertn)
{
    vertices.clear();
    indices.clear();

    // A box has six faces, each one pointing in a different direction.
    const int FaceCount = 6;

    static const XMVECTORF32 faceNormals[FaceCount] =
    {
        { { {  0,  0,  1, 0 } } },
        { { {  0,  0, -1, 0 } } },
        { { {  1,  0,  0, 0 } } },
        { { { -1,  0,  0, 0 } } },
        { { {  0,  1,  0, 0 } } },
        { { {  0, -1,  0, 0 } } },
    };

    static const XMVECTORF32 textureCoordinates[4] =
    {
        { { { 1, 0, 0, 0 } } },
        { { { 1, 1, 0, 0 } } },
        { { { 0, 1, 0, 0 } } },
        { { { 0, 0, 0, 0 } } },
    };

    XMVECTOR tsize = XMLoadFloat3(&size);
    tsize = XMVectorDivide(tsize, g_XMTwo);

    // Create each face in turn.
    for (int i = 0; i < FaceCount; i++)
    {
        XMVECTOR normal = faceNormals[i];

        // Get two vectors perpendicular both to the face normal and to each other.
        XMVECTOR basis = (i >= 4) ? g_XMIdentityR2 : g_XMIdentityR1;

        XMVECTOR side1 = XMVector3Cross(normal, basis);
        XMVECTOR side2 = XMVector3Cross(normal, side1);

        // Six indices (two triangles) per face.
        size_t vbase = vertices.size();
        index_push_back(indices, vbase + 0);
        index_push_back(indices, vbase + 1);
        index_push_back(indices, vbase + 2);

        index_push_back(indices, vbase + 0);
        index_push_back(indices, vbase + 2);
        index_push_back(indices, vbase + 3);

        // Four vertices per face.
        // (normal - side1 - side2) * tsize // normal // t0
        vertices.push_back(VertexPositionNormalTexture(XMVectorMultiply(XMVectorSubtract(XMVectorSubtract(normal, side1), side2), tsize), normal, textureCoordinates[0]));

        // (normal - side1 + side2) * tsize // normal // t1
        vertices.push_back(VertexPositionNormalTexture(XMVectorMultiply(XMVectorAdd(XMVectorSubtract(normal, side1), side2), tsize), normal, textureCoordinates[1]));

        // (normal + side1 + side2) * tsize // normal // t2
        vertices.push_back(VertexPositionNormalTexture(XMVectorMultiply(XMVectorAdd(normal, XMVectorAdd(side1, side2)), tsize), normal, textureCoordinates[2]));

        // (normal + side1 - side2) * tsize // normal // t3
        vertices.push_back(VertexPositionNormalTexture(XMVectorMultiply(XMVectorSubtract(XMVectorAdd(normal, side1), side2), tsize), normal, textureCoordinates[3]));
    }

    // Build RH above
    if (!rhcoords)
        ReverseWinding(indices, vertices);

    if (invertn)
        InvertNormals(vertices);
}
コード例 #25
0
ファイル: indexUtil.cpp プロジェクト: Longlonc/palabos
std::vector<plint> findIndexes(IndexCollection const& collection) {
    return collection.get();
}
コード例 #26
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateIcosahedron( float size /*= 1*/, bool rhcoords /*= true*/)
{
	VertexCollection vertices;
	IndexCollection indices;

	static const float  t = 1.618033988749894848205f; // (1 + sqrt(5)) / 2
	static const float t2 = 1.519544995837552493271f; // sqrt( 1 + sqr( (1 + sqrt(5)) / 2 ) )

	static const XMVECTORF32 verts[12] =
	{
		{ t / t2, 1.f / t2, 0 },
		{ -t / t2, 1.f / t2, 0 },
		{ t / t2, -1.f / t2, 0 },
		{ -t / t2, -1.f / t2, 0 },
		{ 1.f / t2, 0, t / t2 },
		{ 1.f / t2, 0, -t / t2 },
		{ -1.f / t2, 0, t / t2 },
		{ -1.f / t2, 0, -t / t2 },
		{ 0, t / t2, 1.f / t2 },
		{ 0, -t / t2, 1.f / t2 },
		{ 0, t / t2, -1.f / t2 },
		{ 0, -t / t2, -1.f / t2 }
	};

	static const uint32_t faces[20 * 3] =
	{
		0, 8, 4,
		0, 5, 10,
		2, 4, 9,
		2, 11, 5,
		1, 6, 8,
		1, 10, 7,
		3, 9, 6,
		3, 7, 11,
		0, 10, 8,
		1, 8, 10,
		2, 9, 11,
		3, 11, 9,
		4, 2, 0,
		5, 0, 2,
		6, 1, 3,
		7, 3, 1,
		8, 6, 4,
		9, 4, 6,
		10, 5, 7,
		11, 7, 5
	};

	for (size_t j = 0; j < _countof(faces); j += 3)
	{
		uint32_t v0 = faces[j];
		uint32_t v1 = faces[j + 1];
		uint32_t v2 = faces[j + 2];

		XMVECTOR normal = XMVector3Cross(verts[v1].v - verts[v0].v,
			verts[v2].v - verts[v0].v);
		normal = XMVector3Normalize(normal);

		size_t base = vertices.size();
		indices.push_back(base);
		indices.push_back(base + 1);
		indices.push_back(base + 2);

		// Duplicate vertices to use face normals
		XMVECTOR position = XMVectorScale(verts[v0], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMZero /* 0, 0 */));

		position = XMVectorScale(verts[v1], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR0 /* 1, 0 */));

		position = XMVectorScale(verts[v2], size);
		vertices.push_back(VertexPositionNormalTexture(position, normal, g_XMIdentityR1 /* 0, 1 */));
	}

	assert(vertices.size() == 20 * 3);
	assert(indices.size() == 20 * 3);

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, !rhcoords);

	return primitive;
}
コード例 #27
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateGeoSphere( float diameter, size_t tessellation, bool rhcoords)
{
	// An undirected edge between two vertices, represented by a pair of indexes into a vertex array.
	// Becuse this edge is undirected, (a,b) is the same as (b,a).
	typedef std::pair<uint16_t, uint16_t> UndirectedEdge;

	// Makes an undirected edge. Rather than overloading comparison operators to give us the (a,b)==(b,a) property,
	// we'll just ensure that the larger of the two goes first. This'll simplify things greatly.
	auto makeUndirectedEdge = [](uint16_t a, uint16_t b)
	{
		return std::make_pair(max(a, b), min(a, b));
	};

	// Key: an edge
	// Value: the index of the vertex which lies midway between the two vertices pointed to by the key value
	// This map is used to avoid duplicating vertices when subdividing triangles along edges.
	typedef std::map<UndirectedEdge, uint16_t> EdgeSubdivisionMap;


	static const XMFLOAT3 OctahedronVertices[] =
	{
		// when looking down the negative z-axis (into the screen)
		XMFLOAT3(0, 1, 0), // 0 top
		XMFLOAT3(0, 0, -1), // 1 front
		XMFLOAT3(1, 0, 0), // 2 right
		XMFLOAT3(0, 0, 1), // 3 back
		XMFLOAT3(-1, 0, 0), // 4 left
		XMFLOAT3(0, -1, 0), // 5 bottom
	};
	static const uint16_t OctahedronIndices[] =
	{
		0, 1, 2, // top front-right face
		0, 2, 3, // top back-right face
		0, 3, 4, // top back-left face
		0, 4, 1, // top front-left face
		5, 1, 4, // bottom front-left face
		5, 4, 3, // bottom back-left face
		5, 3, 2, // bottom back-right face
		5, 2, 1, // bottom front-right face
	};

	const float radius = diameter / 2.0f;

	// Start with an octahedron; copy the data into the vertex/index collection.

	std::vector<XMFLOAT3> vertexPositions(std::begin(OctahedronVertices), std::end(OctahedronVertices));

	IndexCollection indices;
	indices.insert(indices.begin(), std::begin(OctahedronIndices), std::end(OctahedronIndices));

	// We know these values by looking at the above index list for the octahedron. Despite the subdivisions that are
	// about to go on, these values aren't ever going to change because the vertices don't move around in the array.
	// We'll need these values later on to fix the singularities that show up at the poles.
	const uint16_t northPoleIndex = 0;
	const uint16_t southPoleIndex = 5;

	for (size_t iSubdivision = 0; iSubdivision < tessellation; ++iSubdivision)
	{
		assert(indices.size() % 3 == 0); // sanity

		// We use this to keep track of which edges have already been subdivided.
		EdgeSubdivisionMap subdividedEdges;

		// The new index collection after subdivision.
		IndexCollection newIndices;

		const size_t triangleCount = indices.size() / 3;
		for (size_t iTriangle = 0; iTriangle < triangleCount; ++iTriangle)
		{
			// For each edge on this triangle, create a new vertex in the middle of that edge.
			// The winding order of the triangles we output are the same as the winding order of the inputs.

			// Indices of the vertices making up this triangle
			uint16_t iv0 = indices[iTriangle * 3 + 0];
			uint16_t iv1 = indices[iTriangle * 3 + 1];
			uint16_t iv2 = indices[iTriangle * 3 + 2];

			// Get the new vertices
			XMFLOAT3 v01; // vertex on the midpoint of v0 and v1
			XMFLOAT3 v12; // ditto v1 and v2
			XMFLOAT3 v20; // ditto v2 and v0
			uint16_t iv01; // index of v01
			uint16_t iv12; // index of v12
			uint16_t iv20; // index of v20

			// Function that, when given the index of two vertices, creates a new vertex at the midpoint of those vertices.
			auto divideEdge = [&](uint16_t i0, uint16_t i1, XMFLOAT3& outVertex, uint16_t& outIndex)
			{
				const UndirectedEdge edge = makeUndirectedEdge(i0, i1);

				// Check to see if we've already generated this vertex
				auto it = subdividedEdges.find(edge);
				if (it != subdividedEdges.end())
				{
					// We've already generated this vertex before
					outIndex = it->second; // the index of this vertex
					outVertex = vertexPositions[outIndex]; // and the vertex itself
				}
				else
				{
					// Haven't generated this vertex before: so add it now

					// outVertex = (vertices[i0] + vertices[i1]) / 2
					XMStoreFloat3(
						&outVertex,
						XMVectorScale(
						XMVectorAdd(XMLoadFloat3(&vertexPositions[i0]), XMLoadFloat3(&vertexPositions[i1])),
						0.5f
						)
						);

					outIndex = static_cast<uint16_t>(vertexPositions.size());
					CheckIndexOverflow(outIndex);
					vertexPositions.push_back(outVertex);

					// Now add it to the map.
					subdividedEdges.insert(std::make_pair(edge, outIndex));
				}
			};

			// Add/get new vertices and their indices
			divideEdge(iv0, iv1, v01, iv01);
			divideEdge(iv1, iv2, v12, iv12);
			divideEdge(iv0, iv2, v20, iv20);

			// Add the new indices. We have four new triangles from our original one:
			//        v0
			//        o
			//       /a\
						            //  v20 o---o v01
			//     /b\c/d\
						            // v2 o---o---o v1
			//       v12
			const uint16_t indicesToAdd[] =
			{
				iv0, iv01, iv20, // a
				iv20, iv12, iv2, // b
				iv20, iv01, iv12, // c
				iv01, iv1, iv12, // d
			};
			newIndices.insert(newIndices.end(), std::begin(indicesToAdd), std::end(indicesToAdd));
		}

		indices = std::move(newIndices);
	}

	// Now that we've completed subdivision, fill in the final vertex collection
	VertexCollection vertices;
	vertices.reserve(vertexPositions.size());
	for (auto it = vertexPositions.begin(); it != vertexPositions.end(); ++it)
	{
		auto vertexValue = *it;

		auto normal = XMVector3Normalize(XMLoadFloat3(&vertexValue));
		auto pos = XMVectorScale(normal, radius);

		XMFLOAT3 normalFloat3;
		XMStoreFloat3(&normalFloat3, normal);

		// calculate texture coordinates for this vertex
		float longitude = atan2(normalFloat3.x, -normalFloat3.z);
		float latitude = acos(normalFloat3.y);

		float u = longitude / XM_2PI + 0.5f;
		float v = latitude / XM_PI;

		auto texcoord = XMVectorSet(1.0f - u, v, 0.0f, 0.0f);
		vertices.push_back(VertexPositionNormalTexture(pos, normal, texcoord));
	}

	// There are a couple of fixes to do. One is a texture coordinate wraparound fixup. At some point, there will be
	// a set of triangles somewhere in the mesh with texture coordinates such that the wraparound across 0.0/1.0
	// occurs across that triangle. Eg. when the left hand side of the triangle has a U coordinate of 0.98 and the
	// right hand side has a U coordinate of 0.0. The intent is that such a triangle should render with a U of 0.98 to
	// 1.0, not 0.98 to 0.0. If we don't do this fixup, there will be a visible seam across one side of the sphere.
	// 
	// Luckily this is relatively easy to fix. There is a straight edge which runs down the prime meridian of the
	// completed sphere. If you imagine the vertices along that edge, they circumscribe a semicircular arc starting at
	// y=1 and ending at y=-1, and sweeping across the range of z=0 to z=1. x stays zero. It's along this edge that we
	// need to duplicate our vertices - and provide the correct texture coordinates.
	size_t preFixupVertexCount = vertices.size();
	for (size_t i = 0; i < preFixupVertexCount; ++i)
	{
		// This vertex is on the prime meridian if position.x and texcoord.u are both zero (allowing for small epsilon).
		bool isOnPrimeMeridian = XMVector2NearEqual(
			XMVectorSet(vertices[i].position.x, vertices[i].textureCoordinate.x, 0.0f, 0.0f),
			XMVectorZero(),
			XMVectorSplatEpsilon());

		if (isOnPrimeMeridian)
		{
			size_t newIndex = vertices.size(); // the index of this vertex that we're about to add
			CheckIndexOverflow(newIndex);

			// copy this vertex, correct the texture coordinate, and add the vertex
			VertexPositionNormalTexture v = vertices[i];
			v.textureCoordinate.x = 1.0f;
			vertices.push_back(v);

			// Now find all the triangles which contain this vertex and update them if necessary
			for (size_t j = 0; j < indices.size(); j += 3)
			{
				uint16_t* triIndex0 = &indices[j + 0];
				uint16_t* triIndex1 = &indices[j + 1];
				uint16_t* triIndex2 = &indices[j + 2];

				if (*triIndex0 == i)
				{
					// nothing; just keep going
				}
				else if (*triIndex1 == i)
				{
					std::swap(triIndex0, triIndex1); // swap the pointers (not the values)
				}
				else if (*triIndex2 == i)
				{
					std::swap(triIndex0, triIndex2); // swap the pointers (not the values)
				}
				else
				{
					// this triangle doesn't use the vertex we're interested in
					continue;
				}

				// If we got to this point then triIndex0 is the pointer to the index to the vertex we're looking at
				assert(*triIndex0 == i);
				assert(*triIndex1 != i && *triIndex2 != i); // assume no degenerate triangles

				const VertexPositionNormalTexture& v0 = vertices[*triIndex0];
				const VertexPositionNormalTexture& v1 = vertices[*triIndex1];
				const VertexPositionNormalTexture& v2 = vertices[*triIndex2];

				// check the other two vertices to see if we might need to fix this triangle

				if (abs(v0.textureCoordinate.x - v1.textureCoordinate.x) > 0.5f ||
					abs(v0.textureCoordinate.x - v2.textureCoordinate.x) > 0.5f)
				{
					// yep; replace the specified index to point to the new, corrected vertex
					*triIndex0 = static_cast<uint16_t>(newIndex);
				}
			}
		}
	}

	// And one last fix we need to do: the poles. A common use-case of a sphere mesh is to map a rectangular texture onto
	// it. If that happens, then the poles become singularities which map the entire top and bottom rows of the texture
	// onto a single point. In general there's no real way to do that right. But to match the behavior of non-geodesic
	// spheres, we need to duplicate the pole vertex for every triangle that uses it. This will introduce seams near the
	// poles, but reduce stretching.
	auto fixPole = [&](size_t poleIndex)
	{
		auto poleVertex = vertices[poleIndex];
		bool overwrittenPoleVertex = false; // overwriting the original pole vertex saves us one vertex

		for (size_t i = 0; i < indices.size(); i += 3)
		{
			// These pointers point to the three indices which make up this triangle. pPoleIndex is the pointer to the
			// entry in the index array which represents the pole index, and the other two pointers point to the other
			// two indices making up this triangle.
			uint16_t* pPoleIndex;
			uint16_t* pOtherIndex0;
			uint16_t* pOtherIndex1;
			if (indices[i + 0] == poleIndex)
			{
				pPoleIndex = &indices[i + 0];
				pOtherIndex0 = &indices[i + 1];
				pOtherIndex1 = &indices[i + 2];
			}
			else if (indices[i + 1] == poleIndex)
			{
				pPoleIndex = &indices[i + 1];
				pOtherIndex0 = &indices[i + 2];
				pOtherIndex1 = &indices[i + 0];
			}
			else if (indices[i + 2] == poleIndex)
			{
				pPoleIndex = &indices[i + 2];
				pOtherIndex0 = &indices[i + 0];
				pOtherIndex1 = &indices[i + 1];
			}
			else
			{
				continue;
			}

			const auto& otherVertex0 = vertices[*pOtherIndex0];
			const auto& otherVertex1 = vertices[*pOtherIndex1];

			// Calculate the texcoords for the new pole vertex, add it to the vertices and update the index
			VertexPositionNormalTexture newPoleVertex = poleVertex;
			newPoleVertex.textureCoordinate.x = (otherVertex0.textureCoordinate.x + otherVertex1.textureCoordinate.x) / 2;
			newPoleVertex.textureCoordinate.y = poleVertex.textureCoordinate.y;

			if (!overwrittenPoleVertex)
			{
				vertices[poleIndex] = newPoleVertex;
				overwrittenPoleVertex = true;
			}
			else
			{
				CheckIndexOverflow(vertices.size());

				*pPoleIndex = static_cast<uint16_t>(vertices.size());
				vertices.push_back(newPoleVertex);
			}
		}
	};

	fixPole(northPoleIndex);
	fixPole(southPoleIndex);

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, rhcoords);
	return primitive;
}
コード例 #28
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
//--------------------------------------------------------------------------------------
// Sphere
//--------------------------------------------------------------------------------------
void DirectX::ComputeSphere(VertexCollection& vertices, IndexCollection& indices, float diameter, size_t tessellation, bool rhcoords, bool invertn)
{
    vertices.clear();
    indices.clear();

    if (tessellation < 3)
        throw std::out_of_range("tesselation parameter out of range");

    size_t verticalSegments = tessellation;
    size_t horizontalSegments = tessellation * 2;

    float radius = diameter / 2;

    // Create rings of vertices at progressively higher latitudes.
    for (size_t i = 0; i <= verticalSegments; i++)
    {
        float v = 1 - float(i) / verticalSegments;

        float latitude = (i * XM_PI / verticalSegments) - XM_PIDIV2;
        float dy, dxz;

        XMScalarSinCos(&dy, &dxz, latitude);

        // Create a single ring of vertices at this latitude.
        for (size_t j = 0; j <= horizontalSegments; j++)
        {
            float u = float(j) / horizontalSegments;

            float longitude = j * XM_2PI / horizontalSegments;
            float dx, dz;

            XMScalarSinCos(&dx, &dz, longitude);

            dx *= dxz;
            dz *= dxz;

            XMVECTOR normal = XMVectorSet(dx, dy, dz, 0);
            XMVECTOR textureCoordinate = XMVectorSet(u, v, 0, 0);

            vertices.push_back(VertexPositionNormalTexture(XMVectorScale(normal, radius), normal, textureCoordinate));
        }
    }

    // Fill the index buffer with triangles joining each pair of latitude rings.
    size_t stride = horizontalSegments + 1;

    for (size_t i = 0; i < verticalSegments; i++)
    {
        for (size_t j = 0; j <= horizontalSegments; j++)
        {
            size_t nextI = i + 1;
            size_t nextJ = (j + 1) % stride;

            index_push_back(indices, i * stride + j);
            index_push_back(indices, nextI * stride + j);
            index_push_back(indices, i * stride + nextJ);

            index_push_back(indices, i * stride + nextJ);
            index_push_back(indices, nextI * stride + j);
            index_push_back(indices, nextI * stride + nextJ);
        }
    }

    // Build RH above
    if (!rhcoords)
        ReverseWinding(indices, vertices);

    if (invertn)
        InvertNormals(vertices);
}
コード例 #29
0
std::unique_ptr<GeometricPrimitive> GeometricPrimitive::CreateCube( float size /*= 1*/, bool rhcoords /*= true*/)
{
	// A cube has six faces, each one pointing in a different direction.
	const int FaceCount = 6;

	static const XMVECTORF32 faceNormals[FaceCount] =
	{
		{ 0, 0, 1 },
		{ 0, 0, -1 },
		{ 1, 0, 0 },
		{ -1, 0, 0 },
		{ 0, 1, 0 },
		{ 0, -1, 0 },
	};

	static const XMVECTORF32 textureCoordinates[4] =
	{
		{ 1, 0 },
		{ 1, 1 },
		{ 0, 1 },
		{ 0, 0 },
	};

	VertexCollection vertices;
	IndexCollection indices;

	size /= 2;

	// Create each face in turn.
	for (int i = 0; i < FaceCount; i++)
	{
		XMVECTOR normal = faceNormals[i];

		// Get two vectors perpendicular both to the face normal and to each other.
		XMVECTOR basis = (i >= 4) ? g_XMIdentityR2 : g_XMIdentityR1;

		XMVECTOR side1 = XMVector3Cross(normal, basis);
		XMVECTOR side2 = XMVector3Cross(normal, side1);

		// Six indices (two triangles) per face.
		size_t vbase = vertices.size();
		indices.push_back(vbase + 0);
		indices.push_back(vbase + 1);
		indices.push_back(vbase + 2);

		indices.push_back(vbase + 0);
		indices.push_back(vbase + 2);
		indices.push_back(vbase + 3);

		// Four vertices per face.
		vertices.push_back(VertexPositionNormalTexture((normal - side1 - side2) * size, normal, textureCoordinates[0]));
		vertices.push_back(VertexPositionNormalTexture((normal - side1 + side2) * size, normal, textureCoordinates[1]));
		vertices.push_back(VertexPositionNormalTexture((normal + side1 + side2) * size, normal, textureCoordinates[2]));
		vertices.push_back(VertexPositionNormalTexture((normal + side1 - side2) * size, normal, textureCoordinates[3]));
	}

	// Create the primitive object.
	std::unique_ptr<GeometricPrimitive> primitive(new GeometricPrimitive());

	primitive->pImpl->Initialize( vertices, indices, rhcoords);

	return primitive;

}
コード例 #30
0
ファイル: Geometry.cpp プロジェクト: Microsoft/DirectXTK12
//--------------------------------------------------------------------------------------
// Dodecahedron
//--------------------------------------------------------------------------------------
void DirectX::ComputeDodecahedron(VertexCollection& vertices, IndexCollection& indices, float size, bool rhcoords)
{
    vertices.clear();
    indices.clear();

    static const float a = 1.f / SQRT3;
    static const float b = 0.356822089773089931942f; // sqrt( ( 3 - sqrt(5) ) / 6 )
    static const float c = 0.934172358962715696451f; // sqrt( ( 3 + sqrt(5) ) / 6 );

    static const XMVECTORF32 verts[20] =
    {
        { { {  a,  a,  a, 0 } } },
        { { {  a,  a, -a, 0 } } },
        { { {  a, -a,  a, 0 } } },
        { { {  a, -a, -a, 0 } } },
        { { { -a,  a,  a, 0 } } },
        { { { -a,  a, -a, 0 } } },
        { { { -a, -a,  a, 0 } } },
        { { { -a, -a, -a, 0 } } },
        { { {  b,  c,  0, 0 } } },
        { { { -b,  c,  0, 0 } } },
        { { {  b, -c,  0, 0 } } },
        { { { -b, -c,  0, 0 } } },
        { { {  c,  0,  b, 0 } } },
        { { {  c,  0, -b, 0 } } },
        { { { -c,  0,  b, 0 } } },
        { { { -c,  0, -b, 0 } } },
        { { {  0,  b,  c, 0 } } },
        { { {  0, -b,  c, 0 } } },
        { { {  0,  b, -c, 0 } } },
        { { {  0, -b, -c, 0 } } }
    };

    static const uint32_t faces[12 * 5] =
    {
        0, 8, 9, 4, 16,
        0, 16, 17, 2, 12,
        12, 2, 10, 3, 13,
        9, 5, 15, 14, 4,
        3, 19, 18, 1, 13,
        7, 11, 6, 14, 15,
        0, 12, 13, 1, 8,
        8, 1, 18, 5, 9,
        16, 4, 14, 6, 17,
        6, 11, 10, 2, 17,
        7, 15, 5, 18, 19,
        7, 19, 3, 10, 11,
    };

    static const XMVECTORF32 textureCoordinates[5] =
    {
        { { {  0.654508f, 0.0244717f, 0, 0 } } },
        { { { 0.0954915f,  0.206107f, 0, 0 } } },
        { { { 0.0954915f,  0.793893f, 0, 0 } } },
        { { {  0.654508f,  0.975528f, 0, 0 } } },
        { { {        1.f,       0.5f, 0, 0 } } }
    };

    static const uint32_t textureIndex[12][5] =
    {
        { 0, 1, 2, 3, 4 },
        { 2, 3, 4, 0, 1 },
        { 4, 0, 1, 2, 3 },
        { 1, 2, 3, 4, 0 },
        { 2, 3, 4, 0, 1 },
        { 0, 1, 2, 3, 4 },
        { 1, 2, 3, 4, 0 },
        { 4, 0, 1, 2, 3 },
        { 4, 0, 1, 2, 3 },
        { 1, 2, 3, 4, 0 },
        { 0, 1, 2, 3, 4 },
        { 2, 3, 4, 0, 1 },
    };

    size_t t = 0;
    for (size_t j = 0; j < _countof(faces); j += 5, ++t)
    {
        uint32_t v0 = faces[j];
        uint32_t v1 = faces[j + 1];
        uint32_t v2 = faces[j + 2];
        uint32_t v3 = faces[j + 3];
        uint32_t v4 = faces[j + 4];

        XMVECTOR normal = XMVector3Cross(
            XMVectorSubtract(verts[v1].v, verts[v0].v),
            XMVectorSubtract(verts[v2].v, verts[v0].v));
        normal = XMVector3Normalize(normal);

        size_t base = vertices.size();

        index_push_back(indices, base);
        index_push_back(indices, base + 1);
        index_push_back(indices, base + 2);

        index_push_back(indices, base);
        index_push_back(indices, base + 2);
        index_push_back(indices, base + 3);

        index_push_back(indices, base);
        index_push_back(indices, base + 3);
        index_push_back(indices, base + 4);

        // Duplicate vertices to use face normals
        XMVECTOR position = XMVectorScale(verts[v0], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][0]]));

        position = XMVectorScale(verts[v1], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][1]]));

        position = XMVectorScale(verts[v2], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][2]]));

        position = XMVectorScale(verts[v3], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][3]]));

        position = XMVectorScale(verts[v4], size);
        vertices.push_back(VertexPositionNormalTexture(position, normal, textureCoordinates[textureIndex[t][4]]));
    }

    // Built LH above
    if (rhcoords)
        ReverseWinding(indices, vertices);

    assert(vertices.size() == 12 * 5);
    assert(indices.size() == 12 * 3 * 3);
}