Make a cube from code without going to lowlevelrendering?


#1

Hi,

I would like to make a cude out of triangles like in minecraft, I’m following this tutorial for unity :

But Bs seems to lack (or not ?) some of the methods used.

I’m stuck here :

 mesh.Clear ();
 mesh.vertices = newVertices.ToArray();
 mesh.uv = newUV.ToArray();
 mesh.triangles = newTriangles.ToArray();
 mesh.Optimize ();
 mesh.RecalculateNormals ();
 
 col.sharedMesh=null;
 col.sharedMesh=mesh;

mesh is a HMesh
col is a MeshCollider

But mesh and col don’t have any method used.

Can you help me solve that or showing me how to draw a cube out a triangles please ?

Also, do you have any match for “MeshFilter” from unity ?
and is there a way to convert a List to a array ?


#2

See the creating custom meshes manual: https://www.bsframework.io/docs/creating_meshes.html

You assign the mesh for rendering through CRenderable component.

CMeshCollider requires a PhysicsMesh which is created from same information as the normal mesh. It can be assigned through CMeshCollider::setMesh.


#3

Great, didn’t even seen that in the doc, bsf will soon have his own Minecraft clone x)

Thank you.


#4

I followed the doc of bsf and some doc for create a cube in opengl, I come up with this :

	// Creates an empty mesh with 36 indices and 8 vertices
	MESH_DESC meshDesc;
	meshDesc.numVertices = 8;
	meshDesc.numIndices = 36;

	// Create a vertex with a position, normal and UV coordinates
	SPtr<VertexDataDesc> vertexDesc = VertexDataDesc::create();
	vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
	vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL);
	vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);

	// Create mesh data able to contain 8 vertices of the format specified by vertexDesc, and 36 indices
	SPtr<MeshData> meshData = MeshData::create(8, 36, vertexDesc);

	// Fill out the data for the 0th VES_POSITION element
	Vector3 myVertexPositions[8];

	/*Vertices of a unit cube*/
	myVertexPositions[0] = Vector3(-1.0f, -1.0f, 1.0f);
	myVertexPositions[1] = Vector3(1.0f, -1.0f, 1.0f);
	myVertexPositions[2] = Vector3(1.0f, 1.0f, 1.0f);
	myVertexPositions[3] = Vector3(-1.0f, 1.0f, 1.0f);
	myVertexPositions[4] = Vector3(-1.0f, -1.0f, -1.0f);
	myVertexPositions[5] = Vector3(1.0f, -1.0f, -1.0f);
	myVertexPositions[6] = Vector3(1.0f, 1.0f, -1.0f);
	myVertexPositions[7] = Vector3(-1.0f, 1.0f, -1.0f);
	
	meshData->setVertexData(VES_POSITION, (UINT8*)myVertexPositions, sizeof(myVertexPositions));

	meshDesc.vertexDesc = vertexDesc;
	meshDesc.usage = MeshUsage::MU_DYNAMIC;
	HMesh cubeMesh = Mesh::create(meshDesc);

	// Write 36 32-bit indices
	UINT32* indices = meshData->getIndices32();
	/*Front side*/
	indices[0] = 0; indices[1] = 1; indices[2] = 2;
	indices[3] = 2; indices[4] = 3; indices[5] = 0;
	/*Back side*/
	indices[6] = 1; indices[7] = 5; indices[8] = 6;
	indices[9] = 6; indices[10] = 2; indices[11] = 1;
	/*Left side*/
	indices[12] = 5; indices[13] = 4; indices[14] = 7;
	indices[15] = 7; indices[16] = 6; indices[17] = 5;
	/*Right side*/
	indices[18] = 4; indices[19] = 0; indices[20] = 3;
	indices[21] = 3; indices[22] = 7; indices[23] = 4;
	/*Top*/
	indices[24] = 3; indices[25] = 2; indices[26] = 6;
	indices[27] = 6; indices[28] = 7; indices[29] = 2;
	/*Bottom*/
	indices[30] = 4; indices[31] = 5; indices[32] = 0;
	indices[33] = 1; indices[34] = 0; indices[35] = 5;

	cubeMesh->writeData(meshData, false);

	/************************************************************************/
	/* 								RENDERABLE                  			*/
	/************************************************************************/

	HSceneObject cubeSO = SceneObject::create("Cube");
	HRenderable cubeRenderable = cubeSO->addComponent<CRenderable>();
	cubeRenderable->setMesh(cubeMesh);
	cubeRenderable->setMaterial(assets.exampleMaterial);

