Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement mesh creation in python. #659

Open
wants to merge 486 commits into
base: master
Choose a base branch
from
Open

Implement mesh creation in python. #659

wants to merge 486 commits into from

Conversation

panzergame
Copy link
Contributor

API example:

builder = KX_MeshBuilder(name, scene, [uvsName, colorsName])
builder = KX_MeshBuilder(name, scene, mesh)
     
mat = builder.addMaterial(material, primitiveType)
mat = builder.materials[i]
     
mat.addVertex(pos[, normal, tangent, uvs, colors]) -> index
mat.addIndex([i]) #for rendered primitive and physics in case of triangle primitive
mat.addPrimitiveIndex([i]) # only for rendered primitive
mat.addTriangleIndex([i]) # only for physics shape
     
mat.removeVertex(start[, end])
mat.removePrimitiveIndex(start[, end])
mat.removeTriangleIndex(start[, end])
     
mat.vertices -> [KX_VertexProxy]
mat.primitiveIndices -> [int]
mat.triangleIndices -> [int]
mat.material = mat

Example file: meshbuilder.zip

panzergame and others added 30 commits December 9, 2017 19:59
This cleanup includes:
- uncrustify pass
- move function definition
- remove extra class keyword
- add const
- use static_cast
- reword comments
This member was used only locally in a function, its visibility
is restricted then.
The blender group object member in KX_GameObject (m_blenderGroupObject)
was a redundant information has it is similar to
m_dupliGroupObject->GetBlenderObject().

This member is removed and its usage is replaced by calling function
GetBlenderObject of the dupli game object.
Previously when calling python function obj.collide(...)
the collision data PHY_ICollData was owned by noone and
so leaked in memory.

To fix this issue the owner ship if transfered to
KX_CollisionContactPointList.

Also a function KX_GameObject::HasCollisionCallbacks is
implemented to not create contact point list for nothing.
…emplate.

Instead using two parameters to intanciate the RAS_VertexData template
class, one struct is used: RAS_VertexFormatType, this struct also include
the enum for the uv and color size.
The display array templates classes need a switch to create
the proper display array instance corresponding on the format
given.

This was proceded thanks to macros but these macro were duplicated
for regular display array and batch display array. As new
classes using format to get template paramater will be used
later a general function is implemented.

This function is named CM_InstantiateTemplateSwitch,
it receives as explicit template parameters the base class to down
cast to, the up class using templates and a tuple of all the
template parameters possible for the up class. Also the function
receive a key to select compare with the tuple element instantiated
and a list of arguments passed to the up class constructor.

For display array classes purpose, a tuple is defined in RAS_VertexFormat.h
containing all RAS_VertexFormatType possible: RAS_VertexFormatTuple.
RAS_VertexFormatType now have a comparaison operator with RAS_VertexFormat
to be working properly in CM_InstantiateTemplateSwitch when compared
with the key.
This commit expose all solver iterations for position, velocity, cluster
and drift solvers.
In the same time the RNA definition of new parameters is a bit cleaned and
the UI defined in python is simplified to fit in two columns insteasd of
three.
Previously the mass of the soft body was set after creating the cluster,
causing incorrect mass in the clusters and incorrect behavior in collision.
Previously the game objects were all storing a constraint list used for
the creation of physics constraint from user settings, but once the object
created, this list has no interest and over all it can be shared between
duplicated objects.

To solve this situation a BL_ConvertObjectInfo struct is introduced, this struct
store a pointer to the blender object which was converted and a list of the
blender constraints. These convert info are created in BL_BlenderSceneConverter
and kept in BL_BlenderConverter after conversion, as promissed they are shared
between game objects under a pointer member: m_convertInfo.

Getter GetBlenderObject and GetConstraints are rewritten to return data from
the convert info.

A special case is dedicated in GetBlenderObject to default camera which doesn't
have any convert info.
Always try to not see ketsji from other parts.
Using a function like SetProg and an argument to decide to bind or
not obligate to use a condition. This condition can be totally
avoided if we the enable argument is not dynamic as in our case.

This function is split in two, BindProg and UnbindProg. For
BL_Shader the BindProg function is override non virtually as the only
caller is KX_BlenderMaterial which has a BL_Shader pointer.
This operation is important for the default camera.
The item passed to PyDict_SetItemString will be incref, so if the item
is constructed in the current scope and not stored in an external data,
the item must be decref.

These rules are applied to KX_PythonInit.cpp and remove the usage of
PyDict_Clear in LA_Launcher.
Previously python was created and initialized the same way for the
blenderplayer through the function setupGamePython. This caused that
when reloading the launcher because of game reload (same file or other file)
we had to take care to not call anything related to python, and the
management of the global dict in blenderplayer was harder.
Because of this difficulties the global dict wasn't shared between game
reload contrary to the shared behaviour in embedded player.

To solve this issue the python initialization and module initialization
is split in two functions: initPlayerPython for constructing python and
initGamePython to initialize a context with all the modules and the
previous global dict.

In the same time the prefix bpy_ is removed in BL_BlenderConverter, and
python joysticks, keyboard and mouse are now using std::unique_ptr
in KX_PythonInit.cpp.
Struct DisplayArraySlot contains mt::vec3 which must be aligned on
16 bytes, in consideration RAS_BoundingBox::m_slots uses
mt::simd_allocator to allocate with the proper alignement.
panzergame and others added 12 commits November 8, 2018 20:50
The duplication of navigation mesh was processing a regeneration of the mesh
and a registration to the scene in the function BuildNavMesh. But the caller
(ProcessReplica) is on an object without a scene graph node and so an access
to its scene, this mean that the try to register the nav mesh in the scene
obstacle simulation failed in BuildNavMesh because the scene is unreachable.