But my cube is not showing, what is wrong ? (this is kind of new 3d stuff for me so I’m not sure if all the numbers are correct)


#5

When you are using the Standard shader you need to populate the normals, and potentially also UV’s. Otherwise the lighting calculations won’t work properly.


#6

So, I populated the normals and uvs and the cube doesn’t show up, here is the full code, maybe the cube is wrong.

namespace bs
{
	UINT32 windowResWidth = 600;
	UINT32 windowResHeight = 480;

	/** Container for all resources used by the example. */
	struct Assets
	{
		HTexture exampleAlbedoTex;
		HMaterial exampleMaterial;
	};

	/** Load the resources we'll be using throughout the example. */
	Assets loadAssets()
	{
		Assets assets;

		// Load the 3D model and the animation clip

		// Load PBR textures for the 3D model
		assets.exampleAlbedoTex = ExampleFramework::loadTexture(ExampleTexture::Dirt);

		// Create a material using the default physically based shader, and apply the PBR textures we just loaded
		HShader shader = gBuiltinResources().getBuiltinShader(BuiltinShader::Standard);
		assets.exampleMaterial = Material::create(shader);

		assets.exampleMaterial->setTexture("gAlbedoTex", assets.exampleAlbedoTex);

		return assets;
	}

	/** Set up the 3D object used by the example, and the camera to view the world through. */
	void setUp3DScene(const Assets& assets)
	{
		// Creates an empty mesh with 36 indices and 8 vertices
		MESH_DESC meshDesc;
		meshDesc.numVertices = 8;
		meshDesc.numIndices = 36;

		// Create a vertex with a position, normal and UV coordinates
		SPtr<VertexDataDesc> vertexDesc = VertexDataDesc::create();
		vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
		vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL);
		vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);

		// Create mesh data able to contain 8 vertices of the format specified by vertexDesc, and 36 indices
		SPtr<MeshData> meshData = MeshData::create(8, 36, vertexDesc);

		Vector3 myVertexPositions[8];
		// Cube vertices
		myVertexPositions[0] = Vector3(-1.0f, -1.0f, -1.0f);
		myVertexPositions[1] = Vector3(1.0f, -1.0f, -1.0f);
		myVertexPositions[2] = Vector3(1.0f, 1.0f, -1.0f);
		myVertexPositions[3] = Vector3(-1.0f, 1.0f, -1.0f);
		myVertexPositions[4] = Vector3(-1.0f, -1.0f, 1.0f);
		myVertexPositions[5] = Vector3(1.0f, -1.0f, 1.0f);
		myVertexPositions[6] = Vector3(1.0f, 1.0f, 1.0f);
		myVertexPositions[7] = Vector3(-1.0f, 1.0f, 1.0f);

		Vector3 myNormalPositions[6];
		// Cube normals
		myNormalPositions[0] = Vector3(0.0f, 0.0f, 1.0f);
		myNormalPositions[1] = Vector3(1.0f, 0.0f, 0.0f);
		myNormalPositions[2] = Vector3(0.0f, 0.0f, -1.0f);
		myNormalPositions[3] = Vector3(-1.0f, 0.0f, 0.0f);
		myNormalPositions[4] = Vector3(0.0f, 1.0f, 0.0f);
		myNormalPositions[5] = Vector3(0.0f, -1.0f, 0.0f);

		Vector2 myTexPositions[4];
		// Cube UVs
		myTexPositions[0] = Vector2(0.0f, 0.0f);
		myTexPositions[1] = Vector2(1.0f, 0.0f);
		myTexPositions[2] = Vector2(1.0f, 1.0f);
		myTexPositions[3] = Vector2(0.0f, 1.0f);

		meshData->setVertexData(VES_POSITION, (UINT8*)myVertexPositions, sizeof(myVertexPositions));
		meshData->setVertexData(VES_NORMAL, (UINT8*)myNormalPositions, UINT32(96));
		meshData->setVertexData(VES_TEXCOORD, (UINT8*)myTexPositions, UINT32(64));

		// Write 36 32-bit indices
		UINT32* indices = meshData->getIndices32();
		// front
		indices[0] = 0; indices[1] = 1; indices[2] = 3;
		indices[3] = 3; indices[4] = 1; indices[5] = 2;
		// back
		indices[6] = 1; indices[7] = 5; indices[8] = 2; 
		indices[9] = 2; indices[10] = 5; indices[11] = 6;
		// top
		indices[12] = 5; indices[13] = 4; indices[14] = 6; 
		indices[15] = 6; indices[16] = 4; indices[17] = 7;
		// bottom
		indices[18] = 4; indices[19] = 0; indices[20] = 7; 
		indices[21] = 7; indices[22] = 0; indices[23] = 3;
		// right
		indices[24] = 3; indices[25] = 2; indices[26] = 7;
		indices[27] = 7; indices[28] = 2; indices[29] = 6;
		// left
		indices[30] = 4; indices[31] = 5; indices[32] = 0; 
		indices[33] = 0; indices[34] = 5; indices[35] = 1;   

		meshDesc.vertexDesc = vertexDesc;
		//meshDesc.usage = MeshUsage::MU_DYNAMIC;

		HMesh cubeMesh = Mesh::create(meshDesc);
		cubeMesh->writeData(meshData, true);

		/************************************************************************/
		/* 								RENDERABLE                  			*/
		/************************************************************************/

		HSceneObject cubeSO = SceneObject::create("Cube");
		HRenderable cubeRenderable = cubeSO->addComponent<CRenderable>();
		cubeRenderable->setMesh(cubeMesh);
		cubeRenderable->setMaterial(assets.exampleMaterial);

		/************************************************************************/
		/* 									CAMERA	                     		*/
		/************************************************************************/

		// In order something to render on screen we need at least one camera.

		// Like before, we create a new scene object at (0, 0, 0).
		HSceneObject sceneCameraSO = SceneObject::create("SceneCamera");

		// Get the primary render window we need for creating the camera. 
		SPtr<RenderWindow> window = gApplication().getPrimaryWindow();

		// Add a Camera component that will output whatever it sees into that window 
		// (You could also use a render texture or another window you created).
		HCamera sceneCamera = sceneCameraSO->addComponent<CCamera>();
		sceneCamera->getViewport()->setTarget(window);

		// Set up camera component properties

		// Set closest distance that is visible. Anything below that is clipped.
		sceneCamera->setNearClipDistance(0.005f);

		// Set farthest distance that is visible. Anything above that is clipped.
		sceneCamera->setFarClipDistance(1000);

		// Set aspect ratio depending on the current resolution
		sceneCamera->setAspectRatio(windowResWidth / (float)windowResHeight);

		// Enable multi-sample anti-aliasing for better quality
		sceneCamera->setMSAACount(1);

		// Enable indirect lighting so we get accurate diffuse lighting from the skybox environment map
		const SPtr<RenderSettings>& renderSettings = sceneCamera->getRenderSettings();
		renderSettings->enableIndirectLighting = true;

		sceneCamera->setRenderSettings(renderSettings);

		// Add a CameraFlyer component that allows us to move the camera. See CameraFlyer for more information.
		sceneCameraSO->addComponent<CameraFlyer>();

		// Position and orient the camera scene object
		sceneCameraSO->setPosition(Vector3(0.0f, 2.5f, -4.0f) * 0.65f);
		sceneCameraSO->lookAt(Vector3(0, 1.5f, 0));
	}
}

/** Main entry point into the application. */
#if BS_PLATFORM == BS_PLATFORM_WIN32
#include <windows.h>

int CALLBACK WinMain(
	_In_  HINSTANCE hInstance,
	_In_  HINSTANCE hPrevInstance,
	_In_  LPSTR lpCmdLine,
	_In_  int nCmdShow
)
#else
int main()
#endif
{
	using namespace bs;

	// Initializes the application and creates a window with the specified properties
	VideoMode videoMode(windowResWidth, windowResHeight);
	Application::startUp(videoMode, "Example", false);

	// Registers a default set of input controls
	ExampleFramework::setupInputConfig();

	// Load a model and textures, create materials
	Assets assets = loadAssets();

	// Set up the scene with an object to render and a camera
	setUp3DScene(assets);

	// Runs the main loop that does most of the work. This method will exit when user closes the main
	// window or exits in some other way.
	Application::instance().runMainLoop();

	// When done, clean up
	Application::shutDown();

	return 0;
}

#7

You can try using the built-in ShapeMeshes3D::solidAABox to verify that the problem is indeed with the cube geometry. If that works you can probably reverse engineer that method for your own code.

I also notice you have 8 vertices but only provide 6 normals and 4 texture coordinates. You need to provide a normal/uv for each vertex.


#8

Ok, this time, I’m sure the cube vertices, normals and uvs are correct (I took them from a open source game “Minetest”), but the cube isn’t showing, there is nothing, I should at least got a strange cube or something no ?

// Framework includes
#include "BsApplication.h"
#include "Resources/BsResources.h"
#include "Resources/BsBuiltinResources.h"
#include "Material/BsMaterial.h"
#include "Components/BsCCamera.h"
#include "Components/BsCRenderable.h"
#include "Components/BsCSkybox.h"
#include "RenderAPI/BsRenderAPI.h"
#include "RenderAPI/BsRenderWindow.h"
#include "Scene/BsSceneObject.h"
#include "Utility/BsDrawHelper.h"
#include "Physics/BsMeshCollider.h"
#include "RenderAPI/BsVertexDataDesc.h"

// Example includes
#include "BsCameraFlyer.hpp"
#include "BsExampleFramework.hpp"

namespace bs
{
	UINT32 windowResWidth = 600;
	UINT32 windowResHeight = 480;

	/** Container for all resources used by the example. */
	struct Assets
	{
		HTexture exampleAlbedoTex;
		HMaterial exampleMaterial;
	};

	/** Load the resources we'll be using throughout the example. */
	Assets loadAssets()
	{
		Assets assets;

		// Load the 3D model and the animation clip

		// Load PBR textures for the 3D model
		assets.exampleAlbedoTex = ExampleFramework::loadTexture(ExampleTexture::Dirt);

		// Create a material using the default physically based shader, and apply the PBR textures we just loaded
		HShader shader = gBuiltinResources().getBuiltinShader(BuiltinShader::Standard);
		assets.exampleMaterial = Material::create(shader);

		assets.exampleMaterial->setTexture("gAlbedoTex", assets.exampleAlbedoTex);

		return assets;
	}

	/** Set up the 3D object used by the example, and the camera to view the world through. */
	void setUp3DScene(const Assets& assets)
	{
		// Creates an empty mesh with 6 indices and 24 vertices
		MESH_DESC meshDesc;
		meshDesc.numVertices = 24;
		meshDesc.numIndices = 6;

		// Create a vertex with a position, normal and UV coordinates
		SPtr<VertexDataDesc> vertexDesc = VertexDataDesc::create();
		vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
		vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL);
		vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);

		// Create mesh data able to contain 8 vertices of the format specified by vertexDesc, and 36 indices
		SPtr<MeshData> meshData = MeshData::create(24, 6, vertexDesc);

		Vector3 myVertexPositions[24];
		// Cube vertices
		// Top
		myVertexPositions[0] = Vector3(-0.5, 0.5, -0.5);
		myVertexPositions[1] = Vector3(-0.5, 0.5, 0.5);
		myVertexPositions[2] = Vector3(0.5, 0.5, 0.5);
		myVertexPositions[3] = Vector3(0.5, 0.5, -0.5);
		// Down
		myVertexPositions[4] = Vector3(-0.5, -0.5, -0.5);
		myVertexPositions[5] = Vector3(0.5, -0.5, -0.5);
		myVertexPositions[6] = Vector3(0.5, -0.5, 0.5);
		myVertexPositions[7] = Vector3(-0.5, -0.5, 0.5);
		// Right
		myVertexPositions[8] = Vector3(0.5, -0.5, -0.5);
		myVertexPositions[9] = Vector3(0.5, 0.5, -0.5);
		myVertexPositions[10] = Vector3(0.5, 0.5, 0.5);
		myVertexPositions[11] = Vector3(0.5, -0.5, 0.5);
		// Left
		myVertexPositions[12] = Vector3(-0.5, -0.5, -0.5);
		myVertexPositions[13] = Vector3(-0.5, -0.5, 0.5);
		myVertexPositions[14] = Vector3(-0.5, 0.5, 0.5);
		myVertexPositions[15] = Vector3(-0.5, 0.5, -0.5);
		// Back
		myVertexPositions[16] = Vector3(-0.5, -0.5, 0.5);
		myVertexPositions[17] = Vector3(0.5, -0.5, 0.5);
		myVertexPositions[18] = Vector3(0.5, 0.5, 0.5);
		myVertexPositions[19] = Vector3(-0.5, 0.5, 0.5);
		// Front
		myVertexPositions[20] = Vector3(-0.5, -0.5, -0.5);
		myVertexPositions[21] = Vector3(-0.5, 0.5, -0.5);
		myVertexPositions[22] = Vector3(0.5, 0.5, -0.5);
		myVertexPositions[23] = Vector3(0.5, -0.5, -0.5);

		Vector3 myNormalPositions[24];
		// Cube normals
		// Top
		myNormalPositions[0] = Vector3(0, 1, 0);
		myNormalPositions[1] = Vector3(0, 1, 0);
		myNormalPositions[2] = Vector3(0, 1, 0);
		myNormalPositions[3] = Vector3(0, 1, 0);
		// Down
		myNormalPositions[4] = Vector3(0, -1, 0);
		myNormalPositions[5] = Vector3(0, -1, 0);
		myNormalPositions[6] = Vector3(0, -1, 0);
		myNormalPositions[7] = Vector3(0, -1, 0);
		// Right
		myNormalPositions[8] = Vector3(1, 0, 0);
		myNormalPositions[9] = Vector3(1, 0, 0);
		myNormalPositions[10] = Vector3(1, 0, 0);
		myNormalPositions[11] = Vector3(1, 0, 0);
		// Left
		myNormalPositions[12] = Vector3(-1, 0, 0);
		myNormalPositions[13] = Vector3(-1, 0, 0);
		myNormalPositions[14] = Vector3(-1, 0, 0);
		myNormalPositions[15] = Vector3(-1, 0, 0);
		// Back
		myNormalPositions[16] = Vector3(0, 0, 1);
		myNormalPositions[17] = Vector3(0, 0, 1);
		myNormalPositions[18] = Vector3(0, 0, 1);
		myNormalPositions[19] = Vector3(0, 0, 1);
		// Front
		myNormalPositions[20] = Vector3(0, 0, -1);
		myNormalPositions[21] = Vector3(0, 0, -1);
		myNormalPositions[22] = Vector3(0, 0, -1);
		myNormalPositions[23] = Vector3(0, 0, -1);

		Vector2 myTexPositions[24];
		// Cube UVs
		// Top
		myTexPositions[0] = Vector2(0, 1);
		myTexPositions[1] = Vector2(0, 0);
		myTexPositions[2] = Vector2(1, 0);
		myTexPositions[3] = Vector2(1, 1);
		// Down
		myTexPositions[4] = Vector2(0, 0);
		myTexPositions[5] = Vector2(1, 0);
		myTexPositions[6] = Vector2(1, 1);
		myTexPositions[7] = Vector2(0, 1);
		// Right
		myTexPositions[8] = Vector2(0, 1);
		myTexPositions[9] = Vector2(0, 0);
		myTexPositions[10] = Vector2(1, 0);
		myTexPositions[11] = Vector2(1, 1);
		// Left
		myTexPositions[12] = Vector2(1, 1);
		myTexPositions[13] = Vector2(0, 1);
		myTexPositions[14] = Vector2(0, 0);
		myTexPositions[15] = Vector2(1, 0);
		// Back
		myTexPositions[16] = Vector2(1, 1);
		myTexPositions[17] = Vector2(0, 1);
		myTexPositions[18] = Vector2(0, 0);
		myTexPositions[19] = Vector2(1, 0);
		// Front
		myTexPositions[20] = Vector2(0, 1);
		myTexPositions[21] = Vector2(0, 0);
		myTexPositions[22] = Vector2(1, 0);
		myTexPositions[23] = Vector2(1, 1);

		meshData->setVertexData(VES_POSITION, (UINT8*)myVertexPositions, sizeof(myVertexPositions));
		meshData->setVertexData(VES_NORMAL, (UINT8*)myNormalPositions, UINT32(288));
		meshData->setVertexData(VES_TEXCOORD, (UINT8*)myTexPositions, UINT32(192));

		// Write 6 32-bit indices
		UINT32* indices = meshData->getIndices32();
		// Cube indices
		indices[0] = 0; indices[1] = 1; indices[2] = 2;
		indices[3] = 2; indices[4] = 3; indices[5] = 0;

		meshDesc.vertexDesc = vertexDesc;
		//meshDesc.usage = MeshUsage::MU_DYNAMIC;

		HMesh cubeMesh = Mesh::create(meshDesc);
		cubeMesh->writeData(meshData, true);

		/************************************************************************/
		/* 								RENDERABLE                  			*/
		/************************************************************************/

		HSceneObject cubeSO = SceneObject::create("Cube");
		HRenderable cubeRenderable = cubeSO->addComponent<CRenderable>();
		cubeRenderable->setMesh(cubeMesh);
		cubeRenderable->setMaterial(assets.exampleMaterial);

		/************************************************************************/
		/* 									CAMERA	                     		*/
		/************************************************************************/

		// In order something to render on screen we need at least one camera.

		// Like before, we create a new scene object at (0, 0, 0).
		HSceneObject sceneCameraSO = SceneObject::create("SceneCamera");

		// Get the primary render window we need for creating the camera. 
		SPtr<RenderWindow> window = gApplication().getPrimaryWindow();

		// Add a Camera component that will output whatever it sees into that window 
		// (You could also use a render texture or another window you created).
		HCamera sceneCamera = sceneCameraSO->addComponent<CCamera>();
		sceneCamera->getViewport()->setTarget(window);

		// Set up camera component properties

		// Set closest distance that is visible. Anything below that is clipped.
		sceneCamera->setNearClipDistance(0.005f);

		// Set farthest distance that is visible. Anything above that is clipped.
		sceneCamera->setFarClipDistance(1000);

		// Set aspect ratio depending on the current resolution
		sceneCamera->setAspectRatio(windowResWidth / (float)windowResHeight);

		// Enable multi-sample anti-aliasing for better quality
		sceneCamera->setMSAACount(1);

		// Enable indirect lighting so we get accurate diffuse lighting from the skybox environment map
		const SPtr<RenderSettings>& renderSettings = sceneCamera->getRenderSettings();
		renderSettings->enableIndirectLighting = true;

		sceneCamera->setRenderSettings(renderSettings);

		// Add a CameraFlyer component that allows us to move the camera. See CameraFlyer for more information.
		sceneCameraSO->addComponent<CameraFlyer>();

		// Position and orient the camera scene object
		sceneCameraSO->setPosition(Vector3(0.0f, 2.5f, -4.0f) * 0.65f);
		sceneCameraSO->lookAt(Vector3(0, 1.5f, 0));
	}
}

/** Main entry point into the application. */
#if BS_PLATFORM == BS_PLATFORM_WIN32
#include <windows.h>

int CALLBACK WinMain(
	_In_  HINSTANCE hInstance,
	_In_  HINSTANCE hPrevInstance,
	_In_  LPSTR lpCmdLine,
	_In_  int nCmdShow
)
#else
int main()
#endif
{
	using namespace bs;

	// Initializes the application and creates a window with the specified properties
	VideoMode videoMode(windowResWidth, windowResHeight);
	Application::startUp(videoMode, "Example", false);

	// Registers a default set of input controls
	ExampleFramework::setupInputConfig();

	// Load a model and textures, create materials
	Assets assets = loadAssets();

	// Set up the scene with an object to render and a camera
	setUp3DScene(assets);

	// Runs the main loop that does most of the work. This method will exit when user closes the main
	// window or exits in some other way.
	Application::instance().runMainLoop();

	// When done, clean up
	Application::shutDown();

	return 0;
}

I will try the solid box thing.


#9

Engines use different coordinate systems and index culling order so it’s not necessarily what bsf expects. Index order in particular needs to be clockwise in order for a face (triangle) to be considered front-facing. If the problem is geometry, this is where I’d look first. But I’d first confirm the problem is geometry at all.


#10

So, it’s working, thanks.

I reverse the Solidbox funtion with its iterator to find vertices etc.

For people who wants, here is the code for a “Cube” with 24 vertices and 36 indices:

				// Creates an empty mesh with 36 indices and 24 vertices
	MESH_DESC meshDesc;
	meshDesc.numVertices = 24;
	meshDesc.numIndices = 36;

	// Create a vertex with a position, normal and UV coordinates
	SPtr<VertexDataDesc> vertexDesc = VertexDataDesc::create();
	vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
	vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL);
	vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);

	// Create mesh data able to contain 8 vertices of the format specified by vertexDesc, and 36 indices
	SPtr<MeshData> meshData = MeshData::create(24, 36, vertexDesc);

	Vector3 myVertexPositions[24];
	// Cube vertices
	// Back
	myVertexPositions[0] = Vector3(-1, -1, 1);
	myVertexPositions[1] = Vector3(1, -1, 1);
	myVertexPositions[2] = Vector3(1, 1, 1);
	myVertexPositions[3] = Vector3(-1, 1, 1);
	// Front
	myVertexPositions[4] = Vector3(1, -1, -1);
	myVertexPositions[5] = Vector3(-1, -1, -1);
	myVertexPositions[6] = Vector3(-1, 1, -1);
	myVertexPositions[7] = Vector3(1, 1, -1);
	// Right
	myVertexPositions[8] = Vector3(-1, -1, -1);
	myVertexPositions[9] = Vector3(-1, -1, 1);
	myVertexPositions[10] = Vector3(-1, 1, 1);
	myVertexPositions[11] = Vector3(-1, 1, -1);
	// Left
	myVertexPositions[12] = Vector3(1, -1, 1);
	myVertexPositions[13] = Vector3(1, -1, -1);
	myVertexPositions[14] = Vector3(1, 1, -1);
	myVertexPositions[15] = Vector3(1, 1, 1);
	// Top
	myVertexPositions[16] = Vector3(-1, 1, -1);
	myVertexPositions[17] = Vector3(-1, 1, 1);
	myVertexPositions[18] = Vector3(1, 1, 1);
	myVertexPositions[19] = Vector3(1, 1, -1);
	// Bottom
	myVertexPositions[20] = Vector3(-1, -1, -1);
	myVertexPositions[21] = Vector3(1, -1, -1);
	myVertexPositions[22] = Vector3(1, -1, 1);
	myVertexPositions[23] = Vector3(-1, -1, 1);

	Vector3 myNormalPositions[24];
	// Cube normals
	// Back
	myNormalPositions[0] = Vector3(0, 0, 1);
	myNormalPositions[1] = Vector3(0, 0, 1);
	myNormalPositions[2] = Vector3(0, 0, 1);
	myNormalPositions[3] = Vector3(0, 0, 1);
	// Front
	myNormalPositions[4] = Vector3(0, 0, -1);
	myNormalPositions[5] = Vector3(0, 0, -1);
	myNormalPositions[6] = Vector3(0, 0, -1);
	myNormalPositions[7] = Vector3(0, 0, -1);
	// Right
	myNormalPositions[8] = Vector3(-1, 0, 0);
	myNormalPositions[9] = Vector3(-1, 0, 0);
	myNormalPositions[10] = Vector3(-1, 0, 0);
	myNormalPositions[11] = Vector3(-1, 0, 0);
	// Left
	myNormalPositions[12] = Vector3(1, 0, 0);
	myNormalPositions[13] = Vector3(1, 0, 0);
	myNormalPositions[14] = Vector3(1, 0, 0);
	myNormalPositions[15] = Vector3(1, 0, 0);
	// Top
	myNormalPositions[16] = Vector3(0, 1, 0);
	myNormalPositions[17] = Vector3(0, 1, 0);
	myNormalPositions[18] = Vector3(0, 1, 0);
	myNormalPositions[19] = Vector3(0, 1, 0);
	// Bottom
	myNormalPositions[20] = Vector3(0, -1, 0);
	myNormalPositions[21] = Vector3(0, -1, 0);
	myNormalPositions[22] = Vector3(0, -1, 0);
	myNormalPositions[23] = Vector3(0, -1, 0);

	Vector2 myTexPositions[24];
	// Cube UVs
	// Back
	myTexPositions[0] = Vector2(0, 1);
	myTexPositions[1] = Vector2(1, 1);
	myTexPositions[2] = Vector2(1, 0);
	myTexPositions[3] = Vector2(0, 0);
	// Front
	myTexPositions[4] = Vector2(0, 1);
	myTexPositions[5] = Vector2(1, 1);
	myTexPositions[6] = Vector2(1, 0);
	myTexPositions[7] = Vector2(0, 0);
	// Right
	myTexPositions[8] = Vector2(0, 1);
	myTexPositions[9] = Vector2(1, 1);
	myTexPositions[10] = Vector2(1, 0);
	myTexPositions[11] = Vector2(0, 0);
	// Left
	myTexPositions[12] = Vector2(0, 1);
	myTexPositions[13] = Vector2(1, 1);
	myTexPositions[14] = Vector2(1, 0);
	myTexPositions[15] = Vector2(0, 0);
	// Top
	myTexPositions[16] = Vector2(0, 1);
	myTexPositions[17] = Vector2(1, 1);
	myTexPositions[18] = Vector2(1, 0);
	myTexPositions[19] = Vector2(0, 0);
	// Bottom
	myTexPositions[20] = Vector2(0, 1);
	myTexPositions[21] = Vector2(1, 1);
	myTexPositions[22] = Vector2(1, 0);
	myTexPositions[23] = Vector2(0, 0);

	meshData->setVertexData(VES_POSITION, (UINT8*)myVertexPositions, sizeof(myVertexPositions));
	meshData->setVertexData(VES_NORMAL, (UINT8*)myNormalPositions, UINT32(288));
	meshData->setVertexData(VES_TEXCOORD, (UINT8*)myTexPositions, UINT32(192));

	// Write 36 32-bit indices
	UINT32* indices = meshData->getIndices32();
	// Cube indices
	indices[0] = 2; indices[1] = 1; indices[2] = 0;
	indices[3] = 0; indices[4] = 3; indices[5] = 2;

	indices[6] = 6; indices[7] = 5; indices[8] = 4;
	indices[9] = 4; indices[10] = 7; indices[11] = 6;

	indices[12] = 10; indices[13] = 9; indices[14] = 8;
	indices[15] = 8; indices[16] = 11; indices[17] = 10;

	indices[18] = 14; indices[19] = 13; indices[20] = 12;
	indices[21] = 12; indices[22] = 15; indices[23] = 14;

	indices[24] = 18; indices[25] = 17; indices[26] = 16;
	indices[27] = 16; indices[28] = 19; indices[29] = 18;

	indices[30] = 22; indices[31] = 21; indices[32] = 20;
	indices[33] = 20; indices[34] = 23; indices[35] = 22;

	meshDesc.vertexDesc = vertexDesc;
	meshDesc.usage = MeshUsage::MU_DYNAMIC;
	gDebug().logDebug("OK");

	HMesh cubeMesh = Mesh::create(meshData);
	cubeMesh->writeData(meshData, true);

	/************************************************************************/
	/* 								RENDERABLE                  			*/
	/************************************************************************/

	HSceneObject cubeSO = SceneObject::create("Cube");
	HRenderable cubeRenderable = cubeSO->addComponent<CRenderable>();
	cubeRenderable->setMesh(cubeMesh);
	cubeRenderable->setMaterial(assets.exampleMaterial);

In the documentation, I don’t know if I did everything right but:

https://www.bsframework.io/docs/creating_meshes.html

HMesh mesh = Mesh::create(meshDesc);

For the cube to show up, I had to replace the “meshDesc” by “meshData”, but in this case, I don’t know what the purpose of meshDesc so I missed up somewhere I guess.


#11

Hi, Were you able to make the cube with the faces connected? (6 vertices instead of 24). The problem you had was with the normal alignment? Thanks for posting the code!


#12

Hi, I think the problem was a mix of bad normals/geometry, I don’t know if the faces are connected, I think they are.