To fix this issue the management of obstacle simulation for nav mesh and
obstacles is fully moved into KX_Scene::AddNodeReplicaObject after the new
object ensure a scene graph node.

Fix issue #926.
…nel (#833)

Before it is only accesible under Debug mode
When this option is actived we will use the world space interpretation
of light data for node materials. Basically you will be able to change
normals from camera space to world space.

Thanks to @ethicalfive for the code and investigation.
Previously KX_LibLoadStatus finish callback was only permitted to be
python function not method.

To allow calling a method, work from EXP_RunPythonCallBackList is reused
and the calling of a python function is moved into new function
EXP_RunPythonCallback. This function is in charge of checking that the
python object is callable and construct a tuple of the arguments.

EXP_RunPythonCallback is now called into KX_LibLoadStatus::RunFinishCallback.
Blenderplayer now supports backtrace write into text file of the
name of the current loaded file or default "blender".
This file contain the backtrace constructed during a SIGSEGV.
Useful for bug report.

GPG_ghost.cpp mimic creator part by setting up a signal function
sigHandleCrash (or windowsExceptionHandler for windows which call
sigHandleCrash at the end) calling sigHandleCrashBacktrace
in responsible of writing the file using BLI_system_backtrace.

Fix issue: #739.
Import csignal to provide SIG_* values.
Third argument of std::transform must be the beginning of the list to transform.
Previously a small python code was provided in the python
component template file. This exemple was using the __component__
attribute to define a global variable. But at the end the exemple
of scene global variable is unstable.
Indeed the scene during loading of the python script might be
undefined or wrong, also if the script is imported from multiple
objects but from different scenes, the global variable is unknown,
could be the first or the second scene depending on import order.

To avoid confusion this block is erased and a comment is let in
start() and update() precising to use self.object.scene to get the
current scene.

Startup file is updated too.
Peviously parallax node was able to select an other texture component
than alpha thanks to a enum option.

This option is ported to material texture and so visible in material
texture parallax panel.

The value is defaulted to alpha for versioning and new textures.
Previously the object info node was doing nothing directly by the fact
that GPU_material_bind_uniforms was using nullptr for the last argument
corresponding to the float array of object info.

The object info node is using 4 values
- location
- material index
- object index
- random

location is directly accessible from the object model matrix, concerning
material index, object index and random, theses values are stored into
a 3 float array.

In case of non-instancing drawing this array is passed as argument of
GPU_material_bind_uniforms.
The array is built in BL_BlenderShader::Update using the material index
passed to this Update function, the object index stored into the mesh user
and also the random stored into the mesh user (which is computed at the
construction of a mesh user based on its client pointer).

In case of instancing the array is packed to the instancing buffer.
This data attribute is named INFO_ATTRIB. The vertex shader (similar
to object layer) receives an instancing attribute and copy it to a varying
for the fragment shader. Function GPU_material_builtin is responsible of
selecting the varying instead of the uniform if the material is using
instancing. This function GPU_material_builtin is also used everywhere
in material nodes to avoid futur issues with instancing masterials.

The material and object index is taken directly from the UI named as
"Pass Index". Its value is stored in both KX_GameObject and
KX_BlenderMaterial under the variable name m_passIndex.

The pass index is exposed in python too under attributes:
KX_BlenderMaterial.passIndex
KX_GameObject.passIndex

This commit is used as an example documentation :
https://github.com/UPBGE/blender/wiki/Implementing-pass-index
@panzergame panzergame added this to In progress in 0.2.5 Dec 20, 2018
@panzergame panzergame moved this from In progress to Release objectives in 0.2.5 Dec 23, 2018
@BluePrintRandom
Copy link
Member

I have used this api quite a bit

I think it's ready to merge, @lordloki @panzergame

later we may want to think about a 'merge' meshes command that absorbs a mesh from another object and removes that object (allowing it's transform to be manipulated) - example - adding planes(2 triangles) and triangles to build mesh in game and then absorbing all the pieces after it's transforms are correct viusally.

@BluePrintRandom
Copy link
Member

BluePrintRandom commented Jan 14, 2019

#demo script and example of recalc normals in game 
import bge
from bge import *
import math
from mathutils import *

def recalcNormals( target ):
    #recalc normal command (also makes object mesh unique/ replica)

    if 'Copy' not in target:
        target.replaceMesh(target.meshes[0].copy(), 1, 1)
        target['Copy']=True
    builder = bge.types.KX_MeshBuilder.FromMesh("my mesh", target.meshes[0])
    builder.slots[0].recalculateNormals()
    mesh = builder.finish()
    oldMesh = target.meshes[0]
    target.replaceMesh(mesh,1,1)
    oldMesh.destruct()
    
def main():
    #demo moving vertex and recalculate normal 
    scene = logic.getCurrentScene()
    obj = logic.getCurrentController().owner
    own = logic.getCurrentController().owner
    origmesh = obj.meshes[0]

   
    for vert_index in range(own.meshes[0].getVertexArrayLength(0)):
        vert = own.meshes[0].getVertex(0,vert_index)
        snag = vert.XYZ 
        snag[2] += math.cos(snag[0]+1+(own['Timer']*12) )*.0125
        snag[1] += math.cos(snag[0]+1+(own['Timer']*12) ) *.0125
        vert.XYZ = snag
        #print('moved')
    recalcNormals(own)
    
main()  

@lordloki lordloki removed this from Release objectives in 0.2.5 Sep 18, 2019
@lordloki lordloki closed this Dec 31, 2019
@lordloki lordloki reopened this Dec 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